チャプター4ではブロック崩しゲームを作成しました。
チャプター5では4つの記事を通して ゾンビシューティングゲーム を作成していきましょう。
Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:ゾンビシューティングゲームを作ろう
・Chapter5-1:画面にゾンビを出現させよう ◁今回はここ
・Chapter5-2:ゲームオーバーを設定しよう
・Chapter5-3:プレイ時間を表示しよう
・Chapter5-4:スコアを表示しよう
Chapter6:pygameのお役立ち情報
いよいよ「Chapter5」に突入です。これまで学んできたpygameの知識を活かして、1本の本格的なゾンビシューティングゲームを作り上げましょう。
この章は「Chapter5-1」から「Chapter5-4」までの4つの記事で構成されており、段階的に機能を追加しながら、ゲームとして完成させていきます。
最終的にはゾンビを倒してスコアを稼ぎ、ゲームオーバーやゲームクリアの判定がある、完成度の高い作品になります。
その第一歩となる今回のChapter5-1では、「ゾンビを出現させる」処理を実装していきます。
背景画像の上にプレイヤーキャラとゾンビを表示し、プレイヤーの銃弾でゾンビを倒せるようにするのが今回のゴールです。
ゾンビシューティングゲーム制作の準備
まずはダウンロードしたzipファイルを展開し、その中の「zombie_shooting.py」を実行してください。
「墓場」の背景画像とプレイヤーが表示されるはずです。プレイヤーや左右の矢印キーで移動でき、スペースキーで銃を撃てるようになっています。
現時点ではまだゾンビは登場しません。
つまり、これはゲームを動かすための「キャンバス」が整った段階といえるでしょう。まずはここにゾンビを登場させましょう。
また「zombie_shooting.py」は今回だけでなくChapter5-4まで通して使用します。
毎回少しずつコードを書き足していき、最終的にゾンビシューティングゲームを完成させましょう。
まず初めに、今回の実装の出発点となる現状の zombie_shooting.py
を確認しましょう。
この時点でゲーム画面にはプレイヤーが表示されており、左右に動かすことができます。
スペースキーを押すと銃弾が発射されますが、ゾンビの動きや当たり判定などはまだありません。
# プレイヤーの処理 if key[pygame.K_RIGHT]: # もしキーボードの右矢印キーを押が押されたなら mx += 5 if key[pygame.K_LEFT]: # もしキーボードの左矢印キーを押が押されたなら mx -= 5 mx = max(0, min(740, mx)) # 画面外に出ないように制限 player_rect.x = mx screen.blit(player_img, player_rect)
このコードでは左右キーでプレイヤーが動き、画面の端から外に出てしまわないように制限がかけられています。
また銃弾の処理もすでに次のように実装されています。
# 銃弾の処理 if key[pygame.K_SPACE] and bullet_rect.y < 0: # もしキーボードのスペースキーが押され、かつ銃弾のy座標が0以下(画面外)なら bullet_rect.x = player_rect.x +30 - 4 bullet_rect.y = player_rect.y if bullet_rect.y >= 0: bullet_rect.y += -30 screen.blit(bullet_img, bullet_rect)
この部分では、スペースキーを押すと銃弾が画面上に発射され、上方向に移動していきます。
銃弾はスペースが押されたら出現するのではなく、普段は画面外に待機させておき、スペースが押されたらプレイヤーの正面に移動、その後y軸マイナス方向に-30ずつ移動するというプログラムとなっています。
ゾンビをたくさん出現させる考え方と方法
1体のゾンビだけを画面に表示するなら、1つの変数で管理できます。
しかし今回のゲームでは複数のゾンビが同時に出現し、それぞれが独立して動かしたいです。
これを実現するためには、複数のゾンビの情報(位置や大きさなど)を一括で管理できる仕組みが必要です。
ここで登場するのが「リスト」というPythonの機能です。リストは複数の値(今回の場合はゾンビの座標など)をまとめて扱うことができる便利なデータ構造です。
ゾンビリストを作成しよう
ゲーム画面にゾンビを複数表示するために、リストを使ってゾンビの位置情報をまとめて管理します。
ゾンビの画像そのものはすでに読み込まれています。その画像を画面のどこに表示するかを決める「Rect(矩形)」を作成し、それをリストに格納していきましょう。
以下のコードは、10体のゾンビを画面の上から等間隔で出現させるための処理です:
このコードではfor
文を使って10回ループを回し、その中で pygame.Rect()
を使ってゾンビの初期位置とサイズ(幅60ピクセル、高さ100ピクセル)を指定しています。
横の位置(zombie_x
)は画面の幅(800px)内でランダムに決定し、縦の位置(zombie_y
)は -100 * i
にすることで、画面の上から順に少しずつ間隔を空けて出現するようになっています。
(画面外でゾンビが100px間隔(y軸)で並んで待機している。x軸はランダム)
ここで注意しておきたいのは、画面の上にある「見えない位置」からゾンビが登場してくるという点です。これにより、ゲームが始まってすぐにすべてのゾンビが同じ位置に重なることなく、自然に次々と画面に降りてくる演出が実現できます。
このようにして作成された zombies
リストは、次のステップで「動かす」処理に使っていきます。
ゾンビを動かしてみよう
zombies
リストには10体のゾンビの位置情報が保存されています。しかし現在の状態ではそのゾンビたちは画面外に表示されるだけで動きません。
そこで、各ゾンビが自動的に画面の上から下に向かって降りてくるように、gamestage()
関数内に処理を追加しましょう。
以下のコードは、ゾンビを動かし、画面の下まで到達したら再び上から出現させる処理を行っています。
この for
文の中では、リストに入っているすべてのゾンビに対して同じ処理を繰り返しています。
zombie.y += 5
:各ゾンビの y 座標を5pxずつ増やして下に移動させるscreen.blit(zombie_img, zombie)
:ゾンビ画像を描画if zombie.y > 600:
:ゾンビが画面下に行ったか判定- 下まで来たゾンビはx座標をランダムにして y座標を
-100
に戻すことで、上から再出現する
この処理を毎フレーム繰り返すことでゾンビたちは常に上から下へと移動し、何度も画面に現れます。
ゾンビと弾の衝突判定を追加しよう
ゾンビが画面に表示され、動くようになったところで、次はプレイヤーが撃った「弾」とゾンビがぶつかったことを判定し、命中したゾンビを消す処理を追加します。
ここまでのチャプターで何度も使用した Rect.colliderect()
をまた使用しましょう。これはある Rect
オブジェクトと別の Rect
との重なりを True
または False
で返す関数です。
以下のコードは、ゾンビと弾がぶつかったときの処理を実装した部分です:
これにより、プレイヤーが SPACE
キーを押して撃った弾がゾンビに当たると、ゾンビが倒されて再出現するようになります。また弾も画面外へ戻るため、次の弾を撃つ準備が整います。
これで、「敵を撃って倒す」というゲームの基本的な動作が完成しました。
まだスコアなどの表示はなく、ゲームオーバーもゲームクリアもありませんが、それらは次回以降のチャプターで追加していきます。
まとめ
今回はChapter5の第一歩として「ゾンビを出現させよう」というテーマに取り組みました。
ここまで実装できたあなたはpygameの基礎から一歩進んだ、「動く敵キャラ」を扱えるプログラマーになっています。非常に大きな進歩です!
次回の Chapter5-2 では、ゾンビにぶつかってしまったときの「ゲームオーバー処理」を追加していきます。するとゲームとしての完成度がさらに高まり、プレイに緊張感が生まれます。
最後まで完成させたとき、きっとあなたの中でpygameの理解が一段と深まっているはずです。
次章も、ぜひ一緒に取り組んでいきましょう!
- Chapter5-1の完成コード
-
今回の記事での完成するコード全体は↓↓の通りです。
必要な方は開いて確認しましょう。
# 初期化(ゲームの準備をする) import pygame, sys, random pygame.init() screen = pygame.display.set_mode((800, 600)) haikei_img = pygame.image.load("images/hakaba.png") haikei_img = pygame.transform.scale(haikei_img, (800, 600)) ## プレイヤーデータ player_img = pygame.image.load("images/Player.png") player_img = pygame.transform.scale(player_img, (60, 100)) player_rect = pygame.Rect(370, 500, 60, 100) ## 銃弾データ bullet_img = pygame.image.load("images/bullet.png") bullet_img = pygame.transform.scale(bullet_img, (8, 16)) bullet_rect = pygame.Rect(0, -100, 8, 16) ## ゾンビデータ zombie_img = pygame.image.load("images/Zombie.png") zombie_img = pygame.transform.scale(zombie_img, (60, 100)) zombies = [] # ゾンビの位置情報を入れるためのゾンビリスト for i in range(10): zombie_x = random.randint(0, 800) # 横の位置をランダムに決定 zombie_y = -100 * i # 縦方向に等間隔で並べる zombies.append(pygame.Rect(zombie_x, zombie_y, 60, 100)) # ゾンビ1体分の情報をリストに追加 ## リプレイボタンデータ replay_img = pygame.image.load("images/replaybtn.png") ## 変数 page = 1 mx = 370 hit = 0 score = 0 start_time = pygame.time.get_ticks() # ゲーム開始時の時間 end_time = 0 # ゲーム終了時の時間 freeze_time = False # 時間の停止状態 # ここから各関数の定義 ## ゲームステージ関数 def gamestage(): global mx, page, hit, score, start_time screen.blit(haikei_img, (0, 0)) # ユーザー入力 key = pygame.key.get_pressed() # プレイヤーの処理 if key[pygame.K_RIGHT]: mx += 5 if key[pygame.K_LEFT]: mx -= 5 mx = max(0, min(740, mx)) # プレイヤーが画面端から出ていかないようにする player_rect.x = mx screen.blit(player_img, player_rect) # 銃弾の処理 if key[pygame.K_SPACE] and bullet_rect.y < 0: bullet_rect.x = player_rect.x +30 - 4 bullet_rect.y = player_rect.y if bullet_rect.y >= 0: bullet_rect.y += -30 screen.blit(bullet_img, bullet_rect) # ゾンビの処理 for zombie in zombies: zombie.y += 5 # ゾンビを毎フレームごとに5ピクセル下に移動 screen.blit(zombie_img, zombie) # ゾンビ画像を画面に描画 if zombie.y > 600: # もし画面下に到達したら zombie.x = random.randint(0, 800) zombie.y = -100 # プレイヤーとの衝突判定 # 銃弾との衝突判定 if zombie.colliderect(bullet_rect): # もしゾンビが銃弾と衝突したら # ゾンビを画面外に移動 zombie.y = -100 zombie.x = random.randint(0, 800) # 弾を画面外へ移動 bullet_rect.y = -100 # タイムとスコアの処理 ## ゲームクリア関数 ## ゲームオーバー関数 ## ジャンプ関数 ## リセット関数 ## タイム表示関数 ## スコア表示関数 # メインループ while True: gamestage() #画面描写 pygame.display.update() pygame.time.Clock().tick(60) #終了処理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。