[ 参照リンク:Pythonのロジックゲート](https://www.imangodoc.com/221.html)
前書き
python言語は最近注目を集めています。科学コンピューティングの分野での有用性に加えて、pythonはゲームやバックエンドでも輝いています。このブログ投稿では、正式なプロジェクト開発プロセスに従ってpythonゲームを作成する方法を説明します。このプロジェクトは、「入門から実践までのPythonプログラミング」(この記事では、元のプロジェクトのエラーの一部を修正および改善します。PS:この本を強くお勧めします。本当に良いです)、興味深い点を感じます。今回開発されたゲームはエイリアンインベージョンと呼ばれています。
pygameをインストールして、左右に移動できる宇宙船を作成します
pygameをインストールする
私のコンピューターはwindows10、python3.6、pygameのダウンロードアドレスです:ポータル対応するpythonバージョンのpygameをダウンロードして、次のコマンドを実行してください
$ pip install wheel
$ pip install pygame‑1.9.3‑cp36‑cp36m‑win_amd64.whl
Pygameウィンドウを作成し、ユーザー入力に応答します
新しいフォルダalien_invasionを作成し、そのフォルダに新しいalien_invasion.pyファイルを作成して、次のコードを入力します。
import sys
import pygame
def run_game():
#initialize game and create a dispaly object
pygame.init()
screen = pygame.display.set_mode((1200,800))
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# fill color
screen.fill(bg_color)
# visualiaze the window
pygame.display.flip()
run_game()
上記のコードを実行すると、灰色のインターフェイスを持つウィンドウを取得できます。
$ python alien_invasion.py
設定クラスを作成する
ゲームを作成する過程でいくつかの新しい関数を簡単に作成するために、すべての設定を1か所に保存するSettingsクラスを含む追加の設定モジュールを以下に記述します。これにより、将来プロジェクトが増加したときにゲームの外観を簡単に変更できます。まず、alien_invasion.pyの画面サイズと画面の色を変更します。まず、alien_invasionフォルダーの下に新しいpythonファイルsettings.pyを作成し、それに次のコードを追加します。
class Settings(object):
"""docstring for Settings"""
def init(self):
# initialize setting of game
# screen setting
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230,230,230)
次に、alien_invasion.pyにSettingsクラスをインポートし、関連する設定を使用して、次のように変更します。
import sys
import pygame
from settings import Settings
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# fill color
screen.fill(ai_settings.bg_color)
# visualiaze the window
pygame.display.flip()
run_game()
宇宙船の画像を追加
次に、宇宙船をゲームに追加する必要があります。画面にプレイヤーの船を描画するために、画像をロードし、Pygame()メソッドblit()を使用して描画します。ゲームではほとんどすべてのタイプの画像ファイルを使用できますが、Pygameはデフォルトでビットマップをロードするため、ビットマップ(.bmp)ファイルを使用するのが最も簡単です。他のタイプのイメージをロードすることもできますが、追加のライブラリをインストールする必要があります。無料の写真素材のウェブサイトポータルで画像を探すことをお勧めします。メインプロジェクトフォルダ(alien_invasion)にimagesという名前の新しいフォルダを作成し、次のbmp画像をその中に入れます。次に、shipクラスship.pyを作成します。
import pygame
class Ship():
def init(self,screen):
#initialize spaceship and its location
self.screen = screen
# load bmp image and get rectangle
self.image = pygame.image.load('image/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#put spaceship on the bottom of window
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
def blitme(self):
#buld the spaceship at the specific location
self.screen.blit(self.image,self.rect)
最後に、画面に宇宙船を描画します。つまり、alien_invasion.pyファイルのblitmeメソッドを呼び出します。
import sys
import pygame
from settings import Settings
from ship import Settings
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
ship = Ship(screen)
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# fill color
screen.fill(ai_settings.bg_color)
ship.blitme()
# visualiaze the window
pygame.display.flip()
run_game()
リファクタリング:モジュールgame_functions
大規模なプロジェクトでは、新しいコードを追加する前に、既存のコードをリファクタリングする必要があることがよくあります。リファクタリングの目的は、コードの構造を単純化し、拡張を容易にすることです。 game_functionsモジュールを実装します。このモジュールには、ゲームのエイリアンの侵入を実行できるようにする多数の関数が格納されます。モジュールgame_functionsを作成することにより、alien_invasion.pyが長すぎることを回避し、そのロジックを理解しやすくすることができます。
関数check_events()
まず、イベントを管理するためのコードをcheck_events()という関数に移動します。目的は、イベントループを分離することです。
import sys
import pygame
def check_events():
#respond to keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
次に、alien_invasion.pyコードを変更し、game_functionsモジュールをインポートして、イベントループを関数check_events()の呼び出しに置き換えます。
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
ship = Ship(screen)
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
gf.check_events()
# fill color
screen.fill(ai_settings.bg_color)
ship.blitme()
# visualiaze the window
pygame.display.flip()
run_game()
関数update_screen()
画面を更新するためのコードをupdate_screen()という名前の関数に移動し、この関数をモジュールgame_functionsに配置します。
def update_screen(ai_settings,screen,ship):
# fill color
screen.fill(ai_settings.bg_color)
ship.blitme()
# visualiaze the window
pygame.display.flip()
alien_invasionは次のように変更されます。
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
ship = Ship(screen)
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
gf.check_events()
gf.update_screen(ai_settings,screen,ship)
run_game()
上記の一連のプロセスから、次のことがわかりました。実際の開発プロセスでは、最初にコードをできるだけ単純に記述し、プロジェクトがますます複雑になるとリファクタリングしました。次に、ゲームの動的な側面を扱い始めます。
宇宙船を操縦する
ここで達成したいのは、プレイヤーが左右の矢印キーを使用して宇宙船の左右の動きを制御できるようにすることです。
ボタンに応答する
pygameでは、すべてのキー押下がKEYDOWNイベントとして登録されるため、check_events()では、event.typeを介してKEYDOWNイベントを検出した後、どのキー押下であるかをさらに判別する必要があります。コードは次のように表示されます。
def check_events(ship):
#respond to keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
#move right
ship.rect.centerx +=1
一定の動きを許可する
プレイヤーが右矢印を押して動かないときは、プレイヤーが離すまで宇宙船を動かし続けたいと思います。ここでは、KETUOイベントで判断します。したがって、moving_rightフラグを設定して、継続的な移動を実現します。原則は次のとおりです。
宇宙船が動いていないとき、moving_rightフラグはfalseになります。プレーヤーが右矢印を押すと、このフラグがTrueに設定されます。プレーヤーがそれを放すと、フラグがFalseにリセットされます。
このmoving属性は一種の宇宙船属性であり、shipクラスを使用して制御するため、このクラスに属性名moving_rightとupdate()メソッドを追加してmoving_rightフラグのステータスを確認します。輸送する
self.moving_right = False
def update(self):
if self.moving_right:
self.rect.centerx +=1
game_functions
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
#move right
ship.moving_right = True
elif event.type == pygame.KEYUP:
if event.key = pygame.K_RIGHT:
ship.moving_right = False
最後に、alien_invasionでupdate()メソッドを呼び出します
while True:
# supervise keyboard and mouse item
gf.check_events(ship)
ship.update()
左右に移動
前に右に移動してから左に移動しました。ロジックは似ており、コードは投稿されていません。
宇宙船の速度を調整する
現在、whileループが実行されるたびに、宇宙船は最大1ピクセル移動します。設定にship_speed_factorを追加して、宇宙船の速度を制御できます。この属性に基づいて、各サイクルで宇宙船が移動できる距離を決定します。設定:
class Settings(object):
"""docstring for Settings"""
def init(self):
# initialize setting of game
# screen setting
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230,230,230)
self.ship_speed_factor = 1.5
Ship:
class Ship():
def init(self,ai_settings,screen):
#initialize spaceship and its location
self.screen = screen
self.ai_settings = ai_settings
宇宙船の範囲を制限する
プレイヤーが矢印を長押ししすぎると、宇宙船は消えます。画面の端に達したときに宇宙船を停止するにはどうすればよいですか?ここでは、Shipクラスのupdateメソッドを変更して、論理的な判断を追加するだけです。
リファクター
ここでは、主にcheck_events()関数のリファクタリングについて説明します。コードの一部を、KEYDOWNイベントの処理用とKEYUPイベントの処理用の2つの部分に分割します。 game_functions:
def check_keydown_events(event,ship):
if event.key == pygame.K_RIGHT:
#move right
ship.moving_right = True
elif event.key == pygame.K_LEFT:
#move right
ship.moving_left = True
def check_keyup_events(event,ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
#move right
ship.moving_left = False
def check_events(ship):
#respond to keyboard and mouse item
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
撮影
次に、射撃機能を追加して、プレイヤーがスペースバーを押すと弾丸が発射されるようにします。弾丸は画面を上に移動し、画面に到達すると消えます。
弾丸設定を追加する
いくつかの弾丸プロパティをSettingsクラスに追加します。ここでは、幅3ピクセル、高さ15ピクセルの濃い灰色の弾丸を作成します。弾丸の速度は宇宙船の速度よりわずかに遅いです。
Bulletクラスを作成する
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""A class to manage bullets fired from the ship."""
def init(self, ai_settings, screen, ship):
"""Create a bullet object, at the ship's current position."""
super().init()
self.screen = screen
# Create bullet rect at (0, 0), then set correct position.
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
ai_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
# Store a decimal value for the bullet's position.
self.y = float(self.rect.y)
self.color = ai_settings.bullet_color
self.speed_factor = ai_settings.bullet_speed_factor
def update(self):
"""Move the bullet up the screen."""
# Update the decimal position of the bullet.
self.y -= self.speed_factor
# Update the rect position.
self.rect.y = self.y
def draw_bullet(self):
"""Draw the bullet to the screen."""
pygame.draw.rect(self.screen, self.color, self.rect)
弾丸をグループに保存する
Bulletクラスと上記の必要な設定を定義した後、プレーヤーがスペースバーを押すたびに弾丸を発射するコードを書くことができます。まず、alien_invasionにグループを作成して、すべての有効な箇条書きを保存します。
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
ship = Ship(ai_settings,screen)
bullets = Group()
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
gf.check_events(ai_settings, screen, ship,bullets)
ship.update()
bullets.update()
gf.update_screen(ai_settings, screen, ship,bullets)
火
ここでは、check_keydown_events()関数を変更して、プレーヤーがスペースバーを押したイベントを監視します。ここでは、update_screen()関数を変更して、画面が更新されるたびにすべての箇条書きを再描画できるようにする必要があります。効果を見てみましょう:
不足している箇条書きを削除する
alien_invasionで欠落している箇条書きを削除します。
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
def run_game():
#initialize game and create a dispaly object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
ship = Ship(ai_settings,screen)
bullets = Group()
pygame.display.set_caption("Alien Invasion")
# set backgroud color
bg_color = (230,230,230)
# game loop
while True:
# supervise keyboard and mouse item
gf.check_events(ai_settings, screen, ship,bullets)
ship.update()
bullets.update()
for bullet in bullets.copy():
if bullet.rect.bottom <=0:
bullets.remove(bullet)
gf.update_screen(ai_settings, screen,ship,bullets)
run_game()
弾丸の数を制限する
プレイヤーにターゲットを狙って撃つように促すために、画面上に同時に存在できる弾丸は3つだけであると規定しています。弾丸を作成する前に、消えていない弾丸の数が3つ未満であるかどうかを確認するだけです。
update_bullets()関数を作成します
alien_invasionのコードを簡単にするために、弾丸管理コードをチェックして、game_functionsモジュールに移動します。
def update_bullets(bullets):
bullets.update()
for bullet in bullets.copy():
if bullet.rect.bottom<=0:
bullets.remove(bullet)
fire_bullet()関数を作成します
ここでは、弾丸を発射するコードを別の関数に移動します。
def fire_bullet(ai_settings,screen,ship,bullets):
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings,screen,ship)
bullets.add(new_bullet)
エイリアンを追加し、衝突を検出します
新しいタスクを完了する前に、まずショートカットキーQを追加してゲームを終了します。
最初のエイリアンを作成する
これは宇宙船を作るのと同じ方法です
class Alien(Sprite):
"""A class to represent a single alien in the fleet."""
def init(self, ai_settings, screen):
"""Initialize the alien, and set its starting position."""
super().init()
self.screen = screen
self.ai_settings = ai_settings
# Load the alien image, and set its rect attribute.
self.image = pygame.image.load('images/alien.bmp')
self.rect = self.image.get_rect()
# Start each new alien near the top left of the screen.
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# Store the alien's exact position.
self.x = float(self.rect.x)
def blitme(self):
"""Draw the alien at its current location."""
self.screen.blit(self.image, self.rect)
エイリアンのグループを作成する
ここでは、最初に、線が保持できるエイリアンの数と描画する線の数を決定します。ここのコードには多くの変更があります。効果を見てください。
モバイルエイリアン
以前は静的なエイリアンを作成していましたが、今はエイリアンを動かす必要があります。ここでは、Settingsクラスでエイリアンの移動速度を設定してから、Alienクラスでupdateメソッドを移動します。
エイリアンを撃つ
エイリアンを撃ちたい場合は、まず2人のグループメンバーの間に衝突があるかどうかを検出する必要があります。ゲームでは、衝突はゲーム要素のオーバーラップです。ここでは、sprite.groupcollide()を使用して、2つのグループのメンバー間の衝突を検出します。弾丸がエイリアンに当たった場合、それをすぐに知る必要がありますが、同時に衝突したエイリアンはすぐに消えるので、弾丸の位置を更新した直後に衝突を検出する必要があります。
ゲーム終了
ここでは、いつゲームを終了するかも知る必要があります。いくつかの状況があります。
宇宙船は完全に破壊され、エイリアンは画面の下部に到達します
実際の効果:
スコアリング
最後に、ゲームに再生ボタンを追加して、必要に応じてゲームを開始し、ゲーム終了後にゲームを再開します。また、プレイヤーのレベルが上がるにつれてペースを速めるスコアリングシステムを実装します。
再生ボタンを追加
ここでは、最初にゲームを非アクティブ状態に初期化できます。ボタンをクリックすると、ゲームが開始されます。 Pygameにボタンを作成するための組み込みの方法がないためです。したがって、Buttonクラスを作成することにより、独自のラベルを持つ実線の長方形を作成できます。マウスクリック後の座標が描画したボタンと衝突するかどうかを検出することにより、クリックイベントが発生したかどうかを判断します。
レベルアップ
プレイヤーが敵を排除した後、ゲームをより難しく面白くするために、設定クラスでそれを変更して、静的初期値と動的初期値を増やすことができます。
スコアリング、レベル、残りの船
exe実行可能ファイルにパッケージ化
上記のゲームが開発されたら、それをexe実行可能ファイルに変換する必要があります。 pyinstallerを使用します。インストール手順のリファレンス:ポータル
プロジェクトコード
githubアドレス:ポータル
Recommended Posts