Pyxelでシューティングゲームを作る(改修日記5/10)
会社も休業で暇だったので、以前作ったpythonのシューティングゲームを改造してみました。以前の記事は以下にリンクを張っておきますのでよろしければご参照ください。
以前はpyxel1.2の時代に作りましたが、今回は1.3を使っています。イメージファイルの拡張子が.pyxresになり、カラーパレットが少し変わりました。
改造点1:プレイヤーをマウスで動かす。
自機の操作をマウスでできるようにします。
move_x = pyxel.mouse_x
move_y = pyxel.mouse_y
if move_x > 145:
move_x = 145
if move_x < 0:
move_x = 0
if move_y > 105:
move_y = 105
if move_y < 0:
move_y = 0
self.p_ship.update(move_x, move_y)
ウィンドウからはみ出すことを阻止するためにmove_xとmove_yの変数にマウス座標を代入し、横145、縦105と比較します。その後、p_ship.updateをmove_xとmove_yを引数にして呼び出します。これは自機の座標を更新する関数です。
改造点2:攻撃をオートにする。
今まではスペースキーを押すと自機が攻撃していましたが、これをオートにします。敵の弾をよけることに重点を置いたゲームにしてみます。
#Auto attack
if len(self.shots) < 11 and pyxel.frame_count % 8 == 0:
new_shot = Shot()
new_shot.update(self.p_ship.ship_x, self.p_ship.ship_y, 8)
self.shots.append(new_shot)
自機弾のオブジェクトが入っている配列のself.shotsの長さを見て、画面内に同時に存在する弾の数を制御します。さらにpyxel.frame_countを使って発射間隔を調整します。上記のコードでは8フレームごとに発射します。
改造点3:敵が弾を撃つようにする。
敵の弾を作成する関数を作りました。
def e_shot_ctr(self, x, y, v, c, mx, my):
# Enemy shot
new_e_shot = Ene_shot(x, y, v, c, mx, my)
self.enemys_shots.append(new_e_shot)
x、yは弾の座標。vとcは弾の色制御用。mx、myは毎フレームごとに動く間隔です。これを敵が動く際に呼び出すことで、敵弾を生成し、毎フレームごとに座標を更新させます。
def update(self):
self.e_shot_x = self.e_shot_x + self.e_shot_mx
self.e_shot_y = self.e_shot_y + self.e_shot_my
座標更新は、単純に現在座標にmxとmyを足すだけです。
改造点4:ボスに弾幕っぽいものを追加する。
ボスの弾にもバリエーションを持たせます。弾幕生成用の関数を作成しました。
def b_shot_ctr(self, x, y, v, c, mx, my):
# Boss shot
if self.boss_count == 1:
new_b_shot = [Ene_shot(x, y, v, c, mx, my),
Ene_shot(x+24, y, v, c, mx, my),
Ene_shot(x+48, y, v, c, mx, my)]
elif self.boss_count == 2:
new_b_shot = [Ene_shot(x, y, v, c, mx-0.4, my-0.6),
Ene_shot(x, y, v, c, mx+0.4, my-0.6),
Ene_shot(x, y, v, c, mx, my),
Ene_shot(x+24, y, v, c, mx-0.4, my-0.8),
Ene_shot(x+24, y, v, c, mx+0.4, my-0.8),
Ene_shot(x+24, y, v, c, mx, my),
Ene_shot(x+48, y, v, c, mx-0.4, my-0.6),
Ene_shot(x+48, y, v, c, mx+0.4, my-0.6),
Ene_shot(x+48, y, v, c, mx, my),]
elif self.boss_count == 3:
new_b_shot = [Ene_shot(x+24, y, v, c, mx-1.6, my-0.8),
Ene_shot(x+24, y, v, c, mx-1.2, my-0.7),
Ene_shot(x+24, y, v, c, mx-0.8, my-0.6),
Ene_shot(x+24, y, v, c, mx-0.4, my-0.5),
Ene_shot(x+24, y, v, c, mx, my),
Ene_shot(x+24, y, v, c, mx+1.6, my-0.8),
Ene_shot(x+24, y, v, c, mx+1.2, my-0.7),
Ene_shot(x+24, y, v, c, mx+0.8, my-0.6),
Ene_shot(x+24, y, v, c, mx+0.4, my-0.5),]
elif self.boss_count == 4:
new_b_shot = [Ene_shot(x, y, v, c, mx-2, my-1),
Ene_shot(x, y, v, c, mx-1, my-1.1),
Ene_shot(x, y, v, c, mx-0.5, my-1),
Ene_shot(x, y, v, c, mx-0.2, my-1.1),
Ene_shot(x+15, y, v, c, mx, my+0.2),
Ene_shot(x+24, y, v, c, mx, my+0.2),
Ene_shot(x+33, y, v, c, mx, my+0.2),
Ene_shot(x+48, y, v, c, mx+2, my-1),
Ene_shot(x+48, y, v, c, mx+1, my-1.1),
Ene_shot(x+48, y, v, c, mx+0.5, my-1),
Ene_shot(x+48, y, v, c, mx+0.2, my-1.1),]
elif self.boss_count == 5:
new_b_shot = [Ene_shot(x+28, y, v, c, mx-1.6, my-0.8),
Ene_shot(x+22, y, v, c, mx, my-0.7),
Ene_shot(x+30, y, v, c, mx-0.8, my-0.6),
Ene_shot(x+30, y, v, c, mx-0.4, my-0.5),
Ene_shot(x+24, y, v, c, mx, my),
Ene_shot(x+20, y, v, c, mx+1.6, my-0.8),
Ene_shot(x+26, y, v, c, mx, my-0.7),
Ene_shot(x+18, y, v, c, mx+0.8, my-0.6),
Ene_shot(x+18, y, v, c, mx+0.4, my-0.5),]
else:
new_b_shot = [Ene_shot(x, y, v, c, mx-0.3, my-0.6),
Ene_shot(x, y, v, c, mx+0.3, my-0.6),
Ene_shot(x, y, v, c, mx, my),
Ene_shot(x+24, y, v, c, mx-0.3, my-0.8),
Ene_shot(x+24, y, v, c, mx+0.3, my-0.8),
Ene_shot(x+24, y, v, c, mx, my),
Ene_shot(x+48, y, v, c, mx-0.3, my-0.6),
Ene_shot(x+48, y, v, c, mx+0.3, my-0.6),
Ene_shot(x+48, y, v, c, mx, my),]
self.boss_countに何面のボスかの情報が入っているので、それを用いて条件文を作ります。弾の生成部分は敵弾生成で作った関数を使いまわしました。
敵が弾を撃つようになりました。画面がちょっとにぎやかになりました。
ボスはなかなかの弾幕を撃ってきます。自分で作っておいてなんですが、自機の大きさも相まってちょっとゲームバランスが悪いですね。
コード全文はGitHubにありますので、リンクを載せておきます。よろしければご参考ください。
ここまで読んでいただき、ありがとうございました。
ここまで読んでいただきありがとうございます!