はじめに
pythonとpygameでブロック崩し風のゲーム作りたいな。
説明
・白い四角 : 自機
・赤い丸 : ブロックを崩す玉
・青い四角 : ブロック
・タイトル画面をクリックするとゲーム画面にいく
・ブロックを全部崩した場合や赤い玉を拾えなかった場合、3秒後にタイトルに戻る
・ゲーム中にクリックするとポーズ画面になり「Pause」と表示する
・最後クリックするとポーズが終わりゲームに戻る
ソースコード
py main.py
import pygame
import random
# Pygameの初期化
pygame.init()
# ウィンドウの設定
width, height = 800, 600
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Breakout")
# 色の定義
black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (0, 255, 0)
# フレームレート
clock = pygame.time.Clock()
fps = 60
# パドルの設定
paddle_width = 100
paddle_height = 10
paddle_x = (width - paddle_width) // 2
paddle_y = height - 40
paddle_speed = 10
# ボールの設定
ball_size = 10
ball_x = width // 2
ball_y = height // 2
ball_speed_x = 4
ball_speed_y = -4
# ブロックの設定
block_rows = 5
block_cols = 10
block_width = width // block_cols
block_height = 20
# フォントの設定
font_large = pygame.font.Font(None, 74)
font_small = pygame.font.Font(None, 36)
def draw_text(text, font, color, surface, x, y):
text_obj = font.render(text, True, color)
text_rect = text_obj.get_rect()
text_rect.center = (x, y)
surface.blit(text_obj, text_rect)
def title_screen():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
return
win.fill(black)
draw_text("Breakout", font_large, white, win, width / 2, height / 2 - 50)
draw_text("Click to start", font_small, white, win, width / 2, height / 2 + 50)
pygame.display.update()
clock.tick(fps)
def pause_screen(background):
paused = True
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
paused = False
win.blit(background, (0, 0))
draw_text("Pause", font_large, white, win, width / 2, height / 2)
pygame.display.update()
clock.tick(fps)
def game():
paddle_x = (width - paddle_width) // 2
ball_x, ball_y = width // 2, height // 2
ball_speed_x, ball_speed_y = 4, -4
blocks = [pygame.Rect(col * block_width, row * block_height, block_width, block_height)
for row in range(block_rows) for col in range(block_cols)]
game_clear, game_over = False, False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
background = win.copy()
pause_screen(background)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and paddle_x > 0:
paddle_x -= paddle_speed
if keys[pygame.K_RIGHT] and paddle_x < width - paddle_width:
paddle_x += paddle_speed
ball_x += ball_speed_x
ball_y += ball_speed_y
# 壁との衝突
if ball_x <= 0 or ball_x >= width - ball_size:
ball_speed_x = -ball_speed_x
if ball_y <= 0:
ball_speed_y = -ball_speed_y
if ball_y >= height:
game_over = True
running = False
# パドルとの衝突
paddle_rect = pygame.Rect(paddle_x, paddle_y, paddle_width, paddle_height)
ball_rect = pygame.Rect(ball_x, ball_y, ball_size, ball_size)
if paddle_rect.colliderect(ball_rect):
ball_speed_y = -ball_speed_y
# ブロックとの衝突
for block in blocks[:]:
if block.colliderect(ball_rect):
ball_speed_y = -ball_speed_y
blocks.remove(block)
# 画面の描画
win.fill(black)
pygame.draw.rect(win, white, paddle_rect)
pygame.draw.ellipse(win, red, ball_rect)
for block in blocks:
pygame.draw.rect(win, blue, block)
# ブロックが全て破壊された場合
if not blocks:
game_clear = True
running = False
pygame.display.update()
clock.tick(fps)
return game_clear, game_over
def main():
while True:
title_screen()
game_clear, game_over = game()
if game_clear:
win.fill(black)
draw_text("Game Clear!", font_large, green, win, width / 2, height / 2)
pygame.display.update()
pygame.time.wait(3000)
elif game_over:
win.fill(black)
draw_text("Game Over...", font_large, red, win, width / 2, height / 2)
pygame.display.update()
pygame.time.wait(3000)
if __name__ == "__main__":
main()
pygame.quit()
起動
$ python main.py
ゲーム画面
終わり
できた。