スクリプト/Rmakeで自由なゲームをつくろう / 第04回 敵キャラクターを登場させる
最終投稿者:
aoihikawa
更新:2011/08/11 23:07:26
Rmakeで自由なゲームをつくろう
第04回 敵キャラクターを登場させる
こんにちは。
フリーデザイナープログラマー(自称)の
簸川 葵(ひかわ あおい)と申します。
第03回 ではキャラクターをキー操作で動かすまでのお話でした。
第04回は、これまでつくってきたものに、ちょっとずつ手を加えながら
敵キャラクターを登場させるところまで、やっていきますね。
04-01 背景を動かそう
敵キャラクターを登場させる前に、前回のおさらいも兼ねて、
背景を動かしてみましょう。
背景を動かすためには、縦に長ーい画像を準備する方法もありますが、
今回は、1枚の絵を2枚使用して、これをループさせて表示します。
さて、2枚同じものを表示するには、
背景に関連しているスクリプトを、コピーして増やすこともできますが、
スクリプトがどんどん長くなってしまいます。
そこで、「配列」というものを使います。
配列とは、変数を分割し縦に長い箱にしたものです。
縦方向の場所を区別するときは、番号を使用します。
#変数
pos_bg_x = 0
#変数の配列化
pos_bg_x = createArray() #変数を配列にする関数
#これ以降、「pos_bg_x」は配列になります
pos_bg_x[0] = 0 #配列は「変数[番号]」で場所を区別します
pos_bg_x[1] = 800
basyo = 2
pos_bg_x[basyo] = 1600 #番号に入れる数値は、変数でも使用できます
配列の各番号の場所を、さらに配列にすることもできます。
これを「2次元配列」と呼びます。
変数が、リバーシゲームの升目のようになった感じですね。
pos_bg = createArray() #変数を配列にします
#0番目を1枚目の背景、1番目を2枚目の背景とします。
pos_bg[0] = createArray() #配列の中身をさらに配列にします(2次元配列)
pos_bg[1] = createArray() #次の場所も同じように
x = 0; y = 1 #分かりやすくするために定数を準備しておきます
pos_bg[0][x] = 0 #1枚目の背景のX座標とY座標
pos_bg[0][y] = 0
pos_bg[1][x] = 0 #2枚目の背景のX座標とY座標
pos_bg[1][y] = 0
これを繰り返すことで、3次元配列、とか4次元配列、などという
感じのものも作ることができてしまいます。
ただ、これ以降場合、「多次元配列」という呼び方で
まとめてしまうことが多いです。
それでは、この配列を利用して、
表示する背景を2枚に増やしてみましょう。
#ここから↑は省略 #_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/ #----- 画像の設定 ----- get = createArray() set = createArray() x = 0; y = 1; w = 2; h = 3 #キャラクター画像の設定 img_no = 76793 img_char_name = "img_char" get[x] = 0; get[y] = 0; get[w] = 64; get[h] = 64 set[x] = 0; set[y] = 0; set[w] = 64; set[h] = 64 set_z = 7 pos_char = createArray() pos_char[x] = 368; pos_char[y] = 500 setCreateSprite(img_char_name, img_no, get, set, set_z, pos_char) #背景画像の設定 img_no = 76800 img_bg_name = "img_bg" get[x] = 0; get[y] = 0; get[w] = 800; get[h] = 600 set[x] = 0; set[y] = 0; set[w] = 800; set[h] = 600 set_z = 1 pos_bg = createArray() pos_bg[0] = createArray() pos_bg[0][x] = 0; pos_bg[0][y] = 0 pos_bg[1] = createArray() pos_bg[1][x] = 0; pos_bg[1][y] = -600 setCreateSprite(img_bg_name, img_no, get, set, set_z, pos_bg, 2) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
setCreateSpriteの引数に含まれている配列に番号が振られていません。
このように、配列に番号が振られていない場合、
その配列の集合全体を意味します。
つまり、「get」は「get[x]~get[h]」を纏めた状態で
関数に渡しているわけです。
それでは、受け取る方の関数も配列に対応してあげましょう。
#メニュー項目等の表示OFF
setMenuItemVisible(getMenuBackLog(), false)
setMenuItemVisible(getMenuSave(), false)
setMenuItemVisible(getMenuLoad(), false)
setHelpVisible(false)
#キャンバスの初期化
setCanvasVisible(false)
deleteAllSprite()
drawCanvas()
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#----- 関数の設定 -----
#スプライトの表示位置を変更する関数
def setSpritePos(img_name, pos, i)
if i
setSpritePosition(getVariable(img_name)[i],
pos[i][0], pos[i][1])
else
setSpritePosition(getVariable(img_name),
pos[0], pos[1])
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/
#画像を設定する関数
def setCreateSprite(img_name, img_no, get, set, set_z, pos, ilen)
x = 0; y = 1; w = 2; h = 3
if ilen
setVariable(img_name, createArray())
i = 0
while i < ilen
getVariable(img_name)[i] = createSprite(img_no)
setSpriteRect(getVariable(img_name)[i],
get[x], get[y], get[w], get[h],
set[x], set[y], set[w], set[h])
setSpriteZOrder(getVariable(img_name)[i], set_z)
setSpritePos(img_name, pos, i)
i = i + 1
end
else
setVariable(img_name, createSprite(img_no))
setSpriteRect(getVariable(img_name),
get[x], get[y], get[w], get[h],
set[x], set[y], set[w], set[h])
setSpriteZOrder(getVariable(img_name), set_z)
setSpritePos(img_name, pos)
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#ここから↓は省略
1つめのsetSpritePosという関数はsetSpritePositionを
簡単に利用するために纏めた関数になっています。
引数の「i」は配列の場所を受け取る仕組みになっています。
もし、場所が指定されていない場合、
通常の変数として扱うように処理を分岐させています。
2つめのsetCreateSpriteという関数は先ほどの
「get」、「set」、「pos」という配列に対応するように
変更されています。
また、渡された値が配列だった場合、
配列の長さだけループさせて、画像を設定するように
変更されています。
背景を動かす定数を準備します。
#ここから↑は省略 #定数の設定 char_speed = 10 char_w_max = 800 - 64; char_h_max = 600 - 64 char_anime_change = 3 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ bg_speed = 3 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #変数の設定 char_anime_count = 0 #ここから↓は省略
「bg_speed」には、背景の移動速度が入ります。
準備した配列や関数などを利用して、
キャラクターの移動の変更点と
背景を動かす処理のスクリプトを書きます。
#ここから↑は省略
#----- ゲームのメイン処理を入れる場所 -----
#(ゲームの終了時はmainloopをfalseに)
#----- キャラクターの移動 -----
#_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/
if key_flg_left
#左
pos_char[x] = pos_char[x] - char_speed
if pos_char[x] < 0
pos_char[x] = 0
end
setSpritePos(img_char_name, pos_char)
elsif key_flg_right
#右
pos_char[x] = pos_char[x] + char_speed
if pos_char[x] > char_w_max
pos_char[x] = char_w_max
end
setSpritePos(img_char_name, pos_char)
end
if key_flg_up
#上
pos_char[y] = pos_char[y] - char_speed
if pos_char[y] < 0
pos_char[y] = 0
end
setSpritePos(img_char_name, pos_char)
elsif key_flg_down
#下
pos_char[y] = pos_char[y] + char_speed
if pos_char[y] > char_h_max
pos_char[y] = char_h_max
end
setSpritePos(img_char_name, pos_char)
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#----- キャラクターのアニメーション -----
#アニメーション用カウンター
char_anime_count = char_anime_count + 1
if char_anime_count == (char_anime_change * 2)
char_anime_count = 0
end
#キャラクターの表示を切替
if key_flg_left
if char_anime_count < char_anime_change
setCharSpritePattern(2)
else
setCharSpritePattern(5)
end
elsif key_flg_right
if char_anime_count < char_anime_change
setCharSpritePattern(3)
else
setCharSpritePattern(6)
end
else
if char_anime_count < char_anime_change
setCharSpritePattern(1)
else
setCharSpritePattern(4)
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#----- 背景のスクロール -----
i = 0
while i < 2
pos_bg[i][y] = pos_bg[i][y] + bg_speed
if pos_bg[i][y] > 600
pos_bg[i][y] = (pos_bg[i][y] % 600) - 600
end
setSpritePos(img_bg_name, pos_bg, i)
i = i + 1
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#----- 画面の更新 -----
drawCanvas()
waitTime(30)
end
endInput() #入力受付の終了
goEnding() #ゲームのクリア
ここまでで、背景がスクロールするようになりました。
完成したら、テストプレーを行ってみましょう。
04-02 敵キャラクターを表示しよう
今回も、お手軽にスクリプトの作成までできるよう、
敵キャラクターのサンプルの素材を準備いたしました。
第02回を参考に、クリップからリソースへの登録まで行い、
すぐにスクリプトで利用できるように、準備してください。
それでは、敵キャラクター用の関数から。
ベースはキャラクター用の関数を利用します。
#ここから↑は省略
#キャラクターの表示内容を変更する関数
def setCharSpritePattern(no)
img_char_name = "img_char"
get_x = 0; get_y = 0; get_w = 64; get_h = 64
set_x = 0; set_y = 0; set_w = 64; set_h = 64
if no == 1
get_x = 0; get_y = 0
elsif no == 2
get_x = 64; get_y = 0
elsif no == 3
get_x = 128; get_y = 0
elsif no == 4
get_x = 0; get_y = 64
elsif no == 5
get_x = 64; get_y = 64
elsif no == 6
get_x = 128; get_y = 64
else
get_w = 0; get_h = 0
set_w = 0; set_h = 0
end
setSpriteRect(getVariable(img_char_name),
get_x, get_y, get_w, get_h,
set_x, set_y, set_w, set_h)
end
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクターの表示内容を変更する関数
def setEnemySpritePattern(no, i)
img_enemy_name = "img_enemy"
get_x = 0; get_y = 0; get_w = 64; get_h = 64
set_x = 0; set_y = 0; set_w = 64; set_h = 64
if no == 1
get_x = 0; get_y = 0
elsif no == 2
get_x = 64; get_y = 0
elsif no == 3
get_x = 128; get_y = 0
elsif no == 4
get_x = 192; get_y = 0
else
get_w = 0; get_h = 0
set_w = 0; set_h = 0
end
setSpriteRect(getVariable(img_enemy_name)[i],
get_x, get_y, get_w, get_h,
set_x, set_y, set_w, set_h)
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#ここから↓は省略
作成した関数のすぐ下に、ばらばらな箇所でつくっていた定数を纏めながら
敵キャラクター用の定数も定義します。
定数を一纏めにしておく方が、後でちょっと値を変更したくなった時、
分かりやすいからです。
さらに、どういった意味の定数なのか、コメントも付けておきますね。
#ここから↑は省略
setSpriteRect(getVariable(img_enemy_name)[i],
get_x, get_y, get_w, get_h,
set_x, set_y, set_w, set_h)
end
#_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/
#----- 定数の設定 -----
x = 0; y = 1; w = 2; h = 3
#キャラクターの設定
char_speed = 10
char_w_max = 800 - 64; char_h_max = 600 - 64
char_anime_change = 3
#背景の設定
bg_speed = 3
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクターの設定
max_enemy = 3
enemy_speed = 5
enemy_baratuki = 20
enemy_w_max = 800 - 64; enemy_h_min = -64
enemy_anime_change = 2
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
「max_enemy」は敵キャラクターの数、
「enemy_speed」は敵キャラクターの移動速度、
「enemy_baratuki」は敵キャラクターを出現させるときのばらつき具合、
「enemy_w_max」と「enemy_h_min」は後で使用する
敵キャラクターの出現位置となるX座標の最大値とY座標を設定しています。
続いて、画像の設定です。
こちらも、キャラクターの設定をベースにしながら、
敵キャラクターの数だけ、配列で増やします。
#ここから↑は省略
enemy_anime_change = 2
#----- 画像の設定 -----
get = createArray()
set = createArray()
#キャラクター画像の設定
img_no = 76793
img_char_name = "img_char"
get[x] = 0; get[y] = 0; get[w] = 64; get[h] = 64
set[x] = 0; set[y] = 0; set[w] = 64; set[h] = 64
set_z = 7
pos_char = createArray()
pos_char[x] = 368; pos_char[y] = 500
setCreateSprite(img_char_name, img_no, get, set, set_z, pos_char)
#背景画像の設定
img_no = 76800
img_bg_name = "img_bg"
get[x] = 0; get[y] = 0; get[w] = 800; get[h] = 600
set[x] = 0; set[y] = 0; set[w] = 800; set[h] = 600
set_z = 1
pos_bg = createArray()
pos_bg[0] = createArray()
pos_bg[0][x] = 0; pos_bg[0][y] = 0
pos_bg[1] = createArray()
pos_bg[1][x] = 0; pos_bg[1][y] = -600
setCreateSprite(img_bg_name, img_no, get, set, set_z, pos_bg, 2)
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクターの画像の設定
img_no = 77127
img_enemy_name = "img_enemy"
get[x] = 0; get[y] = 0; get[w] = 64; get[h] = 64
set[x] = 0; set[y] = 0; set[w] = 64; set[h] = 64
set_z = 5
pos_enemy = createArray()
i = 0
while i < max_enemy
pos_enemy[i] = createArray()
pos_enemy[i][x] = 800; pos_enemy[i][y] = 600
i = i + 1
end
setCreateSprite(img_enemy_name, img_no, get, set,
set_z, pos_enemy, max_enemy)
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#ここから↓は省略
敵キャラクターの初期座標が画面外になっています。
これは登場するシーンがくるまで、舞台袖で待っていてもらうのと
同じ仕組みになっています。
変数も同様に、キャラクターの設定をベースにしながら、
敵キャラクターの数だけ、配列で増やします。
#ここから↑は省略
setCreateSprite(img_enemy_name, img_no, get, set,
set_z, pos_enemy, max_enemy)
#----- 変数の設定 -----
#キー入力フラグの設定
key_flg_left = false; key_flg_right = false
key_flg_up = false; key_flg_down = false
key_flg_z = false
#アニメーション用カウンター
#キャラクター
char_anime_count = 0
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクター
enemy_anime_count = createArray()
i = 0
while i < max_enemy
enemy_anime_count[i] = -1
i = i + 1
end
enemy_syutugen_count = 0
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#画面の更新
drawCanvas()
setCanvasVisible(true)
#ここから↓は省略
「enemy_syutugen_count」は敵キャラが画面上に何体出現しているか
カウントするために使用します。
後でこれを利用することで、敵キャラクターを出現させる
スクリプトの実行を分岐させます。
最後に、敵キャラクターを登場、アニメーションさせる
スクリプトを書きます。
#ここから↑は省略
#----- 背景のスクロール -----
i = 0
while i < 2
pos_bg[i][y] = pos_bg[i][y] + bg_speed
if pos_bg[i][y] > 600
pos_bg[i][y] = (pos_bg[i][y] % 600) - 600
end
setSpritePos(img_bg_name, pos_bg, i)
i = i + 1
end
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#----- 敵キャラクターのアニメーション -----
i = 0
while i < max_enemy
#敵キャラクターを出現させる
if (enemy_syutugen_count < max_enemy) && (enemy_anime_count[i] < 0)
if rand(enemy_baratuki) == 0
#出現カウントが最大値より少なく、アニメーションがマイナス(初期値)の場合
enemy_syutugen_count = enemy_syutugen_count + 1 #出現カウント
pos_enemy[i][x] = rand(enemy_w_max)
pos_enemy[i][y] = enemy_h_min
enemy_anime_count[i] = 0 #アニメーションをリセット
end
end
if enemy_anime_count[i] > -1
#アニメーション用カウンター
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_anime_count[i] < enemy_anime_change
setEnemySpritePattern(1, i)
elsif enemy_anime_count[i] < (enemy_anime_change * 2)
setEnemySpritePattern(2, i)
elsif enemy_anime_count[i] < (enemy_anime_change * 3)
setEnemySpritePattern(3, i)
else
setEnemySpritePattern(2, i)
end
#敵キャラクターの移動
pos_enemy[i][y] = pos_enemy[i][y] + enemy_speed
if pos_enemy[i][y] > 600
enemy_syutugen_count = enemy_syutugen_count - 1 #出現カウント
pos_enemy[i][x] = 800
pos_enemy[i][y] = 600
enemy_anime_count[i] = -1
end
setSpritePos(img_enemy_name, pos_enemy, i)
end
i = i + 1
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#----- 画面の更新 -----
drawCanvas()
waitTime(30)
end
endInput() #入力受付の終了
goEnding() #ゲームのクリア
こちらも、基本的にはキャラクターのスクリプトをベースにしていますが、
いくつか、異なっている箇所があります。
説明用に、先ほどの一部を抜粋します。
i = 0
while i < max_enemy
#敵キャラクターを出現させる
if (enemy_syutugen_count < max_enemy) && (enemy_anime_count[i] < 0)
まず、while文で敵キャラクターの最大数まで、処理をループさせています。
次にif文が入っていますが、ここで新しい記号が登場しています。
実は、while文やif文の条件式は、ひとつの条件式の中に、
同時に複数の条件を組み合わせることができます。
「(条件1) && (条件2)」はAND関数と呼び、
条件1と条件2の両方が成立したときだけ、成立と判断されます。
「(条件1) || (条件2)」はOR関数と呼び、
条件1と条件2のどちらか片方でも成立したら、成立と判断されます。
なお、while文、if文などの途中で、この条件式を繋ぐ記号が行の最後だった場合
関数の「,」の時のように、次の行もスクリプトでは同じ行として判断されます。
#次の2つは同一
if (enemy_syutugen_count < max_enemy) && (enemy_anime_count[i] < 0)
end
#--------------------------------------------------
if (enemy_syutugen_count < max_enemy) &&
(enemy_anime_count[i] < 0)
end
また、ちょっと特殊なもので、
「!(条件1) 」はNOT関数と呼び、
条件1が不成立なら成立、成立なら不成立、と判断されるものもあります。
説明用に、先ほどの一部を抜粋します。
if rand(enemy_baratuki) == 0
#出現カウントが最大値より少なく、アニメーションがマイナス(初期値)の場合
enemy_syutugen_count = enemy_syutugen_count + 1 #出現カウント
pos_enemy[i][x] = rand(enemy_w_max)
pos_enemy[i][y] = enemy_h_min
enemy_anime_count[i] = 0 #アニメーションをリセット
end
次のif文では、第01回で登場した、rand関数が使用されています。
「0~enemy_baratuki」の間でランダムで値を決定してもらい、
この値が「0」となったときだけ、出現させるスクリプトに移動するようになっています。
if文の中身については、出現数のカウントと
出現させた時の変数の初期値の設定を行っています。
X座標もまた、毎回異なる場所に出現するように、
「0~enemy_w_max」でX座標を決定してもらうように、rand関数が使用されています。
説明用に、先ほどの一部を抜粋します。
if enemy_anime_count[i] > -1
#アニメーション用カウンター
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_anime_count[i] < enemy_anime_change
setEnemySpritePattern(1, i)
elsif enemy_anime_count[i] < (enemy_anime_change * 2)
setEnemySpritePattern(2, i)
elsif enemy_anime_count[i] < (enemy_anime_change * 3)
setEnemySpritePattern(3, i)
else
setEnemySpritePattern(2, i)
end
続いて、敵キャラクターのアニメーション。
「enemy_anime_count」が初期値になっているかどうか判断することで、
出現している状態のときのみ実行されるようになっています。
また、アニメーションが耳をぱたぱたさせる動きとなる、
1→2→3→2の繰り返しとなるよう変更されています。
説明用に、先ほどの一部を抜粋します。
#敵キャラクターの移動
pos_enemy[i][y] = pos_enemy[i][y] + enemy_speed
if pos_enemy[i][y] > 600
enemy_syutugen_count = enemy_syutugen_count - 1 #出現カウント
pos_enemy[i][x] = 800
pos_enemy[i][y] = 600
enemy_anime_count[i] = -1
end
setSpritePos(img_enemy_name, pos_enemy, i)
end
最後に、敵キャラクターの移動と座標の移動。
if文で、画面外まで敵キャラクターが移動したとき、
使用していた変数を初期化する仕組みになっています。
ここまでで、敵キャラクターが表示されるようになりました。
完成したら、テストプレーを行ってみましょう。
04-03 当たり判定を付けよう
さて、敵キャラクターが登場しただけでは少し物足りないですね。
キャラクターが敵キャラクターに当ったとき、ミスになるように
キャラクターと敵キャラクターに当たり判定を付けてみましょう。
まずは当たり判定の設定から。
キャラクターの座標をそのまま利用することも出来ますが、
今回は、それより内側の位置に当たり判定を設定します。
キャラクターの座標から当たり判定までの
差分の値を定数で設定します。
#ここから↑は省略 #----- 定数の設定 ----- x = 0; y = 1; w = 2; h = 3 #キャラクターの設定 char_speed = 10 char_w_max = 800 - 64; char_h_max = 600 - 64 char_anime_change = 3 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ char_hit = createArray() char_hit[x] = 25; char_hit[y] = 20 char_hit[w] = 14; char_hit[h] = 30 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #背景の設定 bg_speed = 3 #敵キャラクターの設定 max_enemy = 3 enemy_speed = 5 enemy_baratuki = 20 enemy_w_max = 800 - 64; enemy_h_min = -64 enemy_anime_change = 2 #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ enemy_hit = createArray() enemy_hit[x] = 20; enemy_hit[y] = 20 enemy_hit[w] = 24; enemy_hit[h] = 35 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
差分から、当たり判定を算出して保存しておく変数を準備します。
#ここから↑は省略
#アニメーション用カウンター
#キャラクター
char_anime_count = 0
#敵キャラクター
enemy_anime_count = createArray()
i = 0
while i < max_enemy
enemy_anime_count[i] = -1
i = i + 1
end
enemy_syutugen_count = 0
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#キャラクターの非ダメージ
char_damage = false
#キャラクターの当たり判定範囲
char_atari = createArray()
char_atari[x] = pos_char[x] + char_hit[x]
char_atari[y] = pos_char[y] + char_hit[y]
char_atari[w] = char_atari[x] + char_hit[w]
char_atari[h] = char_atari[y] + char_hit[h]
#敵キャラクターの当たり判定範囲
enemy_atari = createArray()
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#画面の更新
drawCanvas()
setCanvasVisible(true)
#ここから↓は省略
「char_damage」には、敵に当たったかどうかの
スイッチを設定します。
キャラクター、敵キャラクターの移動ごとに、
当たり判定の再計算を行います。
#ここから↑は省略
setCharSpritePattern(4)
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#キャラクターの当たり判定範囲
if key_flg_left || key_flg_right || key_flg_up || key_flg_down
char_atari[x] = pos_char[x] + char_hit[x]
char_atari[y] = pos_char[y] + char_hit[y]
char_atari[w] = char_atari[x] + char_hit[w]
char_atari[h] = char_atari[y] + char_hit[h]
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
#----- 背景のスクロール -----
#ここから↓は省略
#ここから↑は省略
#敵キャラクターの移動
pos_enemy[i][y] = pos_enemy[i][y] + enemy_speed
if pos_enemy[i][y] > 600
enemy_syutugen_count = enemy_syutugen_count - 1 #出現カウント
pos_enemy[i][x] = 800
pos_enemy[i][y] = 600
enemy_anime_count[i] = -1
end
setSpritePos(img_enemy_name, pos_enemy, i)
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクターの当たり判定範囲
enemy_atari[x] = pos_enemy[i][x] + enemy_hit[x]
enemy_atari[y] = pos_enemy[i][y] + enemy_hit[y]
enemy_atari[w] = enemy_atari[x] + enemy_hit[w]
enemy_atari[h] = enemy_atari[y] + enemy_hit[h]
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
end
i = i + 1
end
#ここから↓は省略
最後に、実際に当たったかどうかの判定を行い、
当たってしまうとメインループを終了させ、ゲームを終了します。
当たったかどうかの判定は、キャラクターと敵キャラクターの
上下左右、それぞれの位置が超えているかどうか比較することで
判断します。
#ここから↑は省略
#敵キャラクターの移動
pos_enemy[i][y] = pos_enemy[i][y] + enemy_speed
if pos_enemy[i][y] > 600
enemy_syutugen_count = enemy_syutugen_count - 1 #出現カウント
pos_enemy[i][x] = 800
pos_enemy[i][y] = 600
enemy_anime_count[i] = -1
end
setSpritePos(img_enemy_name, pos_enemy, i)
#敵キャラクターの当たり判定範囲
enemy_atari[x] = pos_enemy[i][x] + enemy_hit[x]
enemy_atari[y] = pos_enemy[i][y] + enemy_hit[y]
enemy_atari[w] = enemy_atari[x] + enemy_hit[w]
enemy_atari[h] = enemy_atari[y] + enemy_hit[h]
#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#当たり判定のチェック
if ((char_atari[w]) > (enemy_atari[x])) &&
((char_atari[h]) > (enemy_atari[y])) &&
((char_atari[x]) < (enemy_atari[w])) &&
((char_atari[y]) < (enemy_atari[h]))
char_damage = true
mainloop = false
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
end
i = i + 1
end
#----- 画面の更新 -----
drawCanvas()
waitTime(30)
end
endInput() #入力受付の終了
#_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/
if char_damage
goBadEnding() #ゲームオーバー
else
goEnding() #ゲームのクリア
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
当たってしまったとき、「char_damage」をオンに変更してから、
「mainloop」をオフに変更してゲームのメインループを抜けています。
最後に、「char_damage」を比較することで、
ゲームクリアか、ゲームオーバーか分岐させています。
なお、新しく登場したgoBadEndingは、
ゲームオーバー画面に移動する関数です。
スクリプト全体(一部、少し整理しています)
これで、一通り完成です。
保存、終了をして、テストプレーを行い、
敵キャラクターに当たると、ゲームオーバーになるかどうか、
確認してみましょう。
04-04 おわりに
いかがでしたでしょうか。
大分、シューティングゲームらしくなってきました。
さて、次回は敵キャラクターに反撃する手段、
「弾を発射させる」です。
第01回 スクリプトって何?
第02回 画面にキャラクターを描画する
第03回 キャラクターをキー入力で操作する
第04回 敵キャラクターを登場させる
第05回 弾を発射させる
第06回 より面白くするために
この記事についてご質問等がありましたら
こちらのブログ記事のコメントへご投稿、
よろしくお願いいたします。
コメントする
コメントするには、ログインする必要があります。
コメント一覧
コメントはありません。