(チュートリアルの残りの部分: first 、 second 、 fourth 、 fifth 。)
これは、Python 3とPygameを使用してゲームを作成する5部構成のチュートリアルの3番目です。 2番目の部分では、テキストを画面にレンダリングするために使用される
TextObject
クラスを調べ、メインウィンドウを作成し、オブジェクト(レンガ、ボール、ラケット)の描画方法を学びました。
このパートでは、Breakoutの中心部を深く掘り下げて、イベントの処理方法、メインのBreakoutクラスの知識、ゲーム内のさまざまなオブジェクトの移動方法を学びます。
イベント処理
ブレークアウトには、キーストロークイベント、マウスイベント、タイマーイベントの3種類のイベントがあります。 Gameクラスのメインループは、キーストロークとマウスイベントを処理し、それらをサブスクライバーに渡します(ハンドラー関数を呼び出すことにより)。
Gameクラスは非常に一般的であり、Breakoutの実装についての知識はありませんが、サブスクリプションおよびイベント処理メソッドは非常に具体的です。
ブレイクアウトクラス
Breakoutクラスは、Breakoutの制御方法に関するほとんどの知識を実装しています。 このチュートリアルシリーズでは、Breakoutクラスに数回参加します。 さまざまなイベントハンドラが登録する行は次のとおりです。
すべてのキーイベント(左右の「矢印」の両方)が1つのラケットハンドラメソッドに送信されることに注意してください。
# handle_mouse_event() self.mouse_handlers.append(b.handle_mouse_event) # handle() self.keydown_handlers[pygame.K_LEFT].append(paddle.handle) self.keydown_handlers[pygame.K_RIGHT].append(paddle.handle) self.keyup_handlers[pygame.K_LEFT].append(paddle.handle) self.keyup_handlers[pygame.K_RIGHT].append(paddle.handle)
キーストローク処理
Gameクラスは、各キーイベントの登録済みハンドラーを呼び出し、キーを渡します。 これはPaddleクラスではないことに注意してください。 ブレイクアウトでは、そのようなイベントに関心がある唯一のオブジェクトはラケットです。 キーが押されるか離されると、その
handle()
メソッドが呼び出されます。 Paddleオブジェクトは、これがキープレスイベントかリリースイベントかを知る必要はありません。これは、一対のブール変数
moving_left
と
moving_right
現在の状態を制御するため
moving_right
。
moving_left
がTrueの場合、「左」キーが押されたことを意味し、次のイベントはキーのリリースであり、変数がリセットされます。 同じことが正しいキーにも当てはまります。 ロジックは単純で、イベントに応じてこれらの変数の状態を切り替えることで構成されます。
def handle(self, key): if key == pygame.K_LEFT: self.moving_left = not self.moving_left else: self.moving_right = not self.moving_right
マウスイベント処理
ブレイクアウトには、すぐに会うゲームメニューがあります。 メニューボタンは、移動やボタンの押下(マウスダウンイベントおよびマウスアップイベント)など、さまざまなマウスイベントを制御します。 これらのイベントに応じて、ボタンは内部状態変数を更新します。 マウス処理コードは次のとおりです。
def handle_mouse_event(self, type, pos): if type == pygame.MOUSEMOTION: self.handle_mouse_move(pos) elif type == pygame.MOUSEBUTTONDOWN: self.handle_mouse_down(pos) elif type == pygame.MOUSEBUTTONUP: self.handle_mouse_up(pos) def handle_mouse_move(self, pos): if self.bounds.collidepoint(pos): if self.state != 'pressed': self.state = 'hover' else: self.state = 'normal' def handle_mouse_down(self, pos): if self.bounds.collidepoint(pos): self.state = 'pressed' def handle_mouse_up(self, pos): if self.state == 'pressed': self.on_click(self) self.state = 'hover'
マウスイベントを受信するために登録された
handle_mouse_event()
メソッドは、イベントのタイプをチェックし、このタイプのイベントを処理する適切なメソッドにリダイレクトすることに注意してください。
タイマーイベントの処理
タイマーイベントはメインループでは処理されません。 ただし、メインループは各フレームで呼び出されるため、特定のイベントの時間になったかどうかを簡単に確認できます。 一時的な特殊効果については、後で説明します。
別の状況として、ゲームを一時停止する必要があります。 たとえば、プレーヤーが読む必要があるというメッセージを表示し、何も邪魔しないようにします。 Breakoutクラスの
show_message()
メソッドはこのアプローチを取り、
time.sleep()
を呼び出します。 関連するコードは次のとおりです。
import config as c class Breakout(Game): def show_message(self, text, color=colors.WHITE, font_name='Arial', font_size=20, centralized=False): message = TextObject(c.screen_width // 2, c.screen_height // 2, lambda: text, color, font_name, font_size) self.draw() message.draw(self.surface, centralized) pygame.display.update() time.sleep(c.message_duration)
ゲームプレイ
ゲームプレイ(ゲームプレイ)は、ブレイクアウトルールが作用する場所です。 ゲームプレイでは、イベントに応じてさまざまなオブジェクトを移動し、それらの相互作用に基づいてゲームの状態を変更します。
移動ラケット
前に、Paddleクラスが
moving_right
と
moving_right
更新することで矢印キーに応答することを
moving_left
し
moving_right
。 移動自体は
update()
メソッドで発生します。 ラケットが画面の左端または右端に近い場合、特定の計算がここで実行されます。 ラケットが画面の境界を越えて移動するのは望ましくありません(特定のオフセットを考慮に入れて)。
そのため、移動によってオブジェクトが境界を越えて移動する場合、コードは移動を調整して境界で停止するようにします。 ラケットは水平方向にのみ移動するため、変位の垂直成分は常にゼロです。
import pygame import config as c from game_object import GameObject class Paddle(GameObject): def __init__(self, x, y, w, h, color, offset): GameObject.__init__(self, x, y, w, h) self.color = color self.offset = offset self.moving_left = False self.moving_right = False ... def update(self): if self.moving_left: dx = -(min(self.offset, self.left)) elif self.moving_right: dx = min(self.offset, c.screen_width - self.right) else: return self.move(dx, 0)
動くボール
ボールは単純に
GameObject
基本クラスの機能を使用します。これは、
GameObject
速度(水平および垂直コンポーネント)に基づいてオブジェクトを移動します。 すぐにわかるように、ボールの速度はブレイクアウトクラスの多くの要因によって決まります。 移動は現在の位置に速度を追加するだけであるため、ボールの移動方向は、水平軸と垂直軸に沿った速度によって完全に決定されます。
ボールの初速を設定する
ブレイクアウトボールは、プレイヤーが命を失うたびに、ゲームの最初からどこからでも出てきません。 それは単にエーテルから実体化し、正確に落ちるか、わずかな角度で落下し始めます。 ボールが
create_ball()
メソッドで作成されると、-2から2の範囲のランダムな水平成分とconfig.pyモジュールで指定された垂直成分(デフォルト値は3)で速度を取得します。
def create_ball(self): speed = (random.randint(-2, 2), c.ball_speed) self.ball = Ball(c.screen_width // 2, c.screen_height // 2, c.ball_radius, c.ball_color, speed) self.objects.append(self.ball)
まとめると
このパートでは、キーストローク、マウスの動き、マウスのクリックなどのイベントの処理について説明しました。 また、ブレイクアウトゲームプレイのいくつかの要素、つまりラケットの移動、ボールの移動、ボールの速度の制御についても検討しました。
第4部では、衝突認識の重要なトピックを検討し、ボールがさまざまなゲームオブジェクト(ラケット、レンガ、壁、天井、床)に当たったときに何が起こるかを見ていきます。 次に、ゲームメニューに注意を払います。 メニューとして使用する独自のボタンを作成し、必要に応じて表示と非表示を切り替えることができます。