Pygameでマリオのキーイベントを追加する
マリオをPythonで作成するハンズオン動画を見つけたので、実装してみる。
参考:【#4 キーイベント処理】マリオを左右に動かそう!マリオを一緒に作ってみませんか!pythonで!【ハンズオン実践解説】
1. マリオの動きの実装
(1) キーボード入力に応じた移動の追加
-
update()
メソッド内でpygame.key.get_pressed()
を使用し、右 (→
)、左 (←
)、ジャンプ (スペースキー
) に対応。
def update(self):
# キーボードの状態を取得
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.__right()
if keys[pygame.K_LEFT]:
self.__left()
if keys[pygame.K_SPACE]:
self.__jump()
(2) 移動処理の追加
-
__right()
→ 右移動 (rect.x += 5
) -
__left()
→ 左移動 (rect.x -= 5
) -
__jump()
→ ジャンプ (self.__vy = -10
に設定し、地面から離れる`)
def __right(self):
self.rect.x += 5
self.__isleft = False
self.__walkidx += 1
def __left(self):
self.rect.x -= 5
self.__isleft = True
self.__walkidx += 1
def __jump(self):
if self.__on_ground:
self.__vy = -10
self.__on_ground = False
(3) Y軸の移動処理
-
__vy
を用いた重力処理を追加。-
if not self.__on_ground:
で空中にいる場合self.rect.y
を__vy
の値だけ変化させる。 -
__vy
の値を+1
ずつ増やし、落下する動作を実現。 - 地面 (
y = 180
) に着いたら__on_ground = True
にしてジャンプ可能にする。
-
# Y軸方向に移動
if not self.__on_ground:
self.rect.y += self.__vy
self.__vy += 1
if self.rect.y >= 180:
self.rect.y = 180
self.__on_ground = True
2. 歩行アニメーションの追加
(1) 画像のフレーム切り替え
-
前回:
mario001.png
という1枚の画像のみを表示。 -
今回:
mario001.png
mario002.png
の2枚の画像を配列self.__imgs
に格納し、歩行時に交互に切り替え。-
WALK_ANIME_IDX = [0, 0, 0, 1, 1, 1]
を用いて、6フレームのうち0
(mario001) と1
(mario002) を交互に表示。
-
# marioの画像を読み込む
self.__imgs = [
pygame.image.load('mario001.png'),
pygame.image.load('mario002.png')
]
self.image = self.__imgs[0]
self.rect = pygame.Rect(150, 180, 20, 20)
mario001.png | mario002.png |
---|---|
(2) 左右の向きの判定
-
self.__isleft
で左右の向きを記録し、画像の反転を実現。pygame.transform.flip(self.__imgs[self.WALK_ANIME_IDX[self.__walkidx % 6]], self.__isleft, False)
# 左右どちら向きかのフラグを定義
self.__isleft = False
~~~
self.image = pygame.transform.flip(self.__imgs[self.WALK_ANIME_IDX[self.__walkidx % 6]], self.__isleft, False)
完全なコード
import pygame
# 画面サイズを定義
W, H = 320, 270
# タイル数
TILE_X = 16
TILE_Y = 14
class Mario(pygame.sprite.Sprite):
''' マリオのクラス
'''
WALK_ANIME_IDX = [0, 0, 0, 1, 1, 1]
def __init__(self):
pygame.sprite.Sprite.__init__(self)
# 左右どちら向きかのフラグを定義
self.__isleft = False
# 歩くインデックス
self.__walkidx = 0
# Y軸方向移動郷里
self.__vy = 0
# マリオが地面にいるか
self.__on_ground = True
# marioの画像を読み込む
self.__imgs = [
pygame.image.load('mario001.png'),
pygame.image.load('mario002.png')
]
self.image = self.__imgs[0]
self.rect = pygame.Rect(150, 180, 20, 20)
def __right(self):
self.rect.x += 5
self.__isleft = False
self.__walkidx += 1
def __left(self):
self.rect.x -= 5
self.__isleft = True
self.__walkidx += 1
def __jump(self):
if self.__on_ground:
self.__vy = -10
self.__on_ground = False
def update(self):
# キーボードの状態を取得
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.__right()
if keys[pygame.K_LEFT]:
self.__left()
if keys[pygame.K_SPACE]:
self.__jump()
# Y軸方向に移動
if not self.__on_ground:
self.rect.y += self.__vy
self.__vy += 1
if self.rect.y >= 180:
self.rect.y = 180
self.__on_ground = True
self.image = pygame.transform.flip(self.__imgs[self.WALK_ANIME_IDX[self.__walkidx % 6]], self.__isleft, False)
def main():
'''メイン関数'''
# pygame初期化
pygame.init()
# 画面を構築
win = pygame.display.set_mode((W, H))
pygame.display.set_caption("Pygame Window") # ウィンドウタイトルを設定
# クロックを生成
clock = pygame.time.Clock()
# スプライトグループを定義
group = pygame.sprite.RenderUpdates()
# マリオクラスを定義
mario = Mario()
# マリオをグループに追加
group.add(mario)
# 背景色の初期値(黒)
bg_color = (0, 0, 0)
# イベントループ
running = True
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False # ループを抜ける
# 背景を塗りつぶす
win.fill((135, 206, 235))
# グループを更新
group.update()
# グループを描画
group.draw(win)
# 画面の更新
pygame.display.flip()
clock.tick(30) # FPS制限 (60FPS)
# pygameを終了する
pygame.quit()
# Pythonのファイルが直接実行された場合のみmain()を実行
if __name__ == '__main__':
main()
まとめ
変更点 | 前回 | 今回 |
---|---|---|
キーボード入力 | なし |
pygame.key.get_pressed() を使用 |
横移動 | なし |
__right() __left() で移動可能 |
ジャンプ | なし |
__jump() を追加 |
重力処理 | なし |
self.__vy を用いた落下処理 |
画像 |
mario001.png のみ |
mario001.png mario002.png を交互に表示 |
向き判定 | なし |
pygame.transform.flip() で左右反転 |
この修正により、マリオが移動・ジャンプし、歩行アニメーションがつくようになりました。