0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

インベーダーゲームを作ってみた #100日チャレンジ に感化されて

Last updated at Posted at 2025-05-04

インベーダーゲーム(のようなもの)を作ってみた

(5/6 難易度設定を追加してみました)
そろそろゲーム以外の制作にも挑戦したい!
#100日チャレンジ に感化されて

タイトルなし.gif

import pygame
import random
import sys

def select_difficulty(screen, WHITE, BLACK):
    font = pygame.font.SysFont(None, 50)
    while True:
        screen.fill(BLACK)
        easy_text = font.render("1: Easy", True, WHITE)
        normal_text = font.render("2: Normal", True, WHITE)
        hard_text = font.render("3: Hard", True, WHITE)
        screen.blit(easy_text, (200, 200))
        screen.blit(normal_text, (200, 300))
        screen.blit(hard_text, (200, 400))
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_1:
                    return "easy"
                elif event.key == pygame.K_2:
                    return "normal"
                elif event.key == pygame.K_3:
                    return "hard"

def show_end_screen(screen, font, message, BLUE, WHITE):
    text = font.render(message, True, WHITE)
    screen.blit(text, (300 - text.get_width() // 2, 340))

    retry_rect = pygame.Rect(225, 410, 150, 50)
    pygame.draw.rect(screen, BLUE, retry_rect)
    retry_text = font.render("RETRY", True, WHITE)
    screen.blit(retry_text, (retry_rect.x + 25, retry_rect.y + 10))
    pygame.display.flip()

    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN and retry_rect.collidepoint(event.pos):
                waiting = False
                return  # 戻ってrun_gameを再スタートする

def run_game():
    pygame.init()

    WIDTH, HEIGHT = 600, 800
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Invader Game")
    clock = pygame.time.Clock()

    # 色
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    BLUE = (100, 100, 255)

    # 難易度選択
    difficulty = select_difficulty(screen, WHITE, BLACK)
    if difficulty == "easy":
        enemy_width, enemy_height = 50, 40
    elif difficulty == "normal":
        enemy_width, enemy_height = 40, 30
    else:
        enemy_width, enemy_height = 30, 20

    # フォント
    font_small = pygame.font.SysFont(None, 36)
    font_large = pygame.font.SysFont(None, 60)

    # プレイヤー
    player_img = pygame.Surface((50, 30))
    player_img.fill(WHITE)
    player_rect = player_img.get_rect(center=(WIDTH // 2, HEIGHT - 50))
    player_speed = 5

    # 弾
    bullets = []
    bullet_speed = -10

    # 敵
    enemy_img = pygame.Surface((enemy_width, enemy_height))
    enemy_img.fill((0, 255, 0))
    enemies = []
    enemy_speed_y = 20
    for row in range(4):
        for col in range(6):
            x = 80 + col * 70
            y = 50 + row * 50
            rect = pygame.Rect(x, y, enemy_width, enemy_height)
            direction = random.choice([-1, 1])
            speed = random.randint(1, 3)
            enemies.append({"rect": rect, "dx": direction * speed})

    score = 0
    start_ticks = pygame.time.get_ticks()
    running = True

    while running:
        screen.fill(BLACK)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        # キー入力
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] and player_rect.left > 0:
            player_rect.x -= player_speed
        if keys[pygame.K_RIGHT] and player_rect.right < WIDTH:
            player_rect.x += player_speed
        if keys[pygame.K_SPACE]:
            if len(bullets) < 5:
                bullets.append(pygame.Rect(player_rect.centerx - 2, player_rect.top, 4, 10))

        # 弾移動
        for bullet in bullets[:]:
            bullet.y += bullet_speed
            if bullet.bottom < 0:
                bullets.remove(bullet)

        # 敵移動
        for enemy in enemies:
            rect = enemy["rect"]
            rect.x += enemy["dx"]
            if rect.left < 0 or rect.right > WIDTH:
                rect.y += enemy_speed_y
                enemy["dx"] *= -1

        # 当たり判定
        for bullet in bullets[:]:
            for enemy in enemies[:]:
                if bullet.colliderect(enemy["rect"]):
                    bullets.remove(bullet)
                    enemies.remove(enemy)
                    score += 100
                    break

        # 敵到達でゲームオーバー
        for enemy in enemies:
            if enemy["rect"].bottom > HEIGHT - 100:
                show_end_screen(screen, font_large, "GAME OVER", BLUE, WHITE)
                run_game()
                return

        # 描画
        screen.blit(player_img, player_rect)
        for bullet in bullets:
            pygame.draw.rect(screen, WHITE, bullet)
        for enemy in enemies:
            screen.blit(enemy_img, enemy["rect"])

        # スコアと時間表示
        score_text = font_small.render(f"Score: {score}", True, WHITE)
        screen.blit(score_text, (10, 10))
        elapsed = (pygame.time.get_ticks() - start_ticks) // 1000
        time_text = font_small.render(f"Time: {elapsed}s", True, WHITE)
        screen.blit(time_text, (WIDTH - 150, 10))

        # 勝利判定
        if not enemies:
            show_end_screen(screen, font_large, "YOU WIN!", BLUE, WHITE)
            run_game()
            return

        pygame.display.flip()
        clock.tick(60)

if __name__ == "__main__":
    run_game()

気に入った方は,いいね👍お願いします!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?