Pythonプログラミング学習のためのゲーム開発例

教育向けミニゲームの実装パターン

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()

タグ: Python pygame educational-games

7月10日 18:39 投稿