RmakeでACTゲームをつくろう / 第04回 敵の動き背景演出を入れてみよう
投稿者: aoihikawa 投稿日:2011/10/24 23:47
RmakeでACTゲームをつくろう
第04回 敵の動きや背景の演出を入れてみよう
こんにちは。
フリーデザイナープログラマー(自称)の
簸川 葵(ひかわ あおい)と申します。
第03回 では「敵・アイテムを追加してみよう」ということで、
一通りのACTゲーム完成まで、お話しました。
今回はより面白くするために、敵の動きや背景の演出を
追加してみましょう。
04-01 敵に移動AIを追加する
敵を移動させるAIを追加してみましょう。
今回製作するAIのパターンは、
通常は横に移動しますが、壁や崖に接すると
進行方向を反対側に変えます。
基本はキャラクターとマップの当たり判定と
同様のスクリプトを書きますが、
動きがキャラクターよりも単純なため、
スクリプトの軽量化を考えて、
判定するポイントを2点に絞ります。
敵キャラクターの当たり判定のうち、
縦方向の中央付近を壁判定に、
縦方向の下部を床判定にします。
それでは、実際にスクリプトを書いていきましょう。
まずはチャプター1にて、定数の準備から。
#ここから↑は省略 #敵キャラクターの設定 max_enemy = 3 enemy_anime_change = 2 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ enemy_speed = 5 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
「enemy_speed」は敵キャラクターの移動速度を設定しています。
敵のアニメーションに移動するスクリプトを追加します。
#ここから↑は省略 #----- 敵キャラクターのアニメーション ----- i = 0 while i < max_enemy #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ #敵キャラクターAI enemy_hit_flg = false #方向転換フラグ #敵キャラクターの当たり判定範囲 enemyHitpos_Y1 = floor((getVariable(pos_enemy)[i][y] + enemy_hit[y] + (enemy_hit[h] * 0.5) + 16) / 32) enemyHitpos_Y2 = floor((getVariable(pos_enemy)[i][y] + enemy_hit[y] + enemy_hit[h] + 32) / 32) if enemy_muki[i] == 0 #左向き #当たり判定の座標を算出 enemyHitpos_X1 = floor((getVariable(pos_enemy)[i][x] + enemy_hit[x]) / 32) enemyHit_X = getVariable("hit_map")[enemyHitpos_Y1][enemyHitpos_X1] enemyHit_Y = getVariable("hit_map")[enemyHitpos_Y2][enemyHitpos_X1] getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] - enemy_speed #敵キャラクターの当たり判定左端の座標を取得 hit_x = getVariable(pos_enemy)[i][x] + enemy_hit[x] if hit_x < 0 #画面端の判定 getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] - hit_x enemy_hit_flg = true elsif (enemyHit_X != 19) || (enemyHit_Y == 19) #壁または崖の判定 getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] + enemy_speed enemy_hit_flg = true end #向きを反転する if enemy_hit_flg enemy_muki[i] = 1 end else #右向き #当たり判定の座標を算出 enemyHitpos_X2 = floor((getVariable(pos_enemy)[i][x] + enemy_hit[x] + enemy_hit[w]) / 32) enemyHit_X = getVariable("hit_map")[enemyHitpos_Y1][enemyHitpos_X2] enemyHit_Y = getVariable("hit_map")[enemyHitpos_Y2][enemyHitpos_X2] getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] + enemy_speed #敵キャラクターの当たり判定右端の座標を取得 hit_x = getVariable(pos_enemy)[i][x] + enemy_hit[x] + enemy_hit[w] if hit_x > map_max_w #画面端の判定 getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] - (hit_x - map_max_w) enemy_hit_flg = true elsif (enemyHit_X != 19) || (enemyHit_Y == 19) #壁または崖の判定 getVariable(pos_enemy)[i][x] = getVariable(pos_enemy)[i][x] - enemy_speed enemy_hit_flg = true end #向きを反転する if enemy_hit_flg enemy_muki[i] = 0 end end #変更した座標に画像を移動する setSpritePosition(getVariable(img_enemy_name)[i], getVariable(pos_enemy)[i][x], getVariable(pos_enemy)[i][y]) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #アニメーション用カウンター enemy_anime_count[i] = enemy_anime_count[i] + 1 if enemy_anime_count[i] == (enemy_anime_change * 4) enemy_anime_count[i] = 0 end #ここから↓は省略
取得するY座標は左向き、右向き共に共通ですが、
取得するX座標は向きによって取得するポイントを切り替えています。
壁か崖の判定に入ったとき、「enemy_hit_flg」変数をオンに変更し、
「enemy_hit_flg」がオンの場合、向きを反転する仕組みになっています。
ここまでで、敵を移動させるAIができました。
保存、終了をして、テストプレーを行い、
敵が移動するか確認してみましょう。
04-02 敵を踏んで倒せるようにする
敵を踏むことで倒せるようにしてみましょう。
キャラクターと敵の当たり判定の位置判定を分けることで
踏んでいるかどうかを判断します。
それではチャプター1にて、定数の準備から。
#ここから↑は省略 #敵キャラクターの設定 max_enemy = 3 enemy_anime_change = 2 enemy_speed = 5 enemy_hit = createArray() enemy_hit[x] = 10; enemy_hit[y] = 10 enemy_hit[w] = 35; enemy_hit[h] = 35 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ enemy_point = 100 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
「enemy_point」は敵キャラクターを倒したときに
獲得できるスコアの設定です。
次は、変数の準備。
#ここから↑は省略 #敵キャラクター enemy_anime_count = createArray() enemy_muki = createArray() enemy_act = createArray() #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ enemy_dmg_count = createArray() #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ enemy_atari = createArray() i = 0 while i < max_enemy enemy_anime_count[i] = 0 enemy_muki[i] = 0 enemy_act[i] = act_wrk #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ enemy_dmg_count[i] = 0 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #敵キャラクターの当たり判定範囲 enemy_atari[i] = createArray() enemy_atari[i][x] = getVariable(pos_enemy)[i][x] + enemy_hit[x] - getVariable(pos_map)[x] enemy_atari[i][y] = getVariable(pos_enemy)[i][y] + enemy_hit[y] - getVariable(pos_map)[y] enemy_atari[i][w] = enemy_atari[i][x] + enemy_hit[w] enemy_atari[i][h] = enemy_atari[i][y] + enemy_hit[h] i = i + 1 end #ここから↓は省略
「enemy_dmg_count」は敵キャラクターを倒したときの
アニメーション、状態を管理するカウンターです。
敵キャラクターに、倒された時のアニメーションを追加します。
#ここから↑は省略 #----- 敵キャラクターのアニメーション ----- i = 0 while i < max_enemy #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ if enemy_act[i] == act_dmg #ダメージ中の場合 if enemy_dmg_count[i] < 40 #ダメージ中カウント enemy_dmg_count[i] = enemy_dmg_count[i] + 1 if enemy_dmg_count[i] == 40 #画面外へ移動する getVariable(pos_enemy)[i][x] = (-100) getVariable(pos_enemy)[i][y] = 610 setSpritePosition(getVariable(img_enemy_name)[i], getVariable(pos_enemy)[i][x], getVariable(pos_enemy)[i][y]) end end else #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #敵キャラクターAI enemy_hit_flg = false #方向転換フラグ #中略 setSpritePosition(getVariable(img_enemy_name)[i], getVariable(pos_enemy)[i][x], getVariable(pos_enemy)[i][y]) #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ end #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #アニメーション用カウンター enemy_anime_count[i] = enemy_anime_count[i] + 1 if enemy_anime_count[i] == (enemy_anime_change * 4) enemy_anime_count[i] = 0 end #敵キャラクターの表示を切替 if enemy_act[i] == act_dmg #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ if enemy_dmg_count[i] < 10 setEnemySpritePattern(4 + (enemy_muki[i] * 4), i) else setEnemySpritePattern(3 + (enemy_muki[i] * 4), i) end #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ else if enemy_anime_count[i] < (enemy_anime_change * 2) setEnemySpritePattern(1 + (enemy_muki[i] * 4), i) else setEnemySpritePattern(2 + (enemy_muki[i] * 4), i) end end #ここから↓は省略
敵キャラクターがダメージ中だった場合、
ダメージ状態カウンターが10より下かどうかで
表示を切り替えています。
また、ダメージ状態カウンターが40を超えた場合、
画面外に移動することで、敵キャラクターの表示を消しています。
敵キャラクターを踏んだかどうか、
判定するスクリプトを追加します。
#ここから↑は省略 #_/_/_/ 敵キャラクターとの当たり判定 _/_/_/ i = 0 while i < max_enemy #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ if enemy_act[i] != act_dmg #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #敵キャラクターの当たり判定範囲 enemy_atari[i] = createArray() enemy_atari[i][x] = getVariable(pos_enemy)[i][x] + enemy_hit[x] - getVariable(pos_map)[x] enemy_atari[i][y] = getVariable(pos_enemy)[i][y] + enemy_hit[y] - getVariable(pos_map)[y] enemy_atari[i][w] = enemy_atari[i][x] + enemy_hit[w] enemy_atari[i][h] = enemy_atari[i][y] + enemy_hit[h] #_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/ #当たり判定のチェック if ((char_atari[x3]) > (enemy_atari[i][x])) && ((char_atari[y2]) > (enemy_atari[i][y])) && ((char_atari[x1]) < (enemy_atari[i][w])) && ((char_atari[y1]) < (enemy_atari[i][h])) #----- 上半身 ----- #ゲームオーバー開始 char_act = act_dmg; char_dmg_count = 0 fadeOutMusicStop(100) #音楽の停止 elsif ((char_atari[x3]) > (enemy_atari[i][x])) && ((char_atari[y3]) > (enemy_atari[i][y])) && ((char_atari[x1]) < (enemy_atari[i][w])) && ((char_atari[y2]) < (enemy_atari[i][h])) #----- 下半身 ----- if char_act != act_jmp #ゲームオーバー開始 char_act = act_dmg; char_dmg_count = 0 fadeOutMusicStop(100) #音楽の停止 else #敵を倒す score = score + enemy_point char_act = act_jmp; char_jmp_count = 5 enemy_act[i] = act_dmg enemy_dmg_count[i] = 0 end end end #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
キャラクターの当たり判定と敵キャラクターの当たり判定範囲によって
上半身、下半身のどちらが当たったか、スクリプトを分岐しています。
また、敵を倒したときにキャラクターが少しだけ弾むように、
ジャンプカウンターが5の状態の、ジャンプ状態に変更しています。
ここまでで、敵を踏んで倒せる仕組みができました。
保存、終了をして、テストプレーを行い、
敵が倒せるかどうか確認してみましょう。
04-03 背景を多重スクロールにする
現在、背景とマップを表示している間に
マップよりも少しゆっくりとスクロールする背景を追加して
多重スクロール背景にしてみましょう。
第02回で追加した「setCreateMap」関数を利用します。
まずは、背景マップの追加から。
#マップ画像の設定 img_no = 79094 map_size = 5 #_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/ img_map_name = "img_map" pos_map_bg = "pos_map_bg"; pos_map = "pos_map" #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ setVariable(pos_map_bg, createArray()) getVariable(pos_map_bg)[x] = 0; getVariable(pos_map_bg)[y] = -8 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ setVariable(pos_map, createArray()) getVariable(pos_map)[x] = 0; getVariable(pos_map)[y] = -8 #マップデータの配列を準備 map_data = createArray() map_data[00] = createArray() map_data[01] = createArray() map_data[02] = createArray() map_data[03] = createArray() map_data[04] = createArray() map_data[05] = createArray() map_data[06] = createArray() map_data[07] = createArray() map_data[08] = createArray() map_data[09] = createArray() map_data[10] = createArray() map_data[11] = createArray() map_data[12] = createArray() map_data[13] = createArray() map_data[14] = createArray() map_data[15] = createArray() map_data[16] = createArray() map_data[17] = createArray() map_data[18] = createArray() #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ map_bg_stno = getVariable(img_bg_name) + 1 #背景マップデータ開始位置番号 set_z = 2 #背景マップデータを作成 map_data[00][0] = 019019019019019; map_data[00][1] = 019019019019019; map_data[00][2] = 019019019019019 map_data[01][0] = 019019019019019; map_data[01][1] = 019019019019019; map_data[01][2] = 019019019019019 map_data[02][0] = 019019019019019; map_data[02][1] = 019019019019019; map_data[02][2] = 019019019019019 map_data[03][0] = 019019019019019; map_data[03][1] = 019019019019019; map_data[03][2] = 019019019019019 map_data[04][0] = 019019019019019; map_data[04][1] = 019019019019019; map_data[04][2] = 019019019019019 map_data[05][0] = 019019019019019; map_data[05][1] = 019019019019019; map_data[05][2] = 019019019019244 map_data[06][0] = 019019019240241; map_data[06][1] = 019019019019019; map_data[06][2] = 019019019019019 map_data[07][0] = 019019019019019; map_data[07][1] = 019019019019019; map_data[07][2] = 019019019019019 map_data[08][0] = 019019019019019; map_data[08][1] = 019019019019242; map_data[08][2] = 243019019019019 map_data[09][0] = 019019019019019; map_data[09][1] = 019019019019019; map_data[09][2] = 019019019019019 map_data[10][0] = 019019019019019; map_data[10][1] = 019019019019019; map_data[10][2] = 019019019019019 map_data[11][0] = 019019019019019; map_data[11][1] = 019019019019019; map_data[11][2] = 019019019019019 map_data[12][0] = 019019019019019; map_data[12][1] = 019019019019019; map_data[12][2] = 019019019019019 map_data[13][0] = 019019019019019; map_data[13][1] = 019019019019019; map_data[13][2] = 019019019019019 map_data[14][0] = 019019019019019; map_data[14][1] = 019019019019019; map_data[14][2] = 019019019019019 map_data[15][0] = 019019019019019; map_data[15][1] = 019019019019019; map_data[15][2] = 019019019019019 map_data[16][0] = 019019019019019; map_data[16][1] = 019019019019019; map_data[16][2] = 019019019019019 map_data[17][0] = 019019019019019; map_data[17][1] = 019019019019019; map_data[17][2] = 019019019019019 map_data[18][0] = 019019019019019; map_data[18][1] = 019019019019019; map_data[18][2] = 019019019019019 map_data[00][3] = 019019019019019; map_data[00][4] = 019019019019019; map_data[00][5] = 019019019019019 map_data[01][3] = 019019019019019; map_data[01][4] = 019019019019019; map_data[01][5] = 019019019019019 map_data[02][3] = 019019019019019; map_data[02][4] = 019019019019019; map_data[02][5] = 019019019019019 map_data[03][3] = 019019019019019; map_data[03][4] = 019019019019019; map_data[03][5] = 019019019019019 map_data[04][3] = 019019019019019; map_data[04][4] = 019019019019019; map_data[04][5] = 019019019019019 map_data[05][3] = 245019019019019; map_data[05][4] = 019019019019019; map_data[05][5] = 019019019019019 map_data[06][3] = 019019019019019; map_data[06][4] = 019019019019019; map_data[06][5] = 019019019019019 map_data[07][3] = 019019019019019; map_data[07][4] = 019019019019019; map_data[07][5] = 019019019240241 map_data[08][3] = 019019019019019; map_data[08][4] = 019019242243019; map_data[08][5] = 019019019019019 map_data[09][3] = 019019019019019; map_data[09][4] = 019019019019019; map_data[09][5] = 019019019019019 map_data[10][3] = 019019019019019; map_data[10][4] = 019019019019019; map_data[10][5] = 019019019019019 map_data[11][3] = 019019019019019; map_data[11][4] = 019019019019019; map_data[11][5] = 019019019019019 map_data[12][3] = 019019019019019; map_data[12][4] = 019019019019019; map_data[12][5] = 019019019019019 map_data[13][3] = 019019019019019; map_data[13][4] = 019019019019019; map_data[13][5] = 019019019019019 map_data[14][3] = 019019019019019; map_data[14][4] = 019019019019019; map_data[14][5] = 019019019019019 map_data[15][3] = 019019019019019; map_data[15][4] = 019019019019019; map_data[15][5] = 019019019019019 map_data[16][3] = 019019019019019; map_data[16][4] = 019019019019019; map_data[16][5] = 019019019019019 map_data[17][3] = 019019019019019; map_data[17][4] = 019019019019019; map_data[17][5] = 019019019019019 map_data[18][3] = 019019019019019; map_data[18][4] = 019019019019019; map_data[18][5] = 019019019019019 setCreateMap(img_map_name, img_no, pos_map_bg, set_z, map_size, map_data) map_bg_edno = getVariable(img_map_name) + 1 #背景マップデータ終了位置番号 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ set_z = 4 #マップデータを作成 #ここから↓は省略
マップデータの準備前に、背景マップデータの準備を追加しています。
背景マップデータはカメラのスクロールの対象外となる
レイヤー番号「set_z」を2に設定しています。
また、スクロールをカメラに頼らず行う必要があるため、
背景マップデータの開始位置、終了位置番号を取得し、変数に準備しています。
スクロール用の変数を準備します。
#ここから↑は省略 #ゴールの当たり判定範囲 goal_atari[i] = createArray() goal_atari[i][x] = getVariable(pos_goal)[i][x] + goal_hit[x] - getVariable(pos_map)[x] goal_atari[i][y] = getVariable(pos_goal)[i][y] + goal_hit[y] - getVariable(pos_map)[y] goal_atari[i][w] = goal_atari[i][x] + goal_hit[w] goal_atari[i][h] = goal_atari[i][y] + goal_hit[h] #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ #背景スクロール pos_map_sa = 0 pos_map_old = getVariable(pos_map)[x] #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #----- テキストボックスの設定 ----- #スコア表示の設定 #ここから↓は省略
「pos_map_sa」はマップスクロールの移動量、
「pos_map_old」は移動量の計算に使用します。
背景マップデータをスクロールします。
#ここから↑は省略 #----- 背景のスクロール ----- #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ #背景マップ pos_map_sa = pos_map_old - getVariable(pos_map)[x] if pos_map_sa != 0 getVariable(pos_map_bg)[x] = getVariable(pos_map_bg)[x] + (pos_map_sa * (char_speed * 0.01)) i = map_bg_stno while i < map_bg_edno setSpritePosition(i, getVariable(pos_map_bg)[x], getVariable(pos_map_bg)[y]) i = i + 1 end pos_map_old = getVariable(pos_map)[x] end #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #マップ setSpriteCameraOffset(-(getVariable(pos_map)[x]), 0) #ここから↓は省略
まず、前回のマップ位置座標である「pos_map_old」と
現在の「getVariable(pos_map)[x]」を比較し、
差分である「pos_map_sa」を計算しています。
この「pos_map_sa」の値が0以外に変わっていた場合、
「pos_map_sa」を「char_speed」の0.01倍、背景マップデータを移動させ、
スクロールしています。
while文でループしているのは、マップのときとは異なり、
マップチップの画像ごとに移動を設定する必要があるため、
背景マップデータの作成時に準備しておいた
「map_bg_stno」「map_bg_edno」を元に、
マップチップ画像を1枚ずつ移動させています。
ここまでで、背景を多重スクロールさせる仕組みができました。
保存、終了をして、テストプレーを行い、
背景がスクロールするかどうか確認してみましょう。
04-04 効果音を再生する
アイテムの取得、ゲームオーバー、ゲームクリア時に
効果音を再生してみましょう。
今回もまた、お手軽にスクリプトの作成までできるよう、
サンプルの素材を準備いたしました。
なお、効果音素材はrerofumi様、TAM Music Factory 多夢(TAM)様の素材を
許可を頂きまして、利用させていただいております。
こちらを参考に、クリップからリソースへの登録まで行い、
すぐにスクリプトで利用できるように、準備してください。
それではチャプター1に、定数を準備するところから。
#ここから↑は省略 #音楽・効果音の設定 bgm_main = 66498 bgm_vol = 0.7 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_clear = 89978 se_gameover = 89981 se_get = 89930 se_dmg = 63622 se_vol = 1 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
「se_clear」「se_gameover」「se_get」は効果音素材のID、
「se_vol」は効果音の再生音量を設定しています。
次に、再生の準備を行います。
#ここから↑は省略 #スコアの初期表示 score = 0 str = "スコア " str = str + addZero(score, 5) setText(text_score, str) #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ #効果音の事前準備 se_id = playSound(se_clear); setSoundVolume(se_id, 0) se_id = playSound(se_gameover); setSoundVolume(se_id, 0) se_id = playSound(se_get); setSoundVolume(se_id, 0) se_id = playSound(se_dmg); setSoundVolume(se_id, 0) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #音楽の再生開始 playBGM(bgm_main); setMusicVolume(bgm_vol)
再生音量 0 で予め再生しておくことで
プレイ中の再生がスムーズに行われるようにしています。
それぞれの再生タイミングで、効果音の再生を行います。
#ここから↑は省略 score = score + goal_point #ゲームクリア開始 char_goal_count = 1 char_act = act_std fadeOutMusicStop(100) #音楽の停止 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_clear) setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #中略 getVariable(pos_item)[i][x] = (-100) getVariable(pos_item)[i][y] = 700 setSpritePos(img_item_name, getVariable(pos_item), i) #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_get) setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #中略 #当たり判定のチェック if ((char_atari[x3]) > (enemy_atari[i][x])) && ((char_atari[y2]) > (enemy_atari[i][y])) && ((char_atari[x1]) < (enemy_atari[i][w])) && ((char_atari[y1]) < (enemy_atari[i][h])) #----- 上半身 ----- #ゲームオーバー開始 char_act = act_dmg; char_dmg_count = 0 fadeOutMusicStop(100) #音楽の停止 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_gameover); setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ elsif ((char_atari[x3]) > (enemy_atari[i][x])) && ((char_atari[y3]) > (enemy_atari[i][y])) && ((char_atari[x1]) < (enemy_atari[i][w])) && ((char_atari[y2]) < (enemy_atari[i][h])) #----- 下半身 ----- if char_act != act_jmp #ゲームオーバー開始 char_act = act_dmg; char_dmg_count = 0 fadeOutMusicStop(100) #音楽の停止 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_gameover); setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ else #敵を倒す score = score + enemy_point char_act = act_jmp; char_jmp_count = 5 enemy_act[i] = act_dmg enemy_dmg_count[i] = 0 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_dmg); setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ end end end i = i + 1 end #穴に落下 if pos_char[y] > (gameover_pos_y - 25) #ダメージ状態開始 char_act = act_dmg; char_dmg_count = 0 fadeOutMusicStop(100) #音楽の停止 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ se_id = playSound(se_gameover); setSoundVolume(se_id, se_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ end #ここから↓は省略
スクリプト全体
これで、一通り完成です。
保存、終了をして、テストプレーを行い、
効果音が再生されるか確認してみましょう。
なお、メインループのフレーム数、ジャンプの落下速度、
ゴールの当たり判定を調整しなおしています。
ゲームを公開状態にするときは、
こちらを参考に、オープニング、エンディング、ゲームオーバーの設定も
忘れないようにしましょう。
04-05 おわりに
いかがでしたでしょうか。
前回のシリーズでお話しましたSTGの拡張として、
今回のシリーズではACTゲームならではの仕組みや動きも
追加してきました。
どのようなジャンルのゲームでも
どうやって動かしていくか、という工夫は必要になってきますが、
定数や変数の使い方、画像の表示や移動といった
基本的なところは、共通の流れです。
今回までのシリーズをきっかけに、
面白いアイデアの作品、新しいジャンルのゲームなどが
Rmakeにて登場することを
心より期待、応援しております。
なお、今回のシリーズで完成したサンプルのゲームを
公開しておりますので、実際にプレイしてみたい方は
是非、遊んでみてください。
アクションサンプルゲーム - 【ノベルゲーム】
第01回 関数を再利用してみよう
第02回 マップを表示してみよう
第03回 敵・アイテムを追加してみよう
第04回 敵の動きや背景の演出を入れてみよう
番外 外部ツールと連携してみよう
コメントする
コメントするには、ログインする必要があります。
これについて少し説明していただけないでしょうか?
テスト中用スクリプトです。
charHit_~はキャラクターの座標関連
charHitpos~はそれを元にした当たり判定座標関連
HitFlg~は実際の当たり判定の状態です。
最後のxSa、ySaはスクロール位置の座標です。