3
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?

メリークリスマス!クリスマスツリーを飾ってサンタさんをお出迎え!pythonで簡単なゲーム作ってみた!

Last updated at Posted at 2024-12-24

メリークリスマス!

起動すると下のような画面が表示されます。ちなみに画像なので少し分かりづらいですが、周りにあるまばらな点はイルミネーションのつもりです。

クリスマスツリーの中に少し大きめの白丸が4つあるのですが、ここをクリックすると飾り付けできます。

全て飾り付けが終わると雪が降り始めて、サンタさんがやってくるという仕様です。

実装

コードまとめ
import pygame
import random
import sys
import math

# 初期設定
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("クリスマスツリー")
clock = pygame.time.Clock()

# 色の定義
GREEN = (34, 139, 34)
BROWN = (139, 69, 19)
WHITE = (255, 255, 255)
ORANGE = (255, 165, 0)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)

# イルミネーションの位置
lights = [(random.randint(300, 500), random.randint(150, 500)) for _ in range(25)]

# 飾り付けすべき位置
decor_positions = [(360, 235), (445, 300), (320, 380), (480, 480)]
placed_decorations = []

# 状態
game_over = False

# サンタの画像をロード
santa_image = pygame.image.load("santa_claus.png")
santa_image = pygame.transform.scale(santa_image, (450, 450))  # サンタ画像のサイズを調整
santa_position = (175, 150)  # サンタ画像の表示位置

# デコレーションの画像をロードしてリストに追加
decor_image_paths = [
    "decorations/christmas_oranament_red.png", 
    "decorations/christmas_oranament_orange.png", 
    "decorations/christmas_oranament_blue.png", 
    "decorations/christmas_oranament_green.png"
    ]

def load_decorations():
    decorations = []
    for path in decor_image_paths:
        img = pygame.image.load(path)
        img = pygame.transform.scale(img, (60, 80))  # 画像サイズを調整
        decorations.append(img)
    return decorations

decorations_images = load_decorations()

# 星型を描く関数
def draw_star(surface, color, center, outer_radius, inner_radius, num_points):
    points = []
    angle = math.pi / num_points  # 1つの頂点間の角度
    start_angle = -math.pi / 2    # 90度上方向からスタート

    for i in range(num_points * 2):
        # 外側と内側の頂点を交互に計算
        radius = outer_radius if i % 2 == 0 else inner_radius
        theta = start_angle + i * angle
        x = center[0] + radius * math.cos(theta)
        y = center[1] + radius * math.sin(theta)
        points.append((x, y))

    # 星型を描画
    pygame.draw.polygon(surface, color, points)
    

def draw_tree():
    # 背景
    screen.fill((0, 0, 0))
    
    # 幹
    pygame.draw.rect(screen, BROWN, (360, 400, 80, 200))
    
    # ツリーの3つの三角形
    pygame.draw.polygon(screen, GREEN, [(400, 100), (300, 300), (500, 300)])
    pygame.draw.polygon(screen, GREEN, [(400, 200), (270, 400), (530, 400)])
    pygame.draw.polygon(screen, GREEN, [(400, 300), (250, 500), (550, 500)])
    
    # 星
    draw_star(screen, YELLOW, (400, 95), 30, 10, 5)  # 星型を描画

def illuminate_lights():
    for x, y in lights:
        color = random.choice([ORANGE, BLUE, WHITE, YELLOW])
        pygame.draw.circle(screen, color, (x, y), 5)

def draw_decorations():
    for x, y in decor_positions:
        pygame.draw.circle(screen, WHITE, (x, y), 10, 1)  # 枠線だけの円で飾り付け位置を表示
    for (x, y), img in zip(placed_decorations, decorations_images):
        screen.blit(img, (x-30, y-10))  # デコレーション画像を描画する位置を調整

        # 枠線を削除する
        pygame.draw.circle(screen, WHITE, (x, y), 10, 0)

# 雪の粒を初期化
snowflakes = [{"x": random.randint(0, 800), "y": random.randint(-600, 0), "speed": random.uniform(1, 3)} for _ in range(100)]

def update_and_draw_snowflakes():
    global snowflakes
    for flake in snowflakes:
        flake["y"] += flake["speed"]
        if flake["y"] > 600:  # 画面下に到達したら、上から再生成
            flake["x"] = random.randint(0, 800)
            flake["y"] = random.randint(-50, -10)
            flake["speed"] = random.uniform(3, 5)
        pygame.draw.circle(screen, WHITE, (int(flake["x"]), int(flake["y"])), 3)


# メインループの変更
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
            mouse_x, mouse_y = event.pos
            for pos in decor_positions:
                if pos not in placed_decorations and (mouse_x - pos[0])**2 + (mouse_y - pos[1])**2 <= 100:
                    placed_decorations.append(pos)
                    break
            if len(placed_decorations) == len(decor_positions):
                game_over = True

    if game_over:
        screen.fill((0, 0, 0))  # 背景を黒にする
        update_and_draw_snowflakes()  # 雪を描画
        # サンタ画像を描画
        screen.blit(santa_image, santa_position)
    else:
        draw_tree()
        illuminate_lights()
        draw_decorations()
    
    pygame.display.flip()
    clock.tick(30)

初期設定と基本構造

Pygameライブラリを初期化、画面設定、フレームレート管理をしています。

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("クリスマスツリー")
clock = pygame.time.Clock()

色と装飾の準備

色の定義、イルミネーションの位置、装飾の位置、配置済み装飾リストの準備をしています。

GREEN = (34, 139, 34)
BROWN = (139, 69, 19)
WHITE = (255, 255, 255)
ORANGE = (255, 165, 0)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)

lights = [(random.randint(300, 500), random.randint(150, 500)) for _ in range(25)]
decor_positions = [(360, 235), (445, 300), (320, 380), (480, 480)]
placed_decorations = []

ツリーと星の描画

背景、ツリーの幹、ツリーの葉、星お描画しています。

def draw_tree():
    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, BROWN, (360, 400, 80, 200))
    pygame.draw.polygon(screen, GREEN, [(400, 100), (300, 300), (500, 300)])
    pygame.draw.polygon(screen, GREEN, [(400, 200), (270, 400), (530, 400)])
    pygame.draw.polygon(screen, GREEN, [(400, 300), (250, 500), (550, 500)])
    draw_star(screen, YELLOW, (400, 95), 30, 10, 5)

動的要素の描画

イルミネーション

ランダムな色のライトを小さな円形で描画しています。

def illuminate_lights():
    for x, y in lights:
        color = random.choice([ORANGE, BLUE, WHITE, YELLOW])
        pygame.draw.circle(screen, color, (x, y), 5)

雪の描画

雪を動的に描画し、画面下部に到達した雪を再利用して無限ループを作成しています。

snowflakes = [{"x": random.randint(0, 800), "y": random.randint(-600, 0), "speed": random.uniform(1, 3)} for _ in range(100)]

def update_and_draw_snowflakes():
    for flake in snowflakes:
        flake["y"] += flake["speed"]
        if flake["y"] > 600:
            flake["x"] = random.randint(0, 800)
            flake["y"] = random.randint(-50, -10)
            flake["speed"] = random.uniform(3, 5)
        pygame.draw.circle(screen, WHITE, (int(flake["x"]), int(flake["y"])), 3)

ユーザーインタラクティブとメインループ

ユーザーインタラクティブ

ユーザーのクリックを検知し、装飾位置から近い場所にデコレーションを追加します。

for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
        mouse_x, mouse_y = event.pos
        for pos in decor_positions:
            if pos not in placed_decorations and (mouse_x - pos[0])**2 + (mouse_y - pos[1])**2 <= 100:
                placed_decorations.append(pos)
                break
        if len(placed_decorations) == len(decor_positions):
            game_over = True

メインループ

ゲームの状態に応じてツリーや装飾を描画し、ゲームオーバー後はサンタと雪を表示します。

while True:
    if game_over:
        screen.fill((0, 0, 0))
        update_and_draw_snowflakes()
        screen.blit(santa_image, santa_position)
    else:
        draw_tree()
        illuminate_lights()
        draw_decorations()
    
    pygame.display.flip()
    clock.tick(30)

サンタの追加とゲーム終了

サンタクロースの画像をロードし、サイズを調整してゲーム終了時に表示します。
全ての装飾が配置された時点で、game_overフラグが有効になり、サンタ画像と雪が表示されます。

santa_image = pygame.image.load("santa_claus.png")
santa_image = pygame.transform.scale(santa_image, (450, 450))
santa_position = (175, 150)

まとめ

今回は複雑な工程を含んでいないので、簡単にかわいい感じのゲームを実装できました。
興味があれば皆さんも実装してみてください。

3
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
3
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?