CoRでゲームをつくってみよう / 第05回 弾を発射する
投稿者: aoihikawa 投稿日:2022/08/14 03:23
CoRでゲームをつくってみよう
第05回 弾を発射する
こんにちは。
フリーデザイナープログラマー(自称)の
簸川 葵(ひかわ あおい)と申します。
第04回 では、敵キャラクターを登場させ
当たり判定をつけるところまでスクリプトを実装しました。
第05回は弾を発射するところまでやっていきますね。
05-01 弾を表示しよう
弾、とはキャラクターの位置から移動が開始される点と
移動する方向が異なりますが、
基本的な動きは敵キャラクターと同じです。
これまでのスクリプトを元に応用しながら、
まずは弾を表示させるところまでつくってみましょう。
今回もまた、お手軽にスクリプトの作成までできるよう、
サンプルの素材を準備いたしました。
第01回を参考に、クリップからリソースへの登録まで行い、
すぐにスクリプトで利用できるように、準備してください。
それでは、弾を発射するときに使用するZキーの入力処理から。
方向キーの場合を参考にしながら
ローカル変数の定義を行います。
#_/_/_/ ローカル変数の定義 _/_/_/ #キー入力用のフラグ 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 #---------- ここから ---------- key_flg_z_st = nil; key_flg_z_do = nil; key_flg_z_en = nil #---------- ここまで ----------
create内でローカル変数を初期化します。
#_/_/_/ 変数の初期化 _/_/_/ #キー入力用のフラグ 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 #---------- ここから ---------- key_flg_z_st = false; key_flg_z_do = false; key_flg_z_en = false #---------- ここまで ----------
メインループ内でキーの入力を受け取ります。
#_/_/_/ 入力の判定 _/_/_/ #キー入力判定 #~~~~~~~~~~ 中略 ~~~~~~~~~~ if keyboard.down?('RIGHT') key_flg_right_st = true else key_flg_right_st = false key_flg_right_do = false end #---------- ここから ---------- if keyboard.down?('Z') key_flg_z_st = true else key_flg_z_st = false key_flg_z_do = false end #---------- ここまで ----------
次は、弾の画像素材を読み込んでいきましょう。
スクリプトの最後で素材の定義をします。
#_/_/_/_/_/_/ 素材の定義 _/_/_/_/_/_/ #メイン背景 sprite 'spr_bg_00' do image 'img_bg_00' origin :left_top end #~~~~~~~~~~ 中略 ~~~~~~~~~~ #---------- ここから ---------- #プレイヤー弾 sprite 'spr_char_tama' do image 'img_char_tama' origin :left_top end #---------- ここまで ----------
今回のプレイヤー弾画像ではアニメーションがないため、
背景画像のときと同じ形になります。
preload内で素材をロードします。
preload do #----- ゲームロード時に実行される処理 ----- #_/_/_/ 素材のロード _/_/_/ #メイン背景 image 'img_bg_00', id: 76800 #プレイヤーキャラクター image 'img_char', id: 76793, frame_size: [64, 64] #---------- ここから ---------- #プレイヤー弾 image 'img_char_tama', id: 77342 #---------- ここまで ---------- #敵キャラクター image 'img_enemy', id: 77127, frame_size: [64, 64]
プレイヤー弾で使用するローカル変数を定義します。
後々、使用することになる
当たり判定用のローカル変数も一緒に定義しておきましょう。
scene 'start' do #_/_/_/ ローカル変数の定義 _/_/_/ #~~~~~~~~~~ 中略 ~~~~~~~~~~ #---------- ここから ---------- #プレイヤー弾オブジェクト obj_char_tama_spr = [] obj_char_tama_pos_x = []; obj_char_tama_pos_y = [] obj_char_tama_size_w = nil; obj_char_tama_size_h = nil obj_char_tama_scale_x = []; obj_char_tama_scale_y = [] obj_char_tama_scale_count = [] obj_char_tama_speed = nil obj_char_tama_pos_x_old = []; obj_char_tama_pos_y_old = [] obj_char_tama_hit_x = nil; obj_char_tama_hit_y = nil obj_char_tama_hit_w = nil; obj_char_tama_hit_h = nil obj_char_tama_flg = [] obj_char_tama_max = nil obj_char_tama_next = nil obj_char_tama_next_time = nil obj_char_tama_flg_z = nil #---------- ここまで ----------
今回、新しく定義した
obj_char_tama_scale_x、obj_char_tama_scale_y、obj_char_tama_scale_countは
弾を発射したときの、画像サイズを徐々に変更するときに使用します。
また、弾が待機中か移動中か判断するため
アニメーションの変わりに、obj_char_tama_flgを定義しています。
他、obj_char_tama_next、obj_char_tama_next_timeは
弾の連射速度。
obj_char_tama_flg_zは
Zキーから弾の発射の入力受け付けに使用します。
create内で定義したローカル変数を初期化します。
create do #----- シーンロード時に実行される処理 ----- #_/_/_/ 変数の初期化 _/_/_/ #~~~~~~~~~~ 中略 ~~~~~~~~~~ #---------- ここから ---------- #プレイヤー弾オブジェクト obj_char_tama_size_w = 16; obj_char_tama_size_h = 64 obj_char_tama_speed = 12 obj_char_tama_hit_x = 1; obj_char_tama_hit_y = 0 obj_char_tama_hit_w = 15; obj_char_tama_hit_h = 64 obj_char_tama_max = 5 obj_char_tama_next = (60 * 0.5) obj_char_tama_next_time = (-1) obj_char_tama_flg_z = false i = 0; ilen = obj_char_tama_max while i < ilen do obj_char_tama_pos_x[i] = 800; obj_char_tama_pos_y[i] = 600 obj_char_tama_pos_x_old[i] = obj_char_tama_pos_x[i] obj_char_tama_pos_y_old[i] = obj_char_tama_pos_y[i] obj_char_tama_scale_x[i] = 1; obj_char_tama_scale_y[i] = 0 obj_char_tama_scale_count[i] = 0 obj_char_tama_flg[i] = false i += 1 end #---------- ここまで ----------
画像サイズを指定するときに使用するローカル変数の
obj_char_tama_scale_x、obj_char_tama_scale_yの値は
透明度を設定したときと同じように
1が100%、0が0%となります。
発射時に縦幅のみ0%から徐々にサイズを大きくすることにより
発射の雰囲気を演出します。
他、どのローカル変数がどんな役割を持っているのか
考えながらつくることで、
必要となるローカル変数のパターンを覚えていきましょう。
メインループ内、キー入力処理で
Zキーの入力受け付けを、弾の発射入力受け付けに
渡す処理を追加します。
#_/_/_/ メイン処理 _/_/_/ #--- キー入力処理 --- #~~~~~~~~~~ 中略 ~~~~~~~~~~ #---------- ここから ---------- #Zキー if (key_flg_z_st && !key_flg_z_do) key_flg_z_do = true #--- 押された時に実行する処理 --- obj_char_tama_flg_z = true elsif key_flg_z_do key_flg_z_en = true #--- 押されつづけている時に実行する処理 --- obj_char_tama_flg_z = true elsif key_flg_z_en key_flg_z_en = false #--- 離された時に実行する処理 --- obj_char_tama_flg_z = false end #---------- ここまで ----------
Zキーが押されているとき、連射用のカウントダウンが-1であれば
プレイヤー弾を1つずつ
プレイヤーキャラクターの位置に移動する処理を追加します。
次のプレイヤー弾も続けて発射できるように
連射用のカウントダウン処理も追加しましょう。
#--- プレイヤーキャラクター --- #プレイヤーキャラクター移動方向のフラグによって処理を分岐 if (obj_char_flg_up && obj_char_flg_left) #プレイヤーキャラクターのアニメーションを変更 obj_char_anime = setChangeAnime(obj_char_spr, obj_char_anime, 'left') #~~~~~~~~~~ 中略 ~~~~~~~~~~ #---------- ここから ---------- #--- プレイヤー弾 --- #プレイヤー弾の発射カウントダウン if obj_char_tama_next_time > (-1) obj_char_tama_next_time -= 1 end #プレイヤー弾の発射 if obj_char_tama_flg_z && (obj_char_tama_next_time < 0) obj_char_tama_next_time = obj_char_tama_next i = 0; ilen = obj_char_tama_max while i < ilen do #待機状態のプレイヤー弾を探す if !obj_char_tama_flg[i] #プレイヤー弾を移動状態にする obj_char_tama_pos_x[i] = obj_char_pos_x + ((obj_char_size_w - obj_char_tama_size_w) / 2) obj_char_tama_pos_y[i] = obj_char_pos_y obj_char_tama_scale_x[i] = 1; obj_char_tama_scale_y[i] = 0 obj_char_tama_scale_count[i] = 0 obj_char_tama_flg[i] = true #ループを終了させる i = ilen end i += 1 end end #---------- ここまで ----------
敵キャラクターのときと同様に
1つずつ、待機状態のプレイヤー弾を探し
移動状態に変更しています。
弾の発射時に、プレイヤーキャラクターの中心と位置を合わせるため
obj_char_tama_pos_xの設定でちょっとした計算を行っているところと
プレイヤー弾発射時の弾の大きさを変更する
obj_char_tama_scale_x、obj_char_tama_scale_y、obj_char_tama_scale_countが
追加されているところがポイントです。
プレイヤー弾を移動させる処理を追加します。
こちらも、大まかな部分は
敵キャラクターの場合と同様の形になってきます。
#--- プレイヤー弾 --- #~~~~~~~~~~ 中略 ~~~~~~~~~~ #ループを終了させる i = ilen end i += 1 end end #---------- ここから ---------- #プレイヤー弾の移動 i = 0; ilen = obj_char_tama_max while i < ilen do if obj_char_tama_flg[i] #プレイヤー弾の座標値を移動させる obj_char_tama_pos_y[i] -= obj_char_tama_speed #プレイヤー弾のサイズ値を変更する if obj_char_tama_scale_y[i] < 1 obj_char_tama_scale_count[i] += 1 obj_char_tama_scale_y[i] = (obj_char_tama_speed * obj_char_tama_scale_count[i]) / obj_char_tama_size_h if obj_char_tama_scale_y[i] > 1 obj_char_tama_scale_y[i] = 1 end end #プレイヤー弾の移動範囲制限 if obj_char_tama_pos_y[i] < (obj_char_tama_size_h * (-2)) obj_char_tama_flg[i] = false obj_char_tama_pos_x[i] = 800; obj_char_tama_pos_y[i] = 600 obj_char_tama_scale_x[i] = 1; obj_char_tama_scale_y[i] = 0 obj_char_tama_scale_count[i] = 0 end #プレイヤー弾のオブジェクトを移動する if (obj_char_tama_pos_x_old[i] != obj_char_tama_pos_x[i]) || (obj_char_tama_pos_y_old[i] != obj_char_tama_pos_y[i]) obj_char_tama_pos_x_old[i] = obj_char_tama_pos_x[i] obj_char_tama_pos_y_old[i] = obj_char_tama_pos_y[i] obj_char_tama_spr[i].position obj_char_tama_pos_x[i], obj_char_tama_pos_y[i] obj_char_tama_spr[i].scale obj_char_tama_scale_x[i], obj_char_tama_scale_y[i] end end i += 1 end #---------- ここまで ----------
まずは、移動中となっているプレイヤー弾を
ループ処理で探しています。
プレイヤー弾の座標値を移動させる処理の後
プレイヤー弾の画像サイズを
発射後からobj_char_tama_scale_countを増やしていくことで
徐々に大きくしていく処理が追加されています。
プレイヤー弾の移動範囲制限では
画面上部に達したとき、待機状態に戻すようにしています。
最後に、プレイヤー弾の画像オブジェクトを
実際に移動したり、サイズ変更を行っています。
なお、画像オブジェクトの設定を変更している部分は、
positionで座標の変更、scaleでサイズの変更を行っています。
1回あたりの追加行数が長くなってきましたが
このように、ある程度の行の処理をグループとして把握することで
長文の処理も理解しやすく書くことが出来るようになってきます。
ここまでで、プレイヤー弾画像を
画面上で操作するスクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
05-02 弾に当たり判定を付けよう
発射したプレイヤー弾が敵キャラクターに当たり、
敵キャラクターが倒せるようにしてみましょう。
基本的には敵キャラクターの当たり判定を追加したときと同じですが、
敵キャラクターとプレイヤー弾は、それぞれ複数ありますので、
ループを2つ使用します。
敵キャラクターにプレイヤー弾が当たったときに必要となる
敵キャラクター用のローカル変数を追加します。
scene 'start' do #_/_/_/ ローカル変数の定義 _/_/_/ #~~~~~~~~~~ 中略 ~~~~~~~~~~ #敵キャラクターオブジェクト obj_enemy_spr = [] obj_enemy_pos_x = []; obj_enemy_pos_y = [] obj_enemy_size_w = nil; obj_enemy_size_h = nil obj_enemy_speed = nil; obj_enemy_speed_rnd = nil obj_enemy_pos_x_old = []; obj_enemy_pos_y_old = [] obj_enemy_speed_r_x = []; obj_enemy_speed_r_y = [] obj_enemy_w_max = nil; obj_enemy_h_max = nil #---------- ここから ---------- obj_enemy_hit_time = [] obj_enemy_invincible_time = nil #---------- ここまで ---------- obj_enemy_hit_x = nil; obj_enemy_hit_y = nil obj_enemy_hit_w = nil; obj_enemy_hit_h = nil obj_enemy_anime = [] obj_enemy_max = nil obj_enemy_next = nil obj_enemy_next_rnd = nil obj_enemy_next_time = nil
プレイヤーキャラクターのときに使用した
無敵時間と同じものですが、
敵キャラクターは複数のため、一部ローカル変数は配列になっています。
定義したローカル変数を初期化します。
create do #----- シーンロード時に実行される処理 ----- #_/_/_/ 変数の初期化 _/_/_/ #~~~~~~~~~~ 中略 ~~~~~~~~~~ #敵キャラクターオブジェクト obj_enemy_size_w = 64; obj_enemy_size_h = 64 obj_enemy_w_max = (800 - obj_enemy_size_w) obj_enemy_h_max = (600 + obj_enemy_size_h) obj_enemy_speed = 3; obj_enemy_speed_rnd = 2 #---------- ここから ---------- obj_enemy_invincible_time = (60 * 1) #---------- ここまで ---------- obj_enemy_hit_x = 20; obj_enemy_hit_y = 20 obj_enemy_hit_w = 44; obj_enemy_hit_h = 55 obj_enemy_max = 5 obj_enemy_next = (60 * 4) obj_enemy_next_rnd = 60 obj_enemy_next_time = (60 * 3) i = 0; ilen = obj_enemy_max while i < ilen do obj_enemy_pos_x[i] = 0; obj_enemy_pos_y[i] = ((-64) * 2) obj_enemy_pos_x_old[i] = obj_enemy_pos_x[i] obj_enemy_pos_y_old[i] = obj_enemy_pos_y[i] obj_enemy_speed_r_x[i] = 0; obj_enemy_speed_r_y[i] = 0 obj_enemy_anime[i] = 'wait' #---------- ここから ---------- obj_enemy_hit_time[i] = (-1) #---------- ここまで ---------- i += 1 end
メインループ内、敵キャラクターが移動状態のときの処理で
プレイヤーキャラクターとの当たり判定の後に
プレイヤー弾との当たり判定を追加します。
敵キャラクターでループ処理を使用している中で
プレイヤー弾のループ処理が必要となるため
配列の番号変数(今回は「i」と「j」)によく注意しましょう。
#プレイヤーキャラクターとの当たり判定 if (obj_char_hit_time < 0) && ((obj_char_pos_x + obj_char_hit_x) < (obj_enemy_pos_x_old[i] + obj_enemy_hit_w)) && ((obj_char_pos_x + obj_char_hit_w) > (obj_enemy_pos_x_old[i] + obj_enemy_hit_x)) && ((obj_char_pos_y + obj_char_hit_y) < (obj_enemy_pos_y_old[i] + obj_enemy_hit_h)) && ((obj_char_pos_y + obj_char_hit_h) > (obj_enemy_pos_y_old[i] + obj_enemy_hit_y)) #プレイヤーキャラクターに無敵時間を設定 obj_char_hit_time = obj_char_invincible_time end #---------- ここから ---------- #プレイヤー弾との当たり判定 j = 0; jlen = obj_char_tama_max while j < jlen do #移動状態のプレイヤー弾を探す if obj_char_tama_flg[j] && ((obj_char_tama_pos_x[j] + obj_char_tama_hit_x) < (obj_enemy_pos_x_old[i] + obj_enemy_hit_w)) && ((obj_char_tama_pos_x[j] + obj_char_tama_hit_w) > (obj_enemy_pos_x_old[i] + obj_enemy_hit_x)) && ((obj_char_tama_pos_y[j] + obj_char_tama_hit_y) < (obj_enemy_pos_y_old[i] + obj_enemy_hit_h)) && ((obj_char_tama_pos_y[j] + obj_char_tama_hit_h) > (obj_enemy_pos_y_old[i] + obj_enemy_hit_y)) #敵キャラクターに無敵時間を設定 obj_enemy_hit_time[i] = obj_enemy_invincible_time #アニメーションの開始 obj_enemy_anime[i] = setChangeAnime(obj_enemy_spr[i], obj_enemy_anime[i], 'damage') #プレイヤー弾を待機状態に戻す obj_char_tama_flg[j] = false obj_char_tama_pos_x[j] = 800; obj_char_tama_pos_y[j] = 600 obj_char_tama_scale_x[j] = 1; obj_char_tama_scale_y[j] = 0 obj_char_tama_scale_count[j] = 0 #プレイヤー弾のオブジェクトを移動する obj_char_tama_spr[j].position obj_char_tama_pos_x[j], obj_char_tama_pos_y[j] obj_char_tama_spr[j].scale obj_char_tama_scale_x[j], obj_char_tama_scale_y[j] end j += 1 end end #---------- ここまで ----------
まずは、プレイヤー弾のループ処理内で
移動中のプレイヤー弾かつ、当たり判定用の座標比較を行っています。
プレイヤー弾が敵キャラクターに当たっていた場合、
プレイヤーキャラクターのときと同じように
敵キャラクターに無敵時間を設定し
敵キャラクターをダメージ状態に変更しています。
敵キャラクターに当たったプレイヤー弾の方は
ここで効果を失うよう、待機状態に戻しています。
ダメージ状態となっている敵キャラクターの
無敵時間をカウントダウンします。
#プレイヤー弾のオブジェクトを移動する obj_char_tama_spr[j].position obj_char_tama_pos_x[j], obj_char_tama_pos_y[j] obj_char_tama_spr[j].scale obj_char_tama_scale_x[j], obj_char_tama_scale_y[j] end j += 1 end end #---------- ここから ---------- #ダメージ状態の敵キャラクターを探す if obj_enemy_anime[i] == 'damage' #敵キャラクターの無敵時間をカウント if obj_enemy_hit_time[i] > (-1) obj_enemy_hit_time[i] -= 1 #無敵時間の場合プレイヤーキャラクターを点滅表示する if obj_enemy_hit_time[i] == 0 setAlpha(obj_enemy_spr[i], 1) #無敵時間が終了したら待機状態に戻す obj_enemy_anime[i] = setChangeAnime(obj_enemy_spr[i], obj_enemy_anime[i], 'wait') obj_enemy_speed_r_x[i] = 0; obj_enemy_speed_r_y[i] = 0 obj_enemy_pos_x[i] = 0; obj_enemy_pos_y[i] = ((-64) * 2) #敵キャラクターのオブジェクトを移動する obj_enemy_spr[i].position obj_enemy_pos_x[i], obj_enemy_pos_y[i] elsif ((obj_enemy_hit_time[i] % 10) == 0) setAlpha(obj_enemy_spr[i], 1) elsif ((obj_enemy_hit_time[i] % 5) == 0) setAlpha(obj_enemy_spr[i], 0) elsif ((obj_enemy_hit_time[i] % 3) == 0) setAlpha(obj_enemy_spr[i], 0.5) end end end #---------- ここまで ---------- i += 1 end
無敵時間をカウントダウン処理の流れは
プレイヤーキャラクターのときと同じ形になっています。
無敵時間が終了した敵キャラクターは
待機状態に戻るように、アニメーションの変更や座標の移動などの処理が
追加されています。
ここまでで、敵キャラクターとプレイヤー弾の
当たり判定を行うスクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
05-03 音楽や効果音を鳴らそう
これまでのスクリプトで、シューティングゲームとしての動きは
一通り揃いましたが、音が出ないと少し寂しいですね。
そこで、ゲーム中の音楽の再生と、敵を倒したときに効果音を再生するよう、
スクリプトを追加してみましょう。
まずは、使用する音楽と効果音の素材の準備です。
今回は、事前に使用許可をいただきました、
助教授さまの音楽素材と、rerofumiさまの効果音素材を利用します。
第01回を参考に、クリップをしたら、COREシーンエディタを開いてください。
今回は、音楽と効果音をリソースに追加しますので、
COREシーンエディタのメニューを音楽管理、効果音管理に変更してから
クリップから追加を押します。
後の流れは、画像のときと同じです。
それでは、スクリプトに書いてみましょう。
まずはユーザ定義関数の設定から。
#_/_/_/_/_/_/ ユーザ関数の定義 _/_/_/_/_/_/ #オブジェクトのアニメーションを変更 def setChangeAnime(obj, old_anime, new_anime) if old_anime != new_anime obj.start_animation(new_anime) end return new_anime end #画像オブジェクトの透明度を設定 def setAlpha(obj, a) wrk_obj = obj.instance_variable_get('@js_sprite') wrk_obj.alpha = a end #---------- ここから ---------- #音量を変更する def volBGM(obj, vol) js_obj = obj.instance_variable_get("@js_audio") js_obj.volume = vol end #---------- ここまで ----------
volBGM関数では、
引数で音楽オブジェクトとVOL値(1~0)を渡すことにより
音量を変更しています。
なお、音量の値は1が100%で最大音量
0が0%でミュートとなります。
値は小数点以下も指定可能です。
音楽素材、効果音素材には素材の定義が必要ありません。
preload内で、音楽素材、効果音素材をロードします。
ここで画像素材のロードと同じように
各素材のidが必要となります。
preload do #----- ゲームロード時に実行される処理 ----- #_/_/_/ 素材のロード _/_/_/ #----- 画像 ----- #メイン背景 image 'img_bg_00', id: 76800 #プレイヤーキャラクター image 'img_char', id: 76793, frame_size: [64, 64] #プレイヤー弾 image 'img_char_tama', id: 77342 #敵キャラクター image 'img_enemy', id: 77127, frame_size: [64, 64] #---------- ここから ---------- #----- 音楽 ----- #メイン音楽 music 'bgm_main', id: 77253 #----- 効果音 ----- #弾ヒット sound 'se_hit00', id: 63622 #---------- ここまで ----------
読み込む素材によって、
音楽はmusic、効果音はsoundと命令が変わります。
音楽名、効果音名は自由に付けて構いません。
素材の初期化時に使用するため、分かりやすい名前を付けておきましょう。
音楽と効果音のオブジェクトを管理するための
ローカル変数を定義します。
scene 'start' do #_/_/_/ ローカル変数の定義 _/_/_/ #~~~~~~~~~~ 中略 ~~~~~~~~~~ obj_enemy_next = nil obj_enemy_next_rnd = nil obj_enemy_next_time = nil #---------- ここから ---------- #音楽オブジェクト obj_bgm_main = nil #効果音オブジェクト obj_se_hit00 = nil #---------- ここまで ----------
音楽と効果音のオブジェクトを生成します。
生成したオブジェクトはゲーム全体のバランスに合わせて、
volBGM関数で音量を設定しておきましょう。
#_/_/_/_/_/_/ ユーザ関数の定義 _/_/_/_/_/_/ #_/_/_/ 素材の初期化 _/_/_/ #メイン背景 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 #~~~~~~~~~~ 中略 ~~~~~~~~~~ #敵キャラクター i = 0; ilen = obj_enemy_max while i < ilen do obj_enemy_spr[i] = put_sprite 'spr_enemy' do position obj_enemy_pos_x[i], obj_enemy_pos_y[i] frame_index 0 end #アニメーションの開始 obj_enemy_spr[i].start_animation('wait') i += 1 end #---------- ここから ---------- #音楽 obj_bgm_main = add_music('bgm_main') volBGM(obj_bgm_main, 0.5) #効果音 obj_se_hit00 = add_sound('se_hit00') volBGM(obj_se_hit00, 0.7) #---------- ここまで ----------
音楽オブジェクトはadd_music、
効果音オブジェクトはadd_soundでオブジェクトを生成します。
引数の名前は、素材のロードで使用したときと
同じ名前となります。
ゲームの開始時に音楽が再生されるよう、
create内の最後で、音楽オブジェクトを再生します。
#音楽 obj_bgm_main = add_music('bgm_main') volBGM(obj_bgm_main, 0.5) #効果音 obj_se_hit00 = add_sound('se_hit00') volBGM(obj_se_hit00, 0.7) #---------- ここから ---------- #音楽の再生を開始する obj_bgm_main.play() #---------- ここまで ---------- end
obj_bgm_mainオブジェクトに対して、playを指示することにより
音楽の再生を開始しています。
なお、音楽を停止する場合はstopを指示します。
プレイヤー弾が敵キャラクターに当たった時に効果音が再生されるよう、
当たり判定の処理内で効果音を再生します。
#プレイヤー弾との当たり判定 j = 0; jlen = obj_char_tama_max while j < jlen do #移動状態のプレイヤー弾を探す if obj_char_tama_flg[j] && ((obj_char_tama_pos_x[j] + obj_char_tama_hit_x) < (obj_enemy_pos_x_old[i] + obj_enemy_hit_w)) && ((obj_char_tama_pos_x[j] + obj_char_tama_hit_w) > (obj_enemy_pos_x_old[i] + obj_enemy_hit_x)) && ((obj_char_tama_pos_y[j] + obj_char_tama_hit_y) < (obj_enemy_pos_y_old[i] + obj_enemy_hit_h)) && ((obj_char_tama_pos_y[j] + obj_char_tama_hit_h) > (obj_enemy_pos_y_old[i] + obj_enemy_hit_y)) #---------- ここから ---------- #効果音を再生する obj_se_hit00.play() #---------- ここまで ---------- #敵キャラクターに無敵時間を設定 obj_enemy_hit_time[i] = obj_enemy_invincible_time #アニメーションの開始 obj_enemy_anime[i] = setChangeAnime(obj_enemy_spr[i], obj_enemy_anime[i], 'damage')
音楽は自動で再生がループしますが、
効果音は最後まで再生されると自動で再生が停止します。
ここまでで、音楽素材と効果音素材が
ゲーム内で再生されるスクリプトが出来ました。
画面上部メニューにある、「保存をして実行」を押して
実際のゲーム画面を確認してみましょう。
05-04 おわりに
いかがでしたでしょうか。
これで、シューティングとして必要な要素は
一通り揃いました。
さて、次回はスコアや残機など文字を表示する方法、
タイトル画面やゲームクリアの作り方など
ゲームとして必要な機能を実装する方法について実践してみましょう。
今回までのスクリプト全体
CoRでゲームをつくってみよう / 第05回
第01回 CoRの開発準備をしよう
第02回 画面に背景やキャラクターを描画する
第03回 背景やキャラクターを動かす
第04回 敵キャラクターを登場させる
第05回 弾を発射する
第06回 ゲームとして必要な機能を追加する
第07回 より面白くするために
コメントする
コメントするには、ログインする必要があります。
弾1発ずつ、敵キャラクター1体ずつじゃなくて良いというのは
自分では気付けなかったです。
同じスプライトを複数の変数に代入すれば
別々の弾、別々の敵キャラクターとして扱えるんですね。