Python 言語の習得において、アルゴリズムや文法を理解するだけでなく、実際の応用事例に触れることは重要です。ここでは、GUI フレームワークやグラフィックスライブラリを使用した、実行可能なサンプルコードをいくつか紹介します。これらのプロジェクトは、Tkinter、Pygame、および Turtle モジュールの基本的な操作を実践するための教材として機能します。
Tkinter を用いたブロック組み立てゲーム
ウィジェットベースのインタフェース作成を学ぶために、グリッド管理とキーボードイベントバインドを含むブロックパズルゲームの実装例です。座標系のカスタマイズや状態管理に焦点を当てています。
import tkinter as tk
from tkinter import messagebox
# グリッド定義
GRID_WIDTH = 10
GRID_HEIGHT = 20
CELL_SIZE = 25
class PuzzleGame(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.master = master
self.score = 0
self.lines_cleared = 0
self.init_ui()
def init_ui(self):
# ウィンドセットアップ
self.grid(row=0, column=0)
self.canvas = tk.Canvas(self, width=GRID_WIDTH*CELL_SIZE,
height=GRID_HEIGHT*CELL_SIZE, bg='black')
self.canvas.grid()
# ステータス表示
self.status_label = tk.Label(self, text="Score: 0", fg="white", bg="#333")
self.status_label.grid(row=0, column=GRID_WIDTH, padx=10)
# イベントバインド
self.master.bind('<Key>', self.handle_input)
self.game_active = True
def handle_input(self, event):
key = event.keysym
if key == 'Right':
self.move_block(1, 0)
elif key == 'Left':
self.move_block(-1, 0)
elif key == 'Up':
self.rotate_block()
elif key == 'Down':
self.move_block(0, 1)
def move_block(self, dx, dy):
# ロジック:現在の位置更新と衝突判定
# 簡略化した移動処理
pass
def rotate_block(self):
# ロジック:形状変換処理
pass
if __name__ == '__main__':
root = tk.Tk()
root.title("ブロック パズル")
app = PuzzleGame(root)
app.mainloop()
Pygame によるアーケード風ゲーム
リアルタイム描画とイベントループ制御を理解するための、クラシックな動きを持つサークル追跡ゲームの実装です。外部ライブラリの利用と描画ループの制御方法を示しています。
import pygame
import random
import sys
# 定数設定
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
FRAME_RATE = 60
BLOCK_SIZE = 20
# 色の定義
COLOR_BG = (0, 0, 0)
COLOR_PLAYER = (0, 255, 0)
COLOR_TARGET = (255, 0, 0)
def main():
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
clock = pygame.time.Clock()
player_pos = [WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2]
target_pos = [random.randint(0, WINDOW_WIDTH), random.randint(0, WINDOW_HEIGHT)]
running = True
score = 0
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
speed = 5
if keys[pygame.K_LEFT]: player_pos[0] -= speed
if keys[pygame.K_RIGHT]: player_pos[0] += speed
if keys[pygame.K_UP]: player_pos[1] -= speed
if keys[pygame.K_DOWN]: player_pos[1] += speed
# 画面クリア
screen.fill(COLOR_BG)
# プレイヤー描画
pygame.draw.rect(screen, COLOR_PLAYER,
(player_pos[0], player_pos[1], BLOCK_SIZE, BLOCK_SIZE))
# 対象物描画
pygame.draw.rect(screen, COLOR_TARGET,
(target_pos[0], target_pos[1], BLOCK_SIZE, BLOCK_SIZE))
if player_pos == target_pos:
target_pos = [random.randint(0, WINDOW_WIDTH), random.randint(0, WINDOW_HEIGHT)]
score += 1
pygame.display.flip()
clock.tick(FRAME_RATE)
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
Turtle モジュールを用いた幾何学的描写
図形描画 API の基本操作を学ぶための、数学的パターンや複雑な曲線の自動生成スクリプトです。
import turtle
import time
screen = turtle.Screen()
screen.bgcolor("black")
pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)
colors = ["red", "orange", "yellow", "green", "cyan", "blue", "purple"]
size = 200
angle = 90
# 幾何学的パターンの生成
for i in range(360):
pen.pencolor(colors[i % len(colors)])
pen.forward(i * 2)
pen.right(angle + 1)
pen.width(i / 20)
time.sleep(3)
screen.bye()
さらに、時計の針の動作や有機的な形態を描く場合でも同様の原理が適用されます。以下は時制情報を反映する実装例です。
import datetime
import turtle as t
def draw_hand(length, angle, color="white"):
t.penup()
t.home()
t.setheading(90)
t.right(angle)
t.pendown()
t.color(color)
t.forward(length)
def main():
now = datetime.datetime.now()
sec = now.second
minute = now.minute
hour = now.hour
t.setup(500, 500)
t.tracer(0)
# 時計の中心点調整
t.penup()
t.goto(0, -100)
t.dot(10)
# 針の描画
draw_hand(50, hour * 30 + minute * 0.5, "gold")
draw_hand(80, minute * 6, "silver")
draw_hand(100, sec * 6, "red")
t.update()
t.done()
if __name__ == '__main__':
main()
インタラクティブなウィジェット挙動テスト
ボタンのホバーイベントを処理し、ウィンドウの状態を動的に変更する Tkinter の応用例です。単純なロジックフローの理解に適しています。
import tkinter as tk
class ButtonSwapDemo:
def __init__(self):
self.window = tk.Tk()
self.window.geometry("300x200")
self.label = tk.Label(self.window, text="ボタンを押す", bg="lightgray")
self.label.pack(pady=20)
btn_yes = tk.Button(self.window, text="はい")
btn_no = tk.Button(self.window, text="いいえ")
btn_yes.pack(side=tk.LEFT, padx=10)
btn_no.pack(side=tk.RIGHT, padx=10)
btn_yes.bind("<Enter>", lambda e: btn_yes.config(bg="green"))
btn_yes.bind("<Leave>", lambda e: btn_yes.config(bg="lightgray"))
btn_no.bind("<Enter>", lambda e: btn_no.config(bg="red"))
btn_no.bind("<Leave>", lambda e: btn_no.config(bg="lightgray"))
self.window.mainloop()
if __name__ == "__main__":
demo = ButtonSwapDemo()
スクリーンセーバー効果の実装
多数のドローイングオブジェクトを並行して移動させることで、特定のビジュアルエフェクトを再現します。配列操作と描画オーバーヘッドの管理を学びます。
import pygame
import random
WIDTH = 640
HEIGHT = 480
FPS = 30
class RainChar(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.char = chr(random.randint(0x30A0, 0x30FF))
self.color = (0, 255, 0)
self.font_size = 15
self.font = pygame.font.Font(None, self.font_size)
self.text_surf = self.font.render(self.char, True, self.color)
self.x = random.random() * WIDTH
self.y = -self.font_size
self.speed = random.randint(5, 10)
def update(self):
self.y += self.speed
if self.y > HEIGHT:
self.kill()
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
chars = pygame.sprite.Group()
try:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit
chars.add(RainChar())
screen.fill((0, 0, 0))
chars.draw(screen)
chars.update()
pygame.display.flip()
clock.tick(FPS)
except SystemExit:
pass