質問内容
Pythonでブロック崩しゲームを制作しておりますが、
こちらのゲームにクリックまたは、スペースキーでリトライ機能の付け方をご教授願いたいです。
長ったらしいソースコードで申し訳ございませんが、よろしくお願い致します。
該当のソースコード
Python
1#インポート 2import sys 3import pygame 4import copy 5import time 6from pygame.locals import * 7 8#定数 9R_H_SIZE = 100 #ラケット縦サイズ 10R_W_SIZE = 100 #ラケット横サイズ 11R_B_POS = 30 #ラケット縦位置 12BALL_SIZE = 25 #ボールサイズ 13BALL_SPD = 5 #ボールの移動速度 14B_X_NUM = 10 #ブロック横列の数 15B_Y_NUM = 10 #ブロック縦列の数 16B_H_SIZE = 20 #ブロック縦サイズ 17B_W_SIZE = 35 #ブロック横サイズ 18B_TOP = 50 #ブロック上余白位置 19B_LEFT = 10 #ブロック左余白位置 20B_BLANK = 3 #ブロック間余白 21C_H_SIZE = 450 #コート縦サイズ 22C_W_SIZE = 300 #コート横サイズ 23F_SIZE = 60 #フォントサイズ 24F_RATE = 60 25S_TIME = 2 #START 画面時間(秒) 26E_TIME = 4 #CLEAR 画面時間(秒) 27 28#画面サイズ(X軸, Y軸, 横, 縦) 29SURFACE = Rect(0, 0, 400, 600) #画面サイズ 30 31#ラケットクラス 32class Racket(pygame.sprite.Sprite): 33 #初期メソッド 34 def __init__(self, name): 35 pygame.sprite.Sprite.__init__(self) 36 37 #ファイルの読み込み 38 self.image = pygame.image.load(name) 39 40 #画像サイズ変更 41 self.image = pygame.transform.scale(self.image, (R_W_SIZE / 2, R_H_SIZE)) 42 43 #ラケットオブジェクト生成 44 self.rect = self.image.get_rect() 45 46 self.rect.bottom = SURFACE.bottom - 20 #ラケットのy座標 47 self.rect.centerx = SURFACE.width - R_B_POS 48 49 #ラケット更新メソッド 50 def update(self, racket_pos): 51 #ラケット位置 52 self.rect.centerx = pygame.mouse.get_pos()[0] #マウスのx座標をラケットのx座標に変換 53 self.rect.centery = SURFACE.bottom - R_B_POS #ラケットのy座標 54 55 #画面内に収める 56 self.rect.clamp_ip(SURFACE) 57 58 #描画メソッド 59 def draw(self, surface): 60 surface.blit(self.image, self.rect) 61 62#ボールクラス 63class Ball(pygame.sprite.Sprite): 64 #初期メソッド 65 def __init__(self, name, racket, blocks): 66 pygame.sprite.Sprite.__init__(self) 67 68 #ファイルの読み込み 69 self.image = pygame.image.load(name) 70 71 #画像サイズ変更 72 self.image = pygame.transform.scale(self.image, (BALL_SIZE, BALL_SIZE)) 73 74 #ボールオブジェクト生成 75 self.rect = self.image.get_rect() 76 self.sp_x = 0 #ボール速度(X軸) 77 self.sp_y = 0 #ボール速度(Y軸) 78 self.racket = racket #ラケットを参照 79 self.update = self.setup #ゲーム初期状態 80 self.blocks = blocks #ブロックを参照 81 82 #ゲーム初期状態に設定するメソッド 83 def setup(self, surface): 84 #ボール初期位置 85 self.rect.centerx = int(SURFACE.width / 2) + 1 86 self.rect.centery = int(SURFACE.height / 2) 87 88 #ボール速度 89 self.sp_x = 0 90 self.sp_y = BALL_SPD 91 92 #update属性を設定 93 self.update = self.move 94 95 #ボールの挙動 96 def move(self, surface): 97 self.rect.centerx += int(self.sp_x) 98 self.rect.centery += int(self.sp_y) 99 100 #左壁の反射 101 if self.rect.left < SURFACE.left: 102 self.rect.left = SURFACE.left 103 self.sp_x = -self.sp_x 104 105 #右壁の反射 106 if self.rect.right > SURFACE.right: 107 self.rect.right = SURFACE.right 108 self.sp_x = -self.sp_x 109 110 #上壁の反射 111 if self.rect.top < SURFACE.top: 112 self.rect.top = SURFACE.top 113 self.sp_y = -self.sp_y 114 115 #ボールを落とした場合 116 if self.rect.bottom > SURFACE.bottom: 117 #GAME OVERを表示 118 font = pygame.font.Font(None, F_SIZE) 119 text = font.render("GAME OVER", True, (255,31,31)) 120 surface.blit(text, (73, 299)) 121 122 #接触ブロックのリスト取得 123 blocks_list = pygame.sprite.spritecollide(self, self.blocks, True) 124 125 if len(blocks_list) > 0: #接触ブロックあり 126 #ボールオブジェクト保存 127 ball_rect = copy.copy(self.rect) 128 129 #接触ブロックリストの各ブロックの繰り返し 130 for block in blocks_list: 131 #ブロック上に接触した場合 132 if block.rect.top > ball_rect.top and block.rect.bottom > ball_rect.bottom and self.sp_y > 0: 133 self.rect.bottom = block.rect.top 134 self.sp_y = -self.sp_y 135 136 #ブロック下に接触した場合 137 if block.rect.top < ball_rect.top and block.rect.bottom < ball_rect.bottom and self.sp_y < 0: 138 self.rect.top = block.rect.bottom 139 self.sp_y = -self.sp_y 140 141 #ブロック左に接触した場合 142 if block.rect.left > ball_rect.left and block.rect.right > ball_rect.right and self.sp_x > 0: 143 self.rect.right = block.rect.left 144 self.sp_x = -self.sp_x 145 146 #ブロック右に接触した場合 147 if block.rect.left < ball_rect.left and block.rect.right < ball_rect.right and self.sp_x < 0: 148 self.rect.left = block.rect.right 149 self.sp_x = -self.sp_x 150 151 #残りブロックなし 152 if len(self.blocks) == 0: 153 154 #クリア画面の表示 155 font = pygame.font.Font(None, F_SIZE) 156 text = font.render("GAME CLEAR", True, (63,255,63)) 157 surface.blit(text, (59, 299)) 158 pygame.display.update() 159 #指定時間を待つ 160 time.sleep(E_TIME) 161 self.update = self.start 162 163 #接触ブロックのリスト取得 164 blocks_list = pygame.sprite.spritecollide(self, self.blocks, True) 165 166 167 168 #ラケットとボールの接触判定 169 if self.rect.colliderect(self.racket.rect): 170 #接触位置取得 171 dist = self.rect.centerx - self.racket.rect.centerx 172 #X軸移動距離設定 173 if dist < 0: 174 self.sp_x = -BALL_SPD * (1 + dist / R_W_SIZE / 2) 175 elif dist > 0: 176 self.sp_x = BALL_SPD * (1 - dist / R_W_SIZE / 2) 177 else: 178 self.sp_x = 0 179 #Y方向反転 180 self.sp_y = -BALL_SPD 181 182 #描画メソッド 183 def draw(self, surface): 184 surface.blit(self.image, self.rect) 185#ブロッククラス 186class Block(pygame.sprite.Sprite): 187 #初期メソッド 188 def __init__(self, name, x, y): 189 pygame.sprite.Sprite.__init__(self) 190 191 #ファイルの読み込み 192 self.image = pygame.image.load(name) 193 194 #画像サイズ変更 195 self.image = pygame.transform.scale(self.image, (B_W_SIZE, B_H_SIZE)) 196 197 #ブロックオブジェクト生成 198 self.rect = self.image.get_rect() 199 200 #ブロック位置設定 201 self.rect.left = x * (self.rect.width + B_BLANK) + B_LEFT 202 self.rect.top = y * (self.rect.height + B_BLANK) + B_TOP 203 204 #描画メソッド 205 def draw(self, surface): 206 surface.blit(self.image, self.rect) 207 208 209#メイン関数 210def main(): 211 #画面初期化 212 pygame.init() 213 pygame.display.set_caption("ブロック崩しゲーム") 214 surface = pygame.display.set_mode(SURFACE.size) 215 216 #ブロック作成 217 blocks = pygame.sprite.Group() 218 for x in range(B_X_NUM): #ブロック横 219 for y in range(B_Y_NUM): #ブロック縦 220 blocks.add(Block("fabric_mark_rectangle.png", x, y)) 221 #スプライト作成 222 racket = Racket("sports_tennis_racket.png") 223 ball = Ball("sport_tennis_ball.png", racket, blocks) 224 225 #クロックオブジェクトの生成 226 clock = pygame.time.Clock() 227 228 #ラケット初期位置 229 racket_pos = int(SURFACE.width / 2) 230 231 #STARTを表示 232 font = pygame.font.Font(None, F_SIZE) 233 text = font.render("START", True, (96,96,255)) 234 surface.fill((0,0,0)) 235 surface.blit(text, (133, 299)) 236 pygame.display.update() 237 #一時停止 238 time.sleep(S_TIME) 239 240 #無限ループ 241 while True: 242 #フレームレート設定 243 clock.tick(F_RATE) 244 245 #背景色設定 246 surface.fill((0, 200, 100)) 247 248 #スプライトを更新 249 racket.update(racket_pos) 250 ball.update(surface) 251 252 #スプライトを描画 253 racket.draw(surface) 254 ball.draw(surface) 255 blocks.draw(surface) 256 257 #画面更新 258 pygame.display.update() 259 260 #イベント処理 261 for event in pygame.event.get(): 262 263 #終了処理 264 if event.type == QUIT: #ウインドウのXボタンを押した時 265 exit() 266 if event.type == KEYDOWN: #キーを押すイベント発生時 267 if event.key == K_ESCAPE: 268 exit() 269 270# 終了処理 271def exit(): 272 pygame.quit() 273 sys.exit() 274 275#トップレベルの処理 276if __name__ == "__main__": 277 main() 278
補足情報(FW/ツールのバージョンなど)
Pythonの拡張パッケージであるpygameを用いて、シンプルなブロック崩しを作成中です。
Python3.0以上ということは把握しております。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/01/11 02:19