どうも、こんにちは、だんなです。
第1回の「回転寿司くん君ゲーム」の解説、「キャラをキーボードで動かす」です。
解説① キャラをキーボードで動かす。
上記のゲームプログラムから、キャラをキーボードで動かす部分のみを抽出して解説をしていきます。実際にプログラムを動作させるとこんな感じになります。
キャラクターをキーボードやジョイパッドで動かすプログラムは、今回のような地味な動きであっても複雑な作りになります。思ったように動かなくてイヤになってしまうことが多い部分ですが、ゲームの核となる部分ですので頑張って理解していきましょう!
解説② 解説用のプログラムをダウンロードして開く。
背景をスクロールさせるだけのプログラムをダウンロードして実行してみましょう。アップロード先は、GitHub(ギットハブ)というサイトになります。
https://github.com/mat-tun-neo/kaitenzushi-kun/tree/keypress
・プログラムファイル kaitenzushi-kun.py
・動かすキャラの画像 images/aji000.png
のファイルで動いています。
プログラムファイル kaitenzushi-kun.py
from pygame_functions import * from random import random SCREEN_X = 1200 # 画面 横サイズ (ピクセル) SCREEN_Y = 600 # 画面 縦サイズ (ピクセル) PLAYER_ALLIMAGE = 27 # プレイヤー アニメーション全コマ数 PLAYER_MOVELEN = 16 # プレイヤー 動く幅 (ピクセル) PLAYER_WIDTH = 192 # プレイヤー 横サイズ (ピクセル) PLAYER_HEIGHT = 160 # プレイヤー 縦サイズ (ピクセル) PLAYER_SCALE = 1.5 # プレイヤー 画像の拡大率 PLAYER_Y = 380 - PLAYER_HEIGHT * PLAYER_SCALE - 20 # プレイヤー 初期Y位置 (ピクセル) DISH_MOVELEN = 5 # お皿 動く幅 (ピクセル) screen = screenSize(SCREEN_X, SCREEN_Y) setBackgroundImage("images/bg_kaitenzushi.jpg") # プレイヤー初期描画 player = makeSprite("images/aji000.png") player_x = SCREEN_X / 2 transformSprite(player, 0, PLAYER_SCALE) moveSprite(player, player_x, PLAYER_Y) showSprite(player) left = False right = False # メインループ while True: # プレイヤーの操作判定 (入力なし) if not left and not right: if keyPressed("left"): playerImgNo = 0 left = True if keyPressed("right"): playerImgNo = PLAYER_ALLIMAGE right = True player_x += DISH_MOVELEN moveSprite(player, player_x, PLAYER_Y) if player_x > SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE: player_x = SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE # プレイヤーの操作判定 (入力:左キー) if left: playerImgNo += 1 if playerImgNo > 26: playerImgNo = 0 left = False player_x -= PLAYER_MOVELEN * PLAYER_SCALE if player_x < 0: player_x = 0 moveSprite(player, player_x, PLAYER_Y) # プレイヤーの操作判定 (入力:右キー) if right: playerImgNo -= 1 if playerImgNo < 0: playerImgNo = 0 right = False player_x += PLAYER_MOVELEN * PLAYER_SCALE if player_x > SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE: player_x = SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE moveSprite(player, player_x, PLAYER_Y) tick(60)
動かすキャラの画像 images/aji000.png
解説③ プログラムの解説
キーボードの入力判定は、ずっと繰り返される部分のif文で何十回、何百回、何千回も判定を行っています。キーボードからの入力を待っている状態ですが、プログラムが止まっているわけではないところがポイントです。
一度だけ実行するプログラム部分
⇒ スプライトと呼ばれる部品を作る(画面に配置する)
ずっと繰り返し実行されるメインループ部分
⇒ キーボードの入力判定を延々と行う。
⇒ キーボードの「←」「→」がチョンっと押されたとき、スプライトを移動させる。
という作りになっています。
それでは、各プログラム部分ごとに解説をしていきます。
初期処理(1~22行)
from pygame_functions import * from random import random SCREEN_X = 1200 # 画面 横サイズ (ピクセル) SCREEN_Y = 600 # 画面 縦サイズ (ピクセル) PLAYER_ALLIMAGE = 27 # プレイヤー アニメーション全コマ数 PLAYER_MOVELEN = 16 # プレイヤー 動く幅 (ピクセル) PLAYER_WIDTH = 192 # プレイヤー 横サイズ (ピクセル) PLAYER_HEIGHT = 160 # プレイヤー 縦サイズ (ピクセル) PLAYER_SCALE = 1.5 # プレイヤー 画像の拡大率 PLAYER_Y = 380 - PLAYER_HEIGHT * PLAYER_SCALE - 20 # プレイヤー 初期Y位置 (ピクセル) DISH_MOVELEN = 5 # お皿 動く幅 (ピクセル) screen = screenSize(SCREEN_X, SCREEN_Y) setBackgroundImage("images/bg_kaitenzushi.jpg") # プレイヤー初期描画 player = makeSprite("images/aji000.png") player_x = SCREEN_X / 2 transformSprite(player, 0, PLAYER_SCALE) moveSprite(player, player_x, PLAYER_Y) showSprite(player)
・必要なライブラリのインポート(ライブラリを使いますという宣言)
・プログラム中で使用する数値(画面サイズとか座標とか)を定数に格納。
・ゲーム画面を開く。
・キャラのスプライトを配置。
など、前回までと同様の処理については、解説を割愛します。
キーボード入力「←」「→」のフラグ(23~24行)
left = False right = False
この辺りから、少々小難しくなってきます。
今回のキーボード入力の判定は、高速でずっと繰り返される処理の中でキーが押されている間しか判定されないので、キーをチョンっと押したらキャラクターがニョニョ~っと動く処理に向いていません。
そこで、一度「←」キーがチョンっと押されたらleftフラグをTrue(ONの意味)に、「→」キーがチョンっと押されたらrightフラグをTrue(ONの意味)にするように作っていきます。
逆に、キーを押している間だけキャラクターがニョニョ~っと動くように作る場合は、このようなフラグは必要ありません。
キーボードがチョンっと押されるのを待つ処理(26~39行)
# メインループ while True: # プレイヤーの操作判定 (入力なし) if not left and not right: if keyPressed("left"): playerImgNo = 0 left = True if keyPressed("right"): playerImgNo = PLAYER_ALLIMAGE right = True player_x += DISH_MOVELEN moveSprite(player, player_x, PLAYER_Y) if player_x > SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE: player_x = SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE
今回の処理の山場です、頑張ってソースを解読してみましょう!
メインループで高速でずっと繰り返される処理の中で、キーボードが押されていない時に以下の処理を行っています。
・「←」キーがチョンっと押されたら、leftフラグをONにする。
・「→」キーがチョンっと押されたら、rightフラグをONにする。
・背景スクロールに合わせてキャラを右に5ピクセルずつ移動する。
・キャラのX座標がゲーム画面の右端に到達したら、X座標を固定させる。
「←」フラグがONの場合にスプライトを左へ移動させる(41~50行)
# プレイヤーの操作判定 (入力:左キー) if left: playerImgNo += 1 if playerImgNo > 26: playerImgNo = 0 left = False player_x -= PLAYER_MOVELEN * PLAYER_SCALE if player_x < 0: player_x = 0 moveSprite(player, player_x, PLAYER_Y)
if left:
が何を意味しているのかを理解するのがポイントです。もちろん「←」キーが押されたら、なのですが、厳密には「←」キーがチョンっ押された際にleftフラグがONにされた後、高速にずっと繰り返される処理の中でOFFになっていなければ、と考える必要があります。
実際には、playerImgNoという変数をインクリメント(=+1していくこと)しながら変数が26を超えたらleftフラグをOFFにしています。
今回はこのif文の中でスプライトの移動だけを行っていますが、アニメーション処理までこのif文の中に書くと、
・「←」キーをチョンっと押すと
・このif文に入って(計27回入ります)キャラが移動する
・このif文に入る間だけアニメーションさせる
みたいなことを実現できるわけです。
「→」フラグがONの場合にスプライトを右へ移動させる(52~61行)
# プレイヤーの操作判定 (入力:右キー) if right: playerImgNo -= 1 if playerImgNo < 0: playerImgNo = 0 right = False player_x += PLAYER_MOVELEN * PLAYER_SCALE if player_x > SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE: player_x = SCREEN_X - PLAYER_WIDTH * PLAYER_SCALE moveSprite(player, player_x, PLAYER_Y) tick(60)
if right:
が何を意味しているのかを理解するのがポイントです。やっていることは「←」フラグと同じですので、解説は割愛します。
第1回解説:背景をスクロールさせる
第1回解説:キャラをアニメーションさせる
第1回解説:キャラをキーボードで動かす
のプログラムを足し算すると、この動画のような動きを実現できて一気にゲームらしくなりますので、チャレンジしてみて下さい!(音は僕の好みでおまけで付けています。)
以上、だんなのゲームプログラミング入門講座(第1回解説:キャラをキーボードで動かす)でした。