Pygameを用いてPONG風の卓球ゲームを作る方法とソースコードを解説します。
卓球ゲーム(PONG)を作る
PONGとは、1972年にATARI社から発売されたアーケードゲームです。
内容はバーをコントローラーで上下に操作しボールを打ち合う2人用のピンポンゲームです。
今回はPygameでPONG風の卓球ゲーム作ってみました。
プログラムの処理の流れは下記の通りです。
– | 処理手順 |
---|---|
① | ライブラリ「pygame」「sys」をインポートする。 |
② | バーとボールの位置・速度、得点の初期値を設定する。 |
③ | Pygameを初期化する。[pygame.init] |
④ | 大きさ640*480の画面(ウィンドウ)を生成する。[pygame.display.set_mode] |
⑤ | タイトルバーに表示する文字を「PONG」に設定する。[pygame.display.set_caption] |
⑥ | 画面に描画する文字のフォントと大きさを設定する。 |
⑦ | 背景色を黒に設定する。 |
⑧ | ボールを打つバーの設定をする。 |
⑨ | ボールの設定をする。 |
⑩ | 中央線、バー、ボールを描画する。 |
⑪ | 「↑」キーが押されたらプレイヤー側のバーのy座標を+10する。 |
⑫ | 「↓」キーが押されたらプレイヤー側のバーのy座標を-10する。 |
⑬ | 得点を計算する。[calc_score] |
⑭ | CPU側バーの動きを計算する。(ボールのy座標に追いつくように動かす)[calc_ai] |
⑮ | ボールの動きを壁・バーの跳ね返りを考慮して計算する。[calc_ball] |
⑯ | 閉じるボタンが押されたら画面を閉じて終了する。 |
ソースコード
サンプルプログラムのソースコードです。
# -*- coding:utf-8 -*- import pygame from pygame.locals import * import sys # ボールの動きを計算 def calc_ball(ball_x, ball_y, ball_vx, ball_vy, bar1_x, bar1_y, bar2_x, bar2_y): if ball_x <= bar1_x + 10.: if ball_y >= bar1_y - 7.5 and ball_y <= bar1_y + 42.5: ball_x = 20. ball_vx = -ball_vx if ball_x >= bar2_x - 15.: if ball_y >= bar2_y - 7.5 and ball_y <= bar2_y + 42.5: ball_x = 605. ball_vx = -ball_vx if ball_x < 5.: ball_x, ball_y = 320., 232.5 elif ball_x > 620.: ball_x, ball_y = 307.5, 232.5 if ball_y <= 10.: ball_vy = -ball_vy ball_y = 10. elif ball_y >= 457.5: ball_vy = -ball_vy ball_y = 457.5 return ball_x, ball_y, ball_vx, ball_vy # AIの動きを計算 def calc_ai(ball_x, ball_y, bar2_x, bar2_y): dy = ball_y - bar2_y if dy > 80: bar2_y += 20 elif dy > 50: bar2_y += 15 elif dy > 30: bar2_y += 12 elif dy > 10: bar2_y += 8 elif dy < -80: bar2_y -= 20 elif dy < -50: bar2_y -= 15 elif dy < -30: bar2_y -= 12 elif dy < -10: bar2_y -= 8 if bar2_y >= 420.: bar2_y = 420. elif bar2_y <= 10.: bar2_y = 10. return bar2_y # プレイヤーの動き def calc_player(bar1_y, bar1_dy): bar1_y += bar1_dy if bar1_y >= 420.: bar1_y = 420. elif bar1_y <= 10. : bar1_y = 10. return bar1_y # 得点の計算 def calc_score(ball_x, score1, score2): if ball_x < 5.: score2 += 1 if ball_x > 620.: score1 += 1 return score1, score2 # イベント処理 def event(bar1_dy): for event in pygame.event.get(): if event.type == QUIT: # 閉じるボタンが押されたら終了 pygame.quit() sys.exit() if event.type == KEYDOWN: # キーを押したら if event.key == K_UP: bar1_dy = -10 elif event.key == K_DOWN: bar1_dy = 10 elif event.type == KEYUP: # キーを押し終わったら if event.key == K_UP: bar1_dy = 0. elif event.key == K_DOWN: bar1_dy = 0. return bar1_dy def main(): # 各パラメータ bar1_x, bar1_y = 10. , 215. bar2_x, bar2_y = 620., 215. ball_x, ball_y = 307.5, 232.5 bar1_dy, bar2_dy = 0. , 0. ball_vx, ball_vy = 250., 250. score1, score2 = 0,0 ball_r = 7 # pygameの設定 pygame.init() # Pygameの初期化 screen = pygame.display.set_mode((640,480),0,32) # 画面の大きさ pygame.display.set_caption("PONG") # 画面タイトル clock = pygame.time.Clock() font = pygame.font.SysFont(None,40) # 画面文字の設定 # 背景の設定 back = pygame.Surface((640,480)) background = back.convert() screen.fill((0,0,0)) # ボールを打つバーの設定 bar = pygame.Surface((10,50)) bar1 = bar.convert() bar1.fill((255,255,255)) bar2 = bar.convert() bar2.fill((255,255,255)) # ボールの設定 circ_sur = pygame.Surface((20,20)) pygame.draw.circle(circ_sur,(255,255,255),(ball_r, ball_r), ball_r) ball = circ_sur ball.set_colorkey((0,0,0)) while (1): # 各オブジェクトの描画 screen.blit(background,(0,0)) pygame.draw.aaline(screen,(255,255,255),(330,5),(330,475)) # 中央線の描画 screen.blit(bar1,(bar1_x,bar1_y)) # プレイヤー側バーの描画 screen.blit(bar2,(bar2_x,bar2_y)) # CPU側バーの描画 screen.blit(ball,(ball_x, ball_y)) # ボールの描画 screen.blit(font.render(str(score1), True,(255,255,255)),(250.,10.)) screen.blit(font.render(str(score2), True,(255,255,255)),(400.,10.)) # プレイヤー側バーの位置 bar1_dy = event(bar1_dy) bar1_y = calc_player(bar1_y,bar1_dy) # ボールの移動 time_passed = clock.tick(30) time_sec = time_passed / 1000.0 ball_x += ball_vx * time_sec ball_y += ball_vy * time_sec # 得点の計算 score1, score2 = calc_score(ball_x, score1, score2) # CPUのバー速度を計算 bar2_y = calc_ai(ball_x, ball_y, bar2_x, bar2_y) # ボールの速度・位置を計算 ball_x, ball_y, ball_vx, ball_vy = calc_ball(ball_x, ball_y, ball_vx, ball_vy, bar1_x, bar1_y, bar2_x, bar2_y) pygame.display.update() # 画面を更新 if __name__ == "__main__": main()
実行結果
サンプルプログラムの実行結果です。
– | 関連記事 |
---|---|
1 | Pygameでゲームプログラミング |
2 | Python入門 基本文法 |
コメント
ブログを楽しく拝見させて頂いております。ありがとうございます。
さて、PONGサンプルを動作させようと思いますが、バーだけ動いて動作しません。
何か問題ありますでしょうか?
因みに/→//の対応はしました。
<開発環境>
Windows
Python 3.6
※renk様
コメントありがとうございます。
私の環境(Windows10+Python3.6)でもエラーが出ましたので
ソースコードを修正致しました。
ご確認いただけますと幸いです。
ご対応頂きありがとうございます。
私の環境でも動作確認できました。