見出し画像

Pyhonではゲームを作るのに複雑なプログラムになる


Tkinerでシューティングゲームの簡単なプログラムを書いた

◎ソースコード


import tkinter as tk
import random

# ゲームウィンドウの設定

WIDTH = 600
HEIGHT = 800
PLAYER_WIDTH = 50
PLAYER_HEIGHT = 50
ENEMY_WIDTH = 50
ENEMY_HEIGHT = 50
BULLET_WIDTH = 5
BULLET_HEIGHT = 10
class Game:
    def __init__(self, root):
        self.root = root
        self.root.title("シューティングゲーム")
        self.canvas = tk.Canvas(self.root, width=WIDTH, height=HEIGHT, bg="black")
        self.canvas.pack()

# プレイヤーの設定

        self.player = self.canvas.create_rectangle(WIDTH//2 - PLAYER_WIDTH//2,HEIGHT - PLAYER_HEIGHT - 10,WIDTH//2 + PLAYER_WIDTH//2, HEIGHT - 10, fill="blue")
        self.bullets = []
        self.enemies = []
        self.score = 0
        self.game_over = False

# キーイベントの設定

        self.canvas.bind_all("<Left>", self.move_left)
        self.canvas.bind_all("<Right>", self.move_right)
        self.canvas.bind_all("<space>", self.shoot)
        self.update_game()
    def move_left(self, event):
        if not self.game_over:
            self.canvas.move(self.player, -20, 0)
    def move_right(self, event):
        if not self.game_over:
            self.canvas.move(self.player, 20, 0)
    def shoot(self, event):
        if not self.game_over:
            bullet_coords = self.canvas.coords(self.player)
            bullet = self.canvas.create_rectangle(
                bullet_coords[0] + PLAYER_WIDTH//2 - BULLET_WIDTH//2,
                bullet_coords[1] - BULLET_HEIGHT,
                bullet_coords[0] + PLAYER_WIDTH//2 + BULLET_WIDTH//2,
                bullet_coords[1],
                fill="white"
            )
            self.bullets.append(bullet)
    def update_game(self):
        if self.game_over:
            self.canvas.create_text(WIDTH//2, HEIGHT//2, text="ゲームオーバー",fill="red", font=("Arial", 30))
            return

# 敵の出現と移動

        self.spawn_enemies()
        self.move_bullets()
        self.move_enemies()
        self.check_collisions()
        self.update_score()
        self.root.after(20, self.update_game)
    def spawn_enemies(self):
        if random.random() < 0.05:
            x = random.randint(0, WIDTH - ENEMY_WIDTH)
            y = -ENEMY_HEIGHT
            enemy = self.canvas.create_rectangle(x, y, x + ENEMY_WIDTH, y +ENEMY_HEIGHT, fill="red")
            self.enemies.append(enemy)
    def move_bullets(self):
        for bullet in self.bullets[:]:
            self.canvas.move(bullet, 0, -10)
            if self.canvas.coords(bullet)[1] < 0:
                self.canvas.delete(bullet)
                self.bullets.remove(bullet)
    def move_enemies(self):
        for enemy in self.enemies[:]:
            self.canvas.move(enemy, 0, 5)
            if self.canvas.coords(enemy)[1] > HEIGHT:
                self.canvas.delete(enemy)
                self.enemies.remove(enemy)
    def check_collisions(self):
        player_coords = self.canvas.coords(self.player)

# 弾と敵の衝突

        for enemy in self.enemies[:]:
            enemy_coords = self.canvas.coords(enemy)
            for bullet in self.bullets[:]:
                bullet_coords = self.canvas.coords(bullet)
                if (enemy_coords[0] < bullet_coords[2] and enemy_coords[2] >bullet_coords[0] and
                    enemy_coords[1] < bullet_coords[3] and enemy_coords[3] >bullet_coords[1]):
                    self.canvas.delete(enemy)
                    self.canvas.delete(bullet)
                    self.enemies.remove(enemy)
                    self.bullets.remove(bullet)
                    self.score += 10

# プレイヤーと敵の衝突

        for enemy in self.enemies[:]:
            enemy_coords = self.canvas.coords(enemy)
            if (player_coords[0] < enemy_coords[2] and player_coords[2] >enemy_coords[0] and
                player_coords[1] < enemy_coords[3] and player_coords[3] >enemy_coords[1]):
                self.game_over = True
                return
    def update_score(self):
        self.canvas.delete("score")
        self.canvas.create_text(10, 10, anchor="nw", text=f"スコア: {self.score}",fill="white", font=("Arial", 20), tags="score")

if __name__ == "__main__":
    root = tk.Tk()
    game = Game(root)
    root.mainloop()



このコードは、PythonのTkinterライブラリを使用して、シンプルなシューティングゲームを作成しています。ゲームはプレイヤーが左右に移動し、スペースキーで弾を発射し、敵を撃墜するものです。敵はランダムに画面上部から現れ、画面下部に到達すると消えます。プレイヤーと敵が衝突するとゲームオーバーになります。

コードを順を追って説明します。


1. ゲームウィンドウの設定

WIDTH = 600 
HEIGHT = 800 
PLAYER_WIDTH = 50 
PLAYER_HEIGHT = 50 
ENEMY_WIDTH = 50 
ENEMY_HEIGHT = 50 
BULLET_WIDTH = 5 
BULLET_HEIGHT = 10
  • ゲームの画面サイズやプレイヤー、敵、弾のサイズを設定しています。


2. Game クラス

ゲームの主要なロジックを担当するクラスです。

__init__ メソッド

def __init__(self, root): 
    self.root = root 
    self.root.title("シューティングゲーム") 
    self.canvas = tk.Canvas(self.root, width=WIDTH, height=HEIGHT, bg="black") 
    self.canvas.pack()
 
    self.player = self.canvas.create_rectangle(WIDTH//2 - PLAYER_WIDTH//2, HEIGHT - PLAYER_HEIGHT - 10, WIDTH//2 + PLAYER_WIDTH//2, HEIGHT - 10, fill="blue") 

    self.bullets = [] 
    self.enemies = [] 
    self.score = 0 
    self.game_over = False 

    self.canvas.bind_all("<Left>", self.move_left) 
    self.canvas.bind_all("<Right>", self.move_right) 
    self.canvas.bind_all("<space>", self.shoot) 

    self.update_game()
  • ゲームウィンドウの初期設定を行い、Canvasを使って描画しています。

  • プレイヤーの矩形を作成し、左右の移動と弾の発射のためのキーイベントをバインドしています。

  • ゲームの状態を管理するための変数(スコア、弾、敵、ゲームオーバー)もここで初期化されています。


move_left メソッド

def move_left(self, event): 
    if not self.game_over: 
    self.canvas.move(self.player, -20, 0)
  • プレイヤーを左に移動させるメソッドです。


move_right メソッド

def move_right(self, event): 
    if not self.game_over: 
       self.canvas.move(self.player, 20, 0)
  • プレイヤーを右に移動させるメソッドです。


shoot メソッド

def shoot(self, event): 
    if not self.game_over: 
           bullet_coords = self.canvas.coords(self.player) 
           bullet = self.canvas.create_rectangle( 
                  bullet_coords[0] + PLAYER_WIDTH//2 - BULLET_WIDTH//2, 
                  bullet_coords[1] - BULLET_HEIGHT, 
                  bullet_coords[0] + PLAYER_WIDTH//2 + BULLET_WIDTH//2, 
                  bullet_coords[1], fill="white" 
           ) 
           self.bullets.append(bullet)
  • プレイヤーの位置から弾を発射します。弾は白い矩形で表現され、リストself.bulletsに追加されます。


update_game メソッド

def update_game(self): 
    if self.game_over: 
        self.canvas.create_text(WIDTH//2, HEIGHT//2, text="ゲームオーバー", fill="red", font=("Arial", 30)) 
        return 

    self.spawn_enemies() 
    self.move_bullets() 
    self.move_enemies() 
    self.check_collisions() 
    self.update_score()
 
    self.root.after(20, self.update_game)
  • ゲームループを担当します。毎フレームごとに敵の出現、弾や敵の移動、衝突判定、スコアの更新を行います。


spawn_enemies メソッド

def spawn_enemies(self): 
    if random.random() < 0.05: 
        x = random.randint(0, WIDTH - ENEMY_WIDTH) 
        y = -ENEMY_HEIGHT 
        enemy = self.canvas.create_rectangle(x, y, x + ENEMY_WIDTH, y + ENEMY_HEIGHT, fill="red") 
        self.enemies.append(enemy)
  • 敵が画面上部からランダムに現れる処理です。出現確率は0.05(5%)です。


move_bullets メソッド

def move_bullets(self): 
    for bullet in self.bullets[:]: 
    self.canvas.move(bullet, 0, -10) 
    if self.canvas.coords(bullet)[1] < 0: 
        self.canvas.delete(bullet) 
        self.bullets.remove(bullet)
  • 弾を上方向に移動させ、画面外に出た弾を削除します。


move_enemies メソッド

def move_enemies(self): 
    for enemy in self.enemies[:]: 
        self.canvas.move(enemy, 0, 5) 
        if self.canvas.coords(enemy)[1] > HEIGHT: 
            self.canvas.delete(enemy) 
            self.enemies.remove(enemy)
  • 敵を下方向に移動させ、画面外に出た敵を削除します。


check_collisions メソッド

def check_collisions(self): 
    player_coords = self.canvas.coords(self.player) 

    for enemy in self.enemies[:]: 
        enemy_coords = self.canvas.coords(enemy) 
        for bullet in self.bullets[:]: 
            bullet_coords = self.canvas.coords(bullet) 
            if (enemy_coords[0] < bullet_coords[2] and enemy_coords[2] > bullet_coords[0] and
                enemy_coords[1] < bullet_coords[3] and enemy_coords[3] > bullet_coords[1]): 
                self.canvas.delete(enemy) 
                self.canvas.delete(bullet) 
                self.enemies.remove(enemy) 
                self.bullets.remove(bullet) 
                self.score += 10 
    for enemy in self.enemies[:]: 
        enemy_coords = self.canvas.coords(enemy) 
        if (player_coords[0] < enemy_coords[2] and player_coords[2] > enemy_coords[0] and 
            player_coords[1] < enemy_coords[3] and player_coords[3] > enemy_coords[1]): 
            self.game_over = True 
            return
  • 弾と敵、プレイヤーと敵の衝突をチェックします。弾が敵に当たると、敵と弾が削除され、スコアが10点増加します。プレイヤーと敵が衝突するとゲームオーバーになります。


update_score メソッド

def update_score(self): 
    self.canvas.delete("score") 
    self.canvas.create_text(10, 10, anchor="nw", text=f"スコア: {self.score}", fill="white", font=("Arial", 20), tags="score")
  • 現在のスコアを画面に表示します。


3. ゲームの開始

if __name__ == "__main__": 
    root = tk.Tk()
    game = Game(root) 
    root.mainloop()
  • Tkinterのウィンドウを作成し、ゲームを実行します。

改善案

  • ゲームの難易度調整: 敵の出現率や移動速度を段階的に上げていくことで、ゲームの難易度を上げることができます。

  • 音楽や効果音: 効果音(弾が発射される音や敵を倒した音、ゲームオーバー音)を追加してゲームの臨場感を高めることができます。

  • ゲームの開始画面と終了画面: ゲーム開始時にスタート画面を表示したり、ゲームオーバー時に再挑戦のオプションを表示することができます。


改善策』を考えると、pygameでプログラムを組んだ方が手っ取り早いです。ボスの登場、や敵が攻撃する(弾を打つ)とか、自機のアップグレードの機能などを追加することも、pygameでは容易にプログラムを組むことができます。pygameでのシューティングはYouTubeでも動画配信されていますよ😁


ではまた👋

いいなと思ったら応援しよう!

Yoshi
よろしければ応援お願いします! いただいたチップついては、高額ゲームソフトや中華ゲーム機の資金として使わせていただき、レビューできる様励んでいきます!!