CoRでゲームをつくってみよう / 第03回 背景やキャラクターを動かす
投稿者:
aoihikawa
投稿日:2022/08/11 01:45
CoRでゲームをつくってみよう
第03回 背景やキャラクターを動かす
こんにちは。
フリーデザイナープログラマー(自称)の
簸川 葵(ひかわ あおい)と申します。
第02回 では、画面に背景やキャラクターを
描画するところまでスクリプトを実装しました。
第03回は画面に描画した背景やキャラクターを動かすところまで
やっていきますね。
03-01 キー入力を受けとろう
新CoRでは、ゲームを動かすためのメインループを自作しなくても
メインループの役割を持つ機能が最初から実装されています。
キャラクターを動かすには、まずこのメインループに
キーが押された時、押され続けているとき、離された時といった状態を
判定する仕組みをスクリプトで実装していきます。
キーの3種類の状態を管理するために
1つのキー毎に3種類のフラグローカル変数を準備します。
scene 'start' do #_/_/_/ ローカル変数の定義 _/_/_/ #---------- ここから ---------- #キー入力用のフラグ key_flg_up_st = nil key_flg_up_do = nil key_flg_up_en = nil key_flg_down_st = nil key_flg_down_do = nil key_flg_down_en = nil key_flg_left_st = nil key_flg_left_do = nil key_flg_left_en = nil key_flg_right_st = nil key_flg_right_do = nil key_flg_right_en = nil #---------- ここまで ----------
stがキー入力の開始、
doがキー入力の継続中、
enがキー入力の終了を判定するために利用します。
定義したローカル変数を
シーンの実行時に初期化します。
create do
#----- シーンロード時に実行される処理 -----
#_/_/_/ 変数の初期化 _/_/_/
#---------- ここから ----------
#キー入力用のフラグ
key_flg_up_st = false
key_flg_up_do = false
key_flg_up_en = false
key_flg_down_st = false
key_flg_down_do = false
key_flg_down_en = false
key_flg_left_st = false
key_flg_left_do = false
key_flg_left_en = false
key_flg_right_st = false
key_flg_right_do = false
key_flg_right_en = false
#---------- ここまで ----------
キー入力を受け取ったとき、
フラグ変数を変更する処理を実装します。
キー入力の受け取りは、シーン毎のメインループとなる
update内に、書いていく形になります。
update do
#----- シーンのメインループ処理 -----
#_/_/_/ 入力の判定 _/_/_/
#---------- ここから ----------
#キー入力判定
if keyboard.down?('UP')
key_flg_up_st = true
else
key_flg_up_st = false
key_flg_up_do = false
end
if keyboard.down?('DOWN')
key_flg_down_st = true
else
key_flg_down_st = false
key_flg_down_do = false
end
if keyboard.down?('LEFT')
key_flg_left_st = true
else
key_flg_left_st = false
key_flg_left_do = false
end
if keyboard.down?('RIGHT')
key_flg_right_st = true
else
key_flg_right_st = false
key_flg_right_do = false
end
#---------- ここまで ----------
keyboard.down?はキー入力を受け取る関数です
引数にUP、DOWN、LEFT、RIGHTを指定すると方向キーの入力、
Z、X、Cなどを指定すると英字キーの入力を受け取れます
関数から受け取った戻り値を直接、if文で分岐させて
それぞれのフラグ変数の値を変更しています。
キーの3種類の状態を区別するために
スクリプトをもうひと工夫します。
#_/_/_/ メイン処理 _/_/_/
#---------- ここから ----------
#キー入力処理
if (key_flg_up_st && !key_flg_up_do)
key_flg_up_do = true
#--- 押された時に実行する処理 ---
debug_log '上キーが押された'
elsif key_flg_up_do
key_flg_up_en = true
#--- 押されつづけている時に実行する処理 ---
debug_log '上キーが押されています'
elsif key_flg_up_en
key_flg_up_en = false
#--- 離された時に実行する処理 ---
debug_log '上キーが離された'
end
if (key_flg_down_st && !key_flg_down_do)
key_flg_down_do = true
#--- 押された時に実行する処理 ---
debug_log '下キーが押された'
elsif key_flg_down_do
key_flg_down_en = true
#--- 押されつづけている時に実行する処理 ---
debug_log '下キーが押されています'
elsif key_flg_down_en
key_flg_down_en = false
#--- 離された時に実行する処理 ---
debug_log '下キーが離された'
end
if (key_flg_left_st && !key_flg_left_do)
key_flg_left_do = true
#--- 押された時に実行する処理 ---
debug_log '左キーが押された'
elsif key_flg_left_do
key_flg_left_en = true
#--- 押されつづけている時に実行する処理 ---
debug_log '左キーが押されています'
elsif key_flg_left_en
key_flg_left_en = false
#--- 離された時に実行する処理 ---
debug_log '左キーが離された'
end
if (key_flg_right_st && !key_flg_right_do)
key_flg_right_do = true
#--- 押された時に実行する処理 ---
debug_log '右キーが押された'
elsif key_flg_right_do
key_flg_right_en = true
#--- 押されつづけている時に実行する処理 ---
debug_log '右キーが押されています'
elsif key_flg_right_en
key_flg_right_en = false
#--- 離された時に実行する処理 ---
debug_log '右キーが離された'
end
#---------- ここまで ----------
debug_logは、デバッグウインドウ内に文字を表示する関数です。
画面には表示されない情報を表示するなど、
スクリプトのテストを行うときに重要な役割を持つ関数なので
覚えておくと便利です。
ここまでで、キー入力を受け取り、
デバッグウインドウにその状態を表示するスクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
03-02 キャラクターを動かそう
いよいよキャラクターを動かします。
キャラクターが動く、というのは画像オブジェクトの表示座標が動くことです。
キャラクターを動かすときに使用する
ローカル変数を定義します。
#プレイヤーキャラクターオブジェクト obj_char_spr = nil obj_char_pos_x = nil obj_char_pos_y = nil obj_char_size_w = nil obj_char_size_h = nil #---------- ここから ---------- obj_char_pos_x_old = nil obj_char_pos_y_old = nil obj_char_speed = nil obj_char_speed_r_x = nil obj_char_speed_r_y = nil obj_char_w_max = nil obj_char_h_max = nil obj_char_anime = nil obj_char_flg_up = nil obj_char_flg_down = nil obj_char_flg_left = nil obj_char_flg_right = nil #---------- ここまで ----------
obj_char_pos_x_old、obj_char_pos_y_oldは
過去のキャラクターの座標を保管しておき
位置が変更されたときのみ
画像オブジェクトを移動する判定として使用します。
obj_char_speed、obj_char_speed_r_x、obj_char_speed_r_yは
プレイヤーキャラクターの移動速度を保管しておく定数です。
obj_char_speedは前後左右の移動時に、
obj_char_speed_r_x、obj_char_speed_r_yは斜めの移動時に使用します。
obj_char_w_max、obj_char_h_maxは
プレイヤーキャラクターの移動限界を保管しておく定数です。
obj_char_animeは
過去のアニメーションの種類を保管しておき
アニメーションが変更されたときのみ
表示を変更する判定として使用します。
obj_char_flg_up、obj_char_flg_down、
obj_char_flg_left、obj_char_flg_rightは
プレイヤーキャラクター移動方向を示す、フラグ変数です。
定義したローカル変数を
シーンの実行時に初期化します。
#プレイヤーキャラクターオブジェクト
obj_char_size_w = 64
obj_char_size_h = 64
obj_char_pos_x = (800 - obj_char_size_w) / 2
obj_char_pos_y = 500
#---------- ここから ----------
obj_char_pos_x_old = obj_char_pos_x
obj_char_pos_y_old = obj_char_pos_y
obj_char_speed = 5
wrk_r = 45 * Math::PI / 180
obj_char_speed_r_x = Math.cos(wrk_r) * obj_char_speed
obj_char_speed_r_y = Math.sin(wrk_r) * obj_char_speed
obj_char_w_max = (800 - obj_char_size_w)
obj_char_h_max = (600 - obj_char_size_h)
obj_char_anime = 'neutral'
obj_char_flg_up = false
obj_char_flg_down = false
obj_char_flg_left = false
obj_char_flg_right = false
#---------- ここまで ----------
obj_char_speed_r_x、obj_char_speed_r_yの
値を決めるときに使用している
Math::PI、Math.cos、Math.sinは
三角関数関連の関数を呼び出す命令です。
wrk_rに45度の時のラジアンを求め
三角関数とwrk_rを使用して
斜め移動時のX座標とY座標の移動距離を求めています。
キー入力処理に移動方向のフラグを変更する処理を追加します。
なお、テスト用に使用したdebug_logは削除しています。
scene 'start' do
#_/_/_/ メイン処理 _/_/_/
#キー入力処理
if (key_flg_up_st && !key_flg_up_do)
key_flg_up_do = true
#--- 押された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_up = true
#---------- ここまで ----------
elsif key_flg_up_do
key_flg_up_en = true
#--- 押されつづけている時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_up = true
#---------- ここまで ----------
elsif key_flg_up_en
key_flg_up_en = false
#--- 離された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_up = false
#---------- ここまで ----------
end
if (key_flg_down_st && !key_flg_down_do)
key_flg_down_do = true
#--- 押された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_down = true
#---------- ここまで ----------
elsif key_flg_down_do
key_flg_down_en = true
#--- 押されつづけている時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_down = true
#---------- ここまで ----------
elsif key_flg_down_en
key_flg_down_en = false
#--- 離された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_down = false
#---------- ここまで ----------
end
if (key_flg_left_st && !key_flg_left_do)
key_flg_left_do = true
#--- 押された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_left = true
#---------- ここまで ----------
elsif key_flg_left_do
key_flg_left_en = true
#--- 押されつづけている時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_left = true
#---------- ここまで ----------
elsif key_flg_left_en
key_flg_left_en = false
#--- 離された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_left = false
#---------- ここまで ----------
end
if (key_flg_right_st && !key_flg_right_do)
key_flg_right_do = true
#--- 押された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_right = true
#---------- ここまで ----------
elsif key_flg_right_do
key_flg_right_en = true
#--- 押されつづけている時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_right = true
#---------- ここまで ----------
elsif key_flg_right_en
key_flg_right_en = false
#--- 離された時に実行する処理 ---
#---------- ここから ----------
obj_char_flg_right = false
#---------- ここまで ----------
end
キー入力処理のすぐ下に、
プレイヤーキャラクター移動方向のフラグによって
分岐される処理を追加します。
ここで実際に、アニメーションの切り替えや
プレイヤーキャラクター座標値の変更を行っています。
if (key_flg_right_st && !key_flg_right_do)
key_flg_right_do = true
#--- 押された時に実行する処理 ---
obj_char_flg_right = true
elsif key_flg_right_do
key_flg_right_en = true
#--- 押されつづけている時に実行する処理 ---
obj_char_flg_right = true
elsif key_flg_right_en
key_flg_right_en = false
#--- 離された時に実行する処理 ---
obj_char_flg_right = false
end
#---------- ここから ----------
#プレイヤーキャラクター移動方向のフラグによって処理を分岐
if (obj_char_flg_up && obj_char_flg_left)
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'left'
obj_char_anime = 'left'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x -= obj_char_speed_r_x
obj_char_pos_y -= obj_char_speed_r_y
elsif (obj_char_flg_down && obj_char_flg_left)
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'left'
obj_char_anime = 'left'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x -= obj_char_speed_r_x
obj_char_pos_y += obj_char_speed_r_y
elsif (obj_char_flg_up && obj_char_flg_right)
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'right'
obj_char_anime = 'right'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x += obj_char_speed_r_x
obj_char_pos_y -= obj_char_speed_r_y
elsif (obj_char_flg_down && obj_char_flg_right)
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'right'
obj_char_anime = 'right'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x += obj_char_speed_r_x
obj_char_pos_y += obj_char_speed_r_y
elsif obj_char_flg_up
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'neutral'
obj_char_anime = 'neutral'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_y -= obj_char_speed
elsif obj_char_flg_down
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'neutral'
obj_char_anime = 'neutral'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_y += obj_char_speed
elsif obj_char_flg_left
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'left'
obj_char_anime = 'left'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x -= obj_char_speed
elsif obj_char_flg_right
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'right'
obj_char_anime = 'right'
obj_char_spr.start_animation(obj_char_anime)
end
#プレイヤーキャラクターの座標を変更
obj_char_pos_x += obj_char_speed
else
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'neutral'
obj_char_anime = 'neutral'
obj_char_spr.start_animation(obj_char_anime)
end
end
#---------- ここまで ----------
プレイヤーキャラクターが画面の端を越えて出て行かないように
座標値が限界値を超えたら、引き戻す処理を追加します。
else
#プレイヤーキャラクターのアニメーションを変更
if obj_char_anime != 'neutral'
obj_char_anime = 'neutral'
obj_char_spr.start_animation(obj_char_anime)
end
end
#---------- ここから ----------
#プレイヤーキャラクターの移動範囲制限
if obj_char_pos_x < 0
obj_char_pos_x = 0
end
if obj_char_pos_x > obj_char_w_max
obj_char_pos_x = obj_char_w_max
end
if obj_char_pos_y < 0
obj_char_pos_y = 0
end
if obj_char_pos_y > obj_char_h_max
obj_char_pos_y = obj_char_h_max
end
#---------- ここまで ----------
プレイヤーキャラクターの座標値が変更されていたら
プレイヤーキャラクタのオブジェクトを
画面上で移動する処理を追加します。
#プレイヤーキャラクターの移動範囲制限
if obj_char_pos_x < 0
obj_char_pos_x = 0
end
if obj_char_pos_x > obj_char_w_max
obj_char_pos_x = obj_char_w_max
end
if obj_char_pos_y < 0
obj_char_pos_y = 0
end
if obj_char_pos_y > obj_char_h_max
obj_char_pos_y = obj_char_h_max
end
#---------- ここから ----------
#プレイヤーキャラクターのオブジェクトを移動する
if (obj_char_pos_x_old != obj_char_pos_x) || (obj_char_pos_y_old != obj_char_pos_y)
obj_char_pos_x_old = obj_char_pos_x
obj_char_pos_y_old = obj_char_pos_y
obj_char_spr.position obj_char_pos_x, obj_char_pos_y
end
#---------- ここまで ----------
end
ここで再び、
オブジェクトに対して操作を指定する命令が登場しました。
ここでは、obj_char_sprのオブジェクトに対して
positionを呼び出し、表示座標を変更する命令を行っています。
ここまでで、キャラクター画像を
画面上で移動するスクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
03-03 背景を動かそう
キャラクターの動かし方を踏まえて、
背景を動かしてみましょう。
背景を動かすためには、縦に長ーい画像を準備する方法もありますが、
今回は、1枚の絵を2枚使用して、これをループさせて表示します。
スクロール中に表示される
2枚目の背景画像を生成します。
今回は1枚目の背景と同じものを使用するため
素材の定義や素材のロードなどの処理をとばして
2枚目の背景画像オブジェクトで使用する
ローカル変数の定義から書き始めます。
#メイン背景オブジェクト obj_bg_00_spr = nil #---------- ここから ---------- obj_bg_01_spr = nil #---------- ここまで ---------- obj_bg_pos_x = nil obj_bg_pos_y = nil #---------- ここから ---------- obj_bg_speed = nil #---------- ここまで ----------
obj_bg_01_sprは2枚目の画像オブジェクトを格納するための変数。
obj_bg_speedはスクロール速度を保管しておく定数です。
定義したローカル変数を
シーンの実行時に初期化します。
#_/_/_/ 変数の初期化 _/_/_/
#キー入力用のフラグ
key_flg_up_st = false
key_flg_up_do = false
key_flg_up_en = false
key_flg_down_st = false
key_flg_down_do = false
key_flg_down_en = false
key_flg_left_st = false
key_flg_left_do = false
key_flg_left_en = false
key_flg_right_st = false
key_flg_right_do = false
key_flg_right_en = false
#メイン背景オブジェクト
obj_bg_pos_x = 0
obj_bg_pos_y = 0
#---------- ここから ----------
obj_bg_speed = 1.5
#---------- ここまで ----------
2枚目の背景画像のオブジェクトを生成します。
sprite名は1枚目と同じものを使用することで
1枚目と同じ画像オブジェクトを追加で生成することができます。
#_/_/_/ 素材の初期化 _/_/_/
#メイン背景
obj_bg_00_spr = put_sprite 'spr_bg_00' do
position obj_bg_pos_x, obj_bg_pos_y
src_rect 0, 0, 800, 600
end
#---------- ここから ----------
obj_bg_01_spr = put_sprite 'spr_bg_00' do
position obj_bg_pos_x, (obj_bg_pos_y - 600)
src_rect 0, 0, 800, 600
end
#---------- ここまで ----------
positionのy座標を-600することで
2枚目の表示位置を上にずらしています。
背景画像をスクロールさせる処理を
メインループに追加します。
#プレイヤーキャラクターのオブジェクトを移動する
if (obj_char_pos_x_old != obj_char_pos_x) || (obj_char_pos_y_old != obj_char_pos_y)
obj_char_pos_x_old = obj_char_pos_x
obj_char_pos_y_old = obj_char_pos_y
obj_char_spr.position obj_char_pos_x, obj_char_pos_y
end
#---------- ここから ----------
#背景のスクロール
obj_bg_pos_y += obj_bg_speed
#背景のスクロールをループさせる
if obj_bg_pos_y > 600
obj_bg_pos_y -= 600
end
#背景のオブジェクトを移動する
obj_bg_00_spr.position obj_bg_pos_x, obj_bg_pos_y
obj_bg_01_spr.position obj_bg_pos_x, (obj_bg_pos_y - 600)
#---------- ここまで ----------
スクロールした座標値が600を超えたとき
座標値を-600することで、表示がループするようになっています。
実際のオブジェクトの移動は
プレイヤーキャラクターの場合と同様に
obj_bg_00_sprオブジェクト、obj_bg_01_sprオブジェクトそれぞれに対して
positionに座標値を指定することにより
画面上の2枚の背景画像を移動しています。
ここまでで、背景画像をスクロール表示させる
スクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
03-04 おわりに
いかがでしたでしょうか。
キャラクターが操作出来るようになり
より、ゲーム画面らしくなってきました。
さて、次回は敵キャラクターを登場させて
配列や当たり判定について実践してみましょう。
今回までのスクリプト全体
CoRでゲームをつくってみよう / 第03回
第01回 CoRの開発準備をしよう
第02回 画面に背景やキャラクターを描画する
第03回 背景やキャラクターを動かす
第04回 敵キャラクターを登場させる
第05回 弾を発射する
第06回 ゲームとして必要な機能を追加する
第07回 より面白くするために
コメントする
コメントするには、ログインする必要があります。
コメント一覧
なとおとき(投稿日:2022/08/11 02:31,
履歴)
押し続けの処理の分け方はいつも若干困ってました!