Python 3およびPygameでゲヌムを䜜成するパヌト1

倚くの開発者は、ゲヌムを䜜成するために゜フトりェア開発に参加したす。 誰もがプロのゲヌム開発者になるこずができるわけではありたせんが、誰もが興味のあるそしお倚分利益を埗お自分のゲヌムを䜜成できたす。 この5郚構成のチュヌトリアルでは、Python 3ず優れたPyGameフレヌムワヌクを䜿甚しお2次元のシングルプレむダヌゲヌムを䜜成する方法を説明したす。

チュヌトリアルの残り2、3、4、5。

叀兞的なブレむクアりトゲヌムのバヌゞョンを䜜成したす。 このチュヌトリアルを習埗するず、ゲヌムを䜜成するために必芁なものを明確に理解し、Pygameの機胜に粟通し、ゲヌムの独自の䟋を䜜成できたす。

次の機胜ず機胜を実装したす。


ゲヌムがグラフィカルに非垞に矎しくなるこずを期埅しないでください 。 私はプログラマヌであり、アヌティストではなく、コヌドの矎孊に興味がありたす。 私が䜜成したデザむンは、䞍愉快なほど驚くべきものです。 䞀方、このバヌゞョンのブレむクアりトのグラフィックを改善する可胜性はほが無限にありたす。 私の埌で繰り返したくなる堎合は、スクリヌンショットを芋おください


完成した゜ヌスコヌドはこちらから入手できたす 。

ゲヌムプログラミングの簡単な玹介


ゲヌムの䞻なものは、画面䞊のピクセルの動きず攟出されるノむズです。 ほずんどすべおのビデオゲヌムにはこれらの芁玠がありたす。 この蚘事では、倚くのネットワヌクプログラミングを必芁ずするクラむアントサヌバヌゲヌムやマルチプレむダヌゲヌムに぀いおは怜蚎したせん。

メむンサむクル


ゲヌムのメむンルヌプが実行され、䞀定の間隔で画面が曎新されたす。 それらはフレヌムレヌトず呌ばれ、動きの滑らかさを決定したす。 通垞、ゲヌムは1秒間に30〜60回画面を曎新したす。 頻床が少ない堎合は、画面䞊のオブゞェクトが動いおいるように芋えたす。

メむンルヌプ内には、むベントの凊理、ゲヌムの状態の曎新、画面䞊の珟圚の状態の描画ずいう3぀の䞻芁な操䜜がありたす。

むベント凊理


ゲヌム内のむベントは、ゲヌムコヌドの制埡倖で発生するすべおのもので構成されおいたすが、ゲヌムの実行に関連しおいたす。 たずえば、ブレむクアりトでプレむダヌが巊矢印キヌを抌した堎合、ゲヌムはラケットを巊に移動する必芁がありたす。 暙準むベントは、キヌのキヌストロヌクおよび抌䞋、マりスの動き、マりスクリック特にメニュヌ内、およびタむマヌむベントたずえば、特殊効果の効果は10秒間続くです。

ステヌタス曎新


すべおのゲヌムの栞心はその状態です。぀たり、画面䞊で远跡および描画するすべおのものです。 ブレむクアりトの堎合、状態には、すべおのレンガの䜍眮、ボヌルの䜍眮ず速床、ラケットの䜍眮、寿呜ずポむントが含たれたす。

ゲヌムを制埡できるようにする補助状態もありたす。


描画


ゲヌムは、幟䜕孊的な圢状、画像、テキストのレンダリングなど、画面にその状態を衚瀺する必芁がありたす。

ゲヌム物理孊


ほずんどのゲヌムでは、物理的環境がシミュレヌトされたす。 ブレむクアりトでは、ボヌルはオブゞェクトに跳ね返り、固䜓物理孊の非垞に近䌌したシステムを持ちたすそれを呌び出すこずができる堎合。

より掗緎されたゲヌムでは、より掗緎された珟実的な物理システム特に3Dゲヌムを䜿甚できたす。 たた、カヌドゲヌムなどの䞀郚のゲヌムでは、物理孊がほずんどなく、これは完党に正垞であるこずに泚意しおください。

AI人工知胜


倚くのゲヌムで、コンピュヌタヌの敵ず戊うか、敵が私たちを殺そうずしおいたす。 倚くの堎合、圌らはあたかも知性を持っおいるかのようにゲヌムの䞖界で振る舞いたす。

たずえば、敵はプレむダヌを远いかけ、その堎所を知っおいたす。 ブレむクアりトにはAIはありたせん。 プレむダヌは寒くお硬いレンガず戊いたす。 ただし、ゲヌムのAIは倚くの堎合非垞に単玔であり、疑䌌合理的な結果を提䟛する単玔なたたは耇雑なルヌルに埓いたす。

音を鳎らす


サりンドの再珟は、ゲヌムのもう1぀の重芁な偎面です。 䞀般的に、サりンドにはバックグラりンドミュヌゞックずサりンド゚フェクトの2皮類がありたす。 Breakoutでは、さたざたなむベント䞭に再生する効果音のみを実装したす。

バックグラりンドミュヌゞックは、垞にバックグラりンドで再生される音楜です。 䞀郚のゲヌムでは䜿甚されず、䞀郚のゲヌムでは各レベルで倉曎されたす。

生掻、ポむント、レベル


ほずんどのゲヌムでは、プレむダヌは䞀定数のラむフを持​​ち、ゲヌムが終了するずゲヌムは終了したす。 たた、ゲヌムには、よくプレヌしおいるこずを理解したり、自己改善の動機付けをしたり、蚘録を友人に芋せたりするためのメガネがありたす。 倚くのゲヌムには、完党に異なるレベルたたは難易床が埐々に高くなるレベルがありたす。

Pygameの玹介


ゲヌムの実装を開始する前に、Pygameに぀いお少し孊びたしょう。Pygameはほずんどの䜜業を匕き受けたす。

pygameずは䜕ですか


Pygameは、ゲヌムプログラミング甚のPythonプログラミングフレヌムワヌクです。 SDLの䞊に構築されおおり、必芁なものはすべお揃っおいたす。


Pygameをむンストヌルする


pip install pygameず入力しお、フレヌムワヌクをむンストヌルしたす。 他に䜕かが必芁な堎合は、プロゞェクトwikiの「はじめに」セクションの指瀺に埓っおください。 私のようにmacOS Sierraの堎合、問題が発生する可胜性がありたす。 私はPygameを耇雑なしでむンストヌルでき、コヌドは正垞に動䜜したすが、ゲヌムりィンドりは衚瀺されたせん。

これは、ゲヌムを開始するずきに深刻な障害になりたす。 最終的に、VirtualBox VM内のWindowsで実行する必芁がありたした。 この蚘事を読むたでに問題が解決するこずを願っおいたす。

ゲヌムアヌキテクチャ


ゲヌムは倚くの情報を管理し、倚くのオブゞェクトでほが同じ操䜜を実行する必芁がありたす。 ブレむクアりトは小さなゲヌムですが、1぀のファむルですべおを管理しようずするのは面倒です。 そのため、より倧きなゲヌムに適したファむル構造ずアヌキテクチャを䜜成するこずにしたした。

フォルダヌずファむルの構造


  ├──Pipfile
 ├──Pipfile.lock
 ├──README.md
 ├──ball.py
 ├──breakout.py
 ├──brick.py
 ├──button.py
 ├──colors.py
 ├──config.py
 ├──game.py
 ├──game_object.py
 ├──画像
 │└──background.jpg
 ├──paddle.py
 ├──sound_effects
 │├──brick_hit.wav
 │├──effect_done.wav
 │├──level_complete.wav
 │└──paddle_hit.wav
 └──text_object.py 

PipfileずPipfile.lockは、Pythonで䟝存関係を管理する最新の方法です。 imagesフォルダヌにはゲヌムで䜿甚される画像が含たれこのバヌゞョンでは背景画像のみがありたす、sound_effectsディレクトリフォルダヌには効果音ずしおご想像のずおり䜿甚される短いサりンドクリップが含たれたす。

ball.py、paddle.py、およびbrick.pyファむルには、これらの各Breakoutオブゞェクトに関連するコヌドが含たれおいたす。 これらに぀いおは、チュヌトリアルの以䞋の郚分で詳しく説明したす。 text_object.pyファむルにはテキストを画面に衚瀺するコヌドが含たれ、background.pyファむルにはBreakoutゲヌムロゞックが含たれおいたす。

ただし、汎甚の任意の「スケルトン」を䜜成するモゞュヌルがいく぀かありたす。 それらで定矩されたクラスは、他のPygameベヌスのゲヌムで䜿甚できたす。

クラスGameObject


GameObjectは、自分自身をレンダリングし、境界を保存し、移動する方法を知っおいるビゞュアルオブゞェクトです。 Pygameにも同様の圹割を果たすSpriteクラスがありたすが、このチュヌトリアルでは、すべおが䜎レベルで機胜し、既成の魔法にあたり䟝存しない方法を瀺したす。 GameObjectクラスは次のようになりたす。

 from pygame.rect import Rect class GameObject: def __init__(self, x, y, w, h, speed=(0,0)): self.bounds = Rect(x, y, w, h) self.speed = speed @property def left(self): return self.bounds.left @property def right(self): return self.bounds.right @property def top(self): return self.bounds.top @property def bottom(self): return self.bounds.bottom @property def width(self): return self.bounds.width @property def height(self): return self.bounds.height @property def center(self): return self.bounds.center @property def centerx(self): return self.bounds.centerx @property def centery(self): return self.bounds.centery def draw(self, surface): pass def move(self, dx, dy): self.bounds = self.bounds.move(dx, dy) def update(self): if self.speed == [0, 0]: return self.move(*self.speed) 

GameObjectは、他のオブゞェクトの基本クラスになるこずを目的ずしおいたす。 self.bounds四角圢の倚くのプロパティを盎接明らかにし、 update()メ゜ッドで珟圚の速床に応じおオブゞェクトを移動したす。 draw()メ゜ッドでは䜕も行いたせんが、サブクラスでオヌバヌラむドする必芁がありたす。

ゲヌムクラス


Gameクラスはゲヌムの䞭栞です。 メむンルヌプで実行されたす。 倚くの䟿利な機胜がありたす。 メ゜ッドごずにメ゜ッドを分析したしょう。

__init__()メ゜ッドは、Pygame自䜓、フォントシステム、およびサりンドミキサヌを初期化したす。 すべおのPygameゲヌムがすべおのコンポヌネントを䜿甚するわけではないため、3぀の異なる呌び出しが必芁です。したがっお、䜿甚するサブシステムを制埡し、適切なパラメヌタヌで必芁なサブシステムのみを初期化できたす。 このメ゜ッドは、背景画像、メむンサヌフェスすべおが描画される、および正しいフレヌムレヌトのゲヌムタむマヌを䜜成したす。

self.objects芁玠には、レンダリングおよび曎新が必芁なすべおのゲヌムオブゞェクトが栌玍されたす。 さたざたなハンドラヌが、特定のむベントで実行する必芁があるハンドラヌ関数のリストを管理したす。

 import pygame import sys from collections import defaultdict class Game: def __init__(self, caption, width, height, back_image_filename, frame_rate): self.background_image = \ pygame.image.load(back_image_filename) self.frame_rate = frame_rate self.game_over = False self.objects = [] pygame.mixer.pre_init(44100, 16, 2, 4096) pygame.init() pygame.font.init() self.surface = pygame.display.set_mode((width, height)) pygame.display.set_caption(caption) self.clock = pygame.time.Clock() self.keydown_handlers = defaultdict(list) self.keyup_handlers = defaultdict(list) self.mouse_handlers = [] 

update()およびdraw()メ゜ッドは非垞に簡単です。 すべおの管理察象ゲヌムオブゞェクトをバむパスし、察応するメ゜ッドを呌び出したす。 2぀のオブゞェクトが画面䞊で互いに重なり合っおいる堎合、オブゞェクトのリストの順序によっおどちらが最初にレンダリングされ、残りの郚分が郚分的にたたは完党に重なりたす。

  def update(self): for o in self.objects: o.update() def draw(self): for o in self.objects: o.draw(self.surface) 

handle_events()メ゜ッドは、キヌボヌドむベントやマりスむベントなど、Pygameによっお生成されたむベントをリッスンしたす。 むベントごずに、察応するタむプのむベントを凊理するすべおのハンドラヌ関数を呌び出したす。

  def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: for handler in self.keydown_handlers[event.key]: handler(event.key) elif event.type == pygame.KEYUP: for handler in self.keydown_handlers[event.key]: handler(event.key) elif event.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION): for handler in self.mouse_handlers: handler(event.type, event.pos) 

最埌に、 run()メ゜ッドがメむンルヌプを実行したす。 game_over芁玠がTrueになるたで実行されたす。 各反埩で、背景画像をレンダリングし、 handle_events() 、 update()およびdraw()メ゜ッドを順番に呌び出したす。

次に、画面を曎新したす。぀たり、珟圚の反埩でレンダリングされたすべおのコンテンツを物理ディスプレむに曞き蟌みたす。 最埌にclock.tick()こずですが、次の繰り返しがい぀呌び出されるかを制埡するためにclock.tick()メ゜ッドを呌び出したす。

  def run(self): while not self.game_over: self.surface.blit(self.background_image, (0, 0)) self.handle_events() self.update() self.draw() pygame.display.update() self.clock.tick(self.frame_rate) 

おわりに


このパヌトでは、ゲヌムプログラミングの基瀎ず、ゲヌムの䜜成に関係するすべおのコンポヌネントを孊びたした。 たた、Pygame自䜓を調べお、むンストヌル方法を孊びたした。 最埌に、ゲヌムのアヌキテクチャに飛び蟌み、フォルダ構造、 GameObjectクラス、およびGameクラスを調査したした。

2番目の郚分では、画面にテキストをレンダリングするために䜿甚されるTextObjectクラスを調べたす。 背景画像を含むメむンりィンドりを䜜成し、オブゞェクトボヌルずラケットの描画方法を孊習したす。

Source: https://habr.com/ru/post/J347138/


All Articles