Pygameを用いてPONG風の卓球ゲームを作る方法とソースコードを解説します。
卓球ゲーム(PONG)とは
PONGとは、1972年にATARI社から発売されたアーケードゲームです。
内容はバーをコントローラーで上下に操作しボールを打ち合う2人用のピンポンゲームです。
今回は、以下のようなPygameでPONG風の卓球ゲーム作成する方法を解説します。
動画解説版
サンプルコード
PONEのサンプルコードです。バーを上下に動かしてボールを打ち返し、相手のゴールにボールを入れるとスコアが加算されます。
コード解説
上記コードの各部分を順に詳しく解説します。
1. インポート
import pygame
import sys
from pygame.locals import *
- pygame: Pygameライブラリ。
- sys: システム関連。
- pygame.locals: Pygameの定数。
2. バーのスプライトクラス
# バーのスプライトクラス
class Bar(pygame.sprite.Sprite):
def __init__(self, x, y, alpha=0):
super().__init__()
self.image = pygame.Surface((10, 50 + 50*alpha))
self.image.fill((255, 255, 255))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
def update(self, dy):
self.rect.y += dy
if self.rect.y < 10:
self.rect.y = 10
elif self.rect.y > 420:
self.rect.y = 420
- Barクラス: プレイヤーのバーを表すスプライトクラス。
- initメソッド: バーの初期位置とサイズを設定。alphaはゲームレベルに応じて相手のバーサイズを大きくするための倍率。
- updateメソッド: バーの位置を更新し、画面外に出ないように制限。
3. ボールのスプライトクラス
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y, vx, vy):
super().__init__()
self.image = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(self.image, (255, 255, 255), (10, 10), 10)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.vx = vx
self.vy = vy
def update(self):
self.rect.x += self.vx
self.rect.y += self.vy
if self.rect.y <= 10 or self.rect.y >= 457.5:
self.vy = -self.vy
- Ballクラス: ボールを表すスプライトクラス。
- initメソッド: ボールの初期位置と速度を設定。
- updateメソッド: ボールの位置を更新し、上下の壁に当たった場合に反射。
4. 初期設定
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("PONG")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 40)
# スコア
score1, score2 = 0, 0
# ゲームレベル(値が大きくなるほど、バーとボールが早く動き、敵のバーサイズが大きくなる)
game_level = 2
# ボールスピード
ball_speed = 5
- pygame.init(): Pygameを初期化。
- screen: ゲーム画面の設定。
- pygame.display.set_caption: ウィンドウのタイトルを設定。
- clock: フレームレートを管理。
- font: スコア表示用のフォントを設定。
5. スプライトの作成と管理
# スプライト作成
bar1 = Bar(10, 215)
bar2 = Bar(620, 215, game_level*0.2)
ball = Ball(320, 240, ball_speed + game_level, ball_speed + game_level)
# スプライトグループに追加
all_sprites = pygame.sprite.Group()
all_sprites.add(bar1, bar2, ball)
- bar1, bar2: プレイヤーと敵のバーを作成。
- ball: ボールを作成。
- all_sprites: 全てのスプライトを管理するグループ。
6. ゲームの初期状態
bar1_dy = 0
score1, score2 = 0, 0
- bar1_dy: プレイヤーのバーの移動量(初期値0)。
- score1, score2: プレイヤーと敵のスコア。
7. メインループとイベント処理
running = True # ループ処理の実行を継続するフラグ
while running:
# キーイベント処理
for event in pygame.event.get():
# 閉じるボタンが押されたらループ終了(ゲーム終了)
if event.type == QUIT:
running = False
# ↑もしくは↓矢印キーが押されたらバーを10px動かす
if event.type == KEYDOWN:
if event.key == K_UP:
bar1_dy = -10
elif event.key == K_DOWN:
bar1_dy = 10
if event.type == KEYUP:
if event.key in (K_UP, K_DOWN):
bar1_dy = 0
- QUITイベント: ゲームを終了。
- KEYDOWNイベント: キーが押されたときの処理。
- KEYUPイベント: キーが離されたときの処理。
8. スプライトの更新
# バーとボールの更新
bar1.update(bar1_dy)
bar2.update((ball.rect.y - bar2.rect.y) * 0.1 * game_level)
ball.update()
- bar1.update: プレイヤーのバーを更新。
- bar2.update: 敵のバーをボールに追従させる。ゲームレベル(game_level)が高いほど速く追従する。
- ball.update: ボールを更新。
9. 衝突判定
if pygame.sprite.collide_rect(ball, bar1) or pygame.sprite.collide_rect(ball, bar2):
ball.vx = -ball.vx
- collide_rect: ボールがバーに当たった場合、ボールの方向を反転。
10. スコアの更新
if ball.rect.x < 5:
score2 += 1
ball.rect.center = (320, 240)
ball.vx = 2
ball.vy = 2
elif ball.rect.x > 620:
score1 += 1
ball.rect.center = (320, 240)
ball.vx = -2
ball.vy = -2
- ボールが左端または右端に到達: スコアを更新し、ボールを中央にリセット。
11. 画面の描画
screen.fill((0, 50, 0))
pygame.draw.aaline(screen, (255, 255, 255), (330, 5), (330, 475))
all_sprites.draw(screen)
screen.blit(font.render(str(score1), True, (255, 255, 255)), (250, 10))
screen.blit(font.render(str(score2), True, (255, 255, 255)), (400, 10))
pygame.display.update()
clock.tick(30)
- 画面のクリア: 画面を黒で塗りつぶす。
- 中央線の描画: 中央に線を描画。
- スプライトの描画: 全てのスプライトを描画。
- スコアの描画: スコアを画面に表示。
- 画面の更新: 画面を更新。
- フレームレートの設定: ゲームのフレームレートを設定。
12. main関数の呼び出し
if __name__ == "__main__":
main()
- main関数の呼び出し: ゲームを開始。
関連ページ
Pygameの使い方については以下ページで解説しています。
【Pygame超入門】使い方とサンプルゲームを解説
Pygameで2Dゲームを簡単に制作する方法を入門者向けに解説します。
Python全般については以下ページで解説しています。
【Python超入門】使い方とサンプル集
Pythonの使い方について、基礎文法から応用例まで入門者向けに解説します。
コメント
ブログを楽しく拝見させて頂いております。ありがとうございます。
さて、PONGサンプルを動作させようと思いますが、バーだけ動いて動作しません。
何か問題ありますでしょうか?
因みに/→//の対応はしました。
<開発環境>
Windows
Python 3.6
※renk様
コメントありがとうございます。
私の環境(Windows10+Python3.6)でもエラーが出ましたので
ソースコードを修正致しました。
ご確認いただけますと幸いです。
ご対応頂きありがとうございます。
私の環境でも動作確認できました。