教育向けミニゲームの実装パターン
Pythonを活用したプログラミング学習には、実践的なゲーム開発が効果的です。以下に2つの教育用ミニゲームの実装例を紹介します。Pygameライブラリを用いたコードは、基本的なゲームロジックの理解に適しています。
対戦型シューティングゲーム
2人同時プレイ可能な宇宙戦闘シミュレーションです。プレイヤーは自機を操作し、隕石を撃墜してスコアを競います。背景はスコアに応じて段階的に変化します。
import sys
import game_config
import pygame
from sprites import *
def run_game_loop(player_count, display_surface):
pygame.mixer.music.load(game_config.SOUND_PATHS['space_theme'])
pygame.mixer.music.set_volume(0.35)
pygame.mixer.music.play(-1)
explosion_sound = pygame.mixer.Sound(game_config.SOUND_PATHS['explosion'])
shot_sound = pygame.mixer.Sound(game_config.SOUND_PATHS['laser'])
score_font = pygame.font.Font(game_config.FONT_PATH, 22)
background_images = [
pygame.image.load(game_config.BG_PATHS['stage1']),
pygame.image.load(game_config.BG_PATHS['stage2']),
pygame.image.load(game_config.BG_PATHS['stage3'])
]
scroll_offset = 0
current_background = background_images[0]
player_sprites = pygame.sprite.Group()
projectile_sprites = pygame.sprite.Group()
obstacle_sprites = pygame.sprite.Group()
obstacle_timer = 85
for i in range(player_count):
player_sprites.add(Spacecraft(i+1, game_config))
clock = pygame.time.Clock()
player1_score = player2_score = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
keys = pygame.key.get_pressed()
for index, craft in enumerate(player_sprites):
movement = None
if index == 0:
if keys[pygame.K_w]: movement = 'up'
elif keys[pygame.K_s]: movement = 'down'
elif keys[pygame.K_a]: movement = 'left'
elif keys[pygame.K_d]: movement = 'right'
if movement: craft.move(movement)
if keys[pygame.K_v] and craft.cooldown == 0:
shot_sound.play()
projectile_sprites.add(LaserBeam(craft.rect.center, 1))
craft.cooldown = 25
else:
if keys[pygame.K_UP]: movement = 'up'
elif keys[pygame.K_DOWN]: movement = 'down'
elif keys[pygame.K_LEFT]: movement = 'left'
elif keys[pygame.K_RIGHT]: movement = 'right'
if movement: craft.move(movement)
if keys[pygame.K_RETURN] and craft.cooldown == 0:
shot_sound.play()
projectile_sprites.add(LaserBeam(craft.rect.center, 2))
craft.cooldown = 25
if craft.cooldown > 0: craft.cooldown -= 1
total_score = player1_score + player2_score
if total_score < 1000:
current_background = background_images[0]
elif total_score < 3000:
current_background = background_images[1]
else:
current_background = background_images[2]
display_surface.blit(current_background, (0, -current_background.get_height() + scroll_offset))
display_surface.blit(current_background, (0, scroll_offset))
scroll_offset = (scroll_offset + 3) % current_background.get_height()
if obstacle_timer == 0:
obstacle_timer = 85
obstacle_sprites.add(Meteor(game_config))
else:
obstacle_timer -= 1
for craft in player_sprites:
if pygame.sprite.spritecollide(craft, obstacle_sprites, True):
craft.explosion_frame = 1
explosion_sound.play()
elif craft.explosion_frame > 0:
if craft.explosion_frame > 4:
player_sprites.remove(craft)
if not player_sprites: return
else:
craft.show_explosion(display_surface)
else:
craft.draw(display_surface)
for projectile in projectile_sprites:
projectile.update()
if pygame.sprite.spritecollide(projectile, obstacle_sprites, True):
projectile_sprites.remove(projectile)
if projectile.owner == 1:
player1_score += 1
else:
player2_score += 1
else:
projectile.draw(display_surface)
for obstacle in obstacle_sprites:
obstacle.update()
obstacle.rotate()
obstacle.draw(display_surface)
score_text1 = f'Player A: {player1_score}'
score_text2 = f'Player B: {player2_score}'
display_surface.blit(score_font.render(score_text1, True, (0, 180, 255)), (10, 10))
display_surface.blit(score_font.render(score_text2, True, (255, 60, 60)), (10, 40))
pygame.display.update()
clock.tick(60)
マッチングパズルゲーム
色の一致した宝石を3つ以上揃えて消去するパズルゲームです。スコア表示とサウンドエフェクトを実装しています。
import os
import pygame
from game_engine import PuzzleBoard
def main_game():
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Color Match Challenge')
pygame.mixer.music.load(os.path.join('assets', 'audio', 'background.mp3'))
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1)
sound_effects = {
'invalid': pygame.mixer.Sound(os.path.join('assets', 'audio', 'error.wav')),
'valid': [pygame.mixer.Sound(os.path.join('assets', 'audio', f'match{i}.wav')) for i in range(1, 7)]
}
game_font = pygame.font.Font(os.path.join('assets', 'fonts', 'main.ttf'), 28)
gem_assets = [pygame.image.load(os.path.join('assets', 'gems', f'gem{i}.png')) for i in range(1, 8)]
game_board = PuzzleBoard(screen, sound_effects, game_font, gem_assets)
while True:
final_score = game_board.start_game()
restart_requested = False
while not restart_requested:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
return
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
restart_requested = True
screen.fill((100, 149, 237))
messages = [
f'Total Score: {final_score}',
'Press R to restart',
'Press ESC to exit'
]
for i, msg in enumerate(messages):
text_surf = game_font.render(msg, True, (45, 25, 0))
text_rect = text_surf.get_rect(center=(400, 200 + i*70))
screen.blit(text_surf, text_rect)
pygame.display.flip()
game_board.reset_board()