Rmakeで自由なゲームをつくろう / 第05回 弾を発射させる

投稿者:Cdv30200 aoi icon mini aoihikawa 投稿日:2011/08/08 20:52

Rmakeで自由なゲームをつくろう

 第05回 敵キャラクターを登場させる


  こんにちは。
 フリーデザイナープログラマー(自称)の
 簸川 葵(ひかわ あおい)と申します。


 第04回 では敵キャラクターを登場させるまでのお話でした。
 第05回は、
 弾を発射させるところまで、やっていきますね。



05-01 弾を表示しよう




  弾、とはキャラクターの位置から移動が開始されるところと
 移動する方向が異なりますが、基本的な動きは敵キャラクターと同じです。
  これまでのスクリプトを元にしながら、まずは弾を表示させるところまで
 つくってみましょう。

  今回もまた、お手軽にスクリプトの作成までできるよう、
 サンプルの素材を準備いたしました。


  第02回を参考に、クリップからリソースへの登録まで行い、
 すぐにスクリプトで利用できるように、準備してください。



  それでは、定数の設定から。
#ここから↑は省略
#----- 定数の設定 -----
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

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#キャラクター弾の設定
max_char_tama = 7
char_tama_interval = 5
char_tama_speed = 20
char_tama_h_min = -64

char_tama_hit = createArray()
char_tama_hit[x] = 1;       char_tama_hit[y] = 0
char_tama_hit[w] = 14;      char_tama_hit[h] = 64
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#背景の設定
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_tama_interval」は弾の発射間隔、
 「char_tama_h_min」は弾の移動終了地点のY座標を設定しています。



  続いて、弾の画像の設定です。
#ここから↑は省略

#キャラクター画像の設定
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 = 77342
img_char_tama_name = "img_char_tama"

get[x] = 0;    get[y] = 0;    get[w] = 16;  get[h] = 64
set[x] = 0;    set[y] = 0;    set[w] = 16;  set[h] = 64
set_z = 6
pos_char_tama = createArray()
i = 0
while i < max_char_tama
    pos_char_tama[i] = createArray()
    pos_char_tama[i][x] = -64;  pos_char_tama[i][y] = 600
    i = i + 1
end
setCreateSprite(img_char_tama_name, img_no, get, set,
                set_z, pos_char_tama, max_char_tama)
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#背景画像の設定
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)

#ここから↓は省略

  敵キャラクターと弾の初期値が画面外で重ならないよう、
 念のために別の位置に設定されています。



  次は変数の設定。
#ここから↑は省略

#----- 変数の設定 -----

#キー入力フラグの設定
key_flg_left  = false;      key_flg_right = false
key_flg_up    = false;      key_flg_down  = false
key_flg_z     = false

#アニメーション用カウンター
#キャラクター
char_anime_count = 0

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#キャラクター弾
char_tama_anime_count = createArray()
i = 0
while i < max_char_tama
    char_tama_anime_count[i] = -1
    i = i + 1
end
char_tama_syutugen_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]

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#キャラクター弾の発射間隔カウント
char_tama_interval_count = 0

#キャラクター弾の当たり判定範囲
char_tama_atari = createArray()
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#敵キャラクターの当たり判定範囲
enemy_atari = createArray()

#ここから↓は省略

  今回、キャラクターの弾にはアニメーションがありませんが、
 画面上に出現しているかどうかの判定も兼ねているため、
 こちらの判定処理として利用する理由で、
 「char_tama_anime_count」が設定されています。
  変数の内容は、敵キャラクターの設定と、同じ形になっていますね。



  実際に弾の表示を開始するスクリプトの追加です。
 Zキーが押されたときに、表示を開始します。
#ここから↑は省略
    #----- キャラクターの移動 -----
    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
    
    #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
    #----- キャラクター弾の発射 -----
    if key_flg_z
        char_tama_interval_count = char_tama_interval_count + 1
        if (char_tama_interval_count > char_tama_interval) && 
           (char_tama_syutugen_count < max_char_tama)
            char_tama_interval_count = 0
            char_tama_syutugen_count = char_tama_syutugen_count + 1
            
            #弾の発射
            i = 0
            while i < max_char_tama
                if char_tama_anime_count[i] < 0
                    pos_char_tama[i][x] = pos_char[x] + 24
                    pos_char_tama[i][y] = pos_char[y]
                    char_tama_anime_count[i] = 0
                    
                    i = max_char_tama
                end
                i = i + 1
            end
        end
    end
    
    #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#ここから↓は省略

  「char_tama_interval_count」をカウントし、
 「char_tama_interval」に設定された値に到達したら
 弾を発射するスクリプトに流れます。
  Zキーを押したままでの連射速度を、ここで調整しています。

  弾の発射のスクリプトは、表示の開始地点が
 キャラクターの座標になっているところの他は、
 敵キャラクターを登場させた時と、同じ形になっています。



  最後に、弾の移動と、表示位置の更新。
#ここから↑は省略
                   char_damage = true
                   mainloop = false
                end
            end
        end
        
        i = i + 1
    end
    
    #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
    
    #----- キャラクター弾のアニメーション -----
    i = 0
    while i < max_char_tama
        if char_tama_anime_count[i] > -1
            #キャラクター弾の移動
            pos_char_tama[i][y] = pos_char_tama[i][y] - char_tama_speed
            if pos_char_tama[i][y] < char_tama_h_min
                char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                pos_char_tama[i][x] = -64
                pos_char_tama[i][y] = 600
                char_tama_anime_count[i] = -1
            end
            setSpritePos(img_char_tama_name, pos_char_tama, i)
        end
        
        i = i + 1
    end
    #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
    
    #----- 画面の更新 -----
    drawCanvas()
    
    waitTime(30)
end

#ここから↓は省略

  弾の移動方向はY座標のマイナス、つまり、上に向かって移動するように
 変更されています。
  これに伴い、画面外に到達したかどうかの判定も、
 設定されたY座標より小さくなったかどうかで判定しています。

  また、初期値の座標が画面外左下に変更されています。



  ここまでで、キャラクターの弾が表示されるようになりました。
 完成したら、テストプレーを行ってみましょう。



05-02 弾に当たり判定を付けよう




  発射した弾が敵キャラクターに当たり、
 敵キャラクターが倒せるようにしてみましょう。

  基本的には敵キャラクターの当たり判定を追加したときと同じですが、
 敵キャラクターと弾は、それぞれ複数ありますので、ループを2つ使用します。


  まずは、敵キャラクターの当たり判定を追加したときに使用した変数を
 弾の当たり判定の時にも、ついでに使用できるように、
 敵キャラクターの数だけ配列で増やしましょう。
#ここから↑は省略

#キャラクターの当たり判定範囲
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]

#キャラクター弾の発射間隔カウント
char_tama_interval_count = 0

#キャラクター弾の当たり判定範囲
char_tama_atari = createArray()

#_/_/_/_/_/_/_/_/_/_/_/_/ 変更分 _/_/_/_/_/_/_/_/_/_/_/_/
#敵キャラクターの当たり判定範囲
enemy_atari = createArray()
i = 0
while i < max_enemy
    enemy_atari[i] = createArray()
    i = i + 1
end
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#ここから↓は省略

  二次元配列の0番目には敵キャラクターの番号、
 1番目には座標が入ります。



  これにあわせて、敵キャラクターの当たり判定を入れる
 スクリプトを変更します。
#ここから↑は省略

            #敵キャラクターの移動
            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[i][x] = pos_enemy[i][x] + enemy_hit[x]
            enemy_atari[i][y] = pos_enemy[i][y] + enemy_hit[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[w]) > (enemy_atari[i][x])) && 
               ((char_atari[h]) > (enemy_atari[i][y])) && 
               ((char_atari[x]) < (enemy_atari[i][w])) && 
               ((char_atari[y]) < (enemy_atari[i][h]))
               
               char_damage = true
               mainloop = false
            end
            #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#ここから↓は省略




  変更した敵キャラクターの当たり判定を使用して、
 弾の当たり判定と比較します。
#ここから↑は省略

        if char_tama_anime_count[i] > -1
            #キャラクター弾の移動
            pos_char_tama[i][y] = pos_char_tama[i][y] - char_tama_speed
            if pos_char_tama[i][y] < char_tama_h_min
                #弾を初期値に戻す
                char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                pos_char_tama[i][x] = -64
                pos_char_tama[i][y] = 600
                char_tama_anime_count[i] = -1
            end
            setSpritePos(img_char_tama_name, pos_char_tama, i)
            
            #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
            #キャラクター弾の当たり判定範囲
            char_tama_atari[x] = pos_char_tama[i][x] + char_tama_hit[x]
            char_tama_atari[y] = pos_char_tama[i][y] + char_tama_hit[y]
            char_tama_atari[w] = char_tama_atari[x] + char_tama_hit[w]
            char_tama_atari[h] = char_tama_atari[y] + char_tama_hit[h]
            
            #敵キャラクターの数だけループ
            j = 0
            while j < max_enemy
                if (enemy_anime_count[j] > -1) && 
                   (enemy_anime_count[j] < (enemy_anime_change * 4))
                    #敵キャラクターの当たり判定範囲
                    
                    #当たり判定のチェック
                    if ((char_tama_atari[w]) > (enemy_atari[j][x])) && 
                       ((char_tama_atari[h]) > (enemy_atari[j][y])) && 
                       ((char_tama_atari[x]) < (enemy_atari[j][w])) && 
                       ((char_tama_atari[y]) < (enemy_atari[j][h]))
                       
                       #弾を初期値に戻す
                       char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                       pos_char_tama[i][x] = -64
                       pos_char_tama[i][y] = 600
                       char_tama_anime_count[i] = -1
                       setSpritePos(img_char_tama_name, pos_char_tama, i)
                       
                       j = max_enemy
                    end
                end
                j = j + 1
            end
            #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
        end

#ここから↓は省略




  敵キャラクターに弾が当たった後の、敵キャラクターの動きを設定します。
 敵キャラクターのアニメーション用変数を、
 次のように変化させることで、現在の状態を判断します。



  それでは、敵キャラクターに弾が当たったときに、
 アニメーションカウンターがダウン中の状態へ、
 スキップするように変更しましょう。
#ここから↑は省略

                    #当たり判定のチェック
                    if ((char_tama_atari[w]) > (enemy_atari[j][x])) && 
                       ((char_tama_atari[h]) > (enemy_atari[j][y])) && 
                       ((char_tama_atari[x]) < (enemy_atari[j][w])) && 
                       ((char_tama_atari[y]) < (enemy_atari[j][h]))
                       
                       #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
                       #敵キャラクターのアニメーションカウンターを
                       #ダウン中に変更
                       enemy_anime_count[j] = (enemy_anime_change * 4)
                       #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
                       
                       #弾を初期値に戻す
                       char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                       pos_char_tama[i][x] = -64
                       pos_char_tama[i][y] = 600
                       char_tama_anime_count[i] = -1
                       setSpritePos(img_char_tama_name, pos_char_tama, i)
                       
                       #効果音
                       se_id = playSound(se_hit);  setSoundVolume(se_id, se_vol)
                       
                       j = max_enemy
                    end

#ここから↓は省略



  次は、敵キャラクターのアニメーションのスクリプト。
 「enemy_anime_count」でダウン中かどうか判断し、処理を分岐させて、
 ダウン中のアニメーション表示の切り替えを実行します。
#ここから↑は省略

        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 * 4)
                #敵キャラクターのダウン中
                
                #点滅表示する処理
                if (enemy_anime_count[i] % 2) == 0
                    setEnemySpritePattern(4, i)
                else
                    setEnemySpritePattern(0, i)
                end
                
                #一定時間経過したら、初期値へリセット
                if enemy_anime_count[i] > (enemy_anime_change * 10)
                    #敵キャラクターを初期値に戻す
                    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)
            else
            #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
                #敵キャラクターの移動中
                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)
                
                #敵キャラクターの当たり判定範囲
                enemy_atari[i][x] = pos_enemy[i][x] + enemy_hit[x]
                enemy_atari[i][y] = pos_enemy[i][y] + enemy_hit[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[w]) > (enemy_atari[i][x])) && 
                   ((char_atari[h]) > (enemy_atari[i][y])) && 
                   ((char_atari[x]) < (enemy_atari[i][w])) && 
                   ((char_atari[y]) < (enemy_atari[i][h]))
                   
                   char_damage = true
                   mainloop = false
                end
            #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
            end
            #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
        end

#ここから↓は省略

  敵キャラクターを点滅表示させる処理は、
 「enemy_anime_count[i]」を2で割ったとき、余りが出たときに
 setEnemySpritePatternが「0」、つまり、非表示にすることで
 表示を点滅させています。

  ダウン中かどうかの判定をするif文のendの位置が離れているため、
 スクリプトの書き忘れに注意してください。



  ここまでで、敵キャラクターが弾で倒せるようになりました。
 完成したら、テストプレーを行ってみましょう。



05-03 音楽や効果音を鳴らそう




  これまでのスクリプトで、シューティングゲームとしての動きは
 一通り揃いましたが、音が出ないと少し寂しいですね。

  そこで、ゲーム中の音楽の再生と、敵を倒したときに効果音を再生するよう、
 スクリプトを追加してみましょう。


  まずは、使用する音楽と効果音の素材の準備です。
 今回は、事前に使用許可をいただきました、
 助教授さまの音楽素材と、rerofumiさまの効果音素材を利用します。


効果音


zako_hit03


  第02回を参考に、クリップをしたら、リソースエディタを開いてください。

  今回は、音楽と効果音をリソースに追加しますので、
 リソースエディタのメニューを音楽、効果音に変更してから
 クリップから追加を押します。


 後の流れは、画像のときと同じです。



  それでは、スクリプトに書いてみましょう。
 まずは定数の設定から。
#ここから↑は省略

#敵キャラクターの設定
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

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#音楽・効果音の設定
bgm_main = 77253

bgm_vol = 0.7

se_hit = 63622

se_vol = 1
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#----- 画像の設定 -----
get = createArray()
set = createArray()

#ここから↓は省略

  「bgm_main」、「se_hit」は各素材のID番号、
 「bgm_vol」、「se_vol」は再生するときの音量を設定しています。



  次は、効果音の事前準備とBGMの再生開始。
#ここから↑は省略

#敵キャラクターの当たり判定範囲
enemy_atari = createArray()
i = 0
while i < max_enemy
    enemy_atari[i] = createArray()
    i = i + 1
end

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#効果音の事前準備
se_id = playSound(se_hit);  setSoundVolume(se_id, 0)

#音楽の再生開始
playBGM(bgm_main);  setMusicVolume(bgm_vol)
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#画面の更新
drawCanvas()
setCanvasVisible(true)

#ここから↓は省略

  「playSound」関数で、効果音の再生を行います。
 「setSoundVolume」関数は、効果音の再生時に取得した変数を引数に渡すことで
 効果音の再生音量を設定します。
  効果音を事前に音量0で再生しておくことで、
 実際に再生するタイミングでラグが発生しないようにしています。

  「playBGM」関数は、音楽の再生を行います。
 「setMusicVolume」関数は、
 再生中の音楽の再生音量を設定します。



  敵を倒したタイミングで効果音を再生します。
#ここから↑は省略

                    #当たり判定のチェック
                    if ((char_tama_atari[w]) > (enemy_atari[j][x])) && 
                       ((char_tama_atari[h]) > (enemy_atari[j][y])) && 
                       ((char_tama_atari[x]) < (enemy_atari[j][w])) && 
                       ((char_tama_atari[y]) < (enemy_atari[j][h]))
                       
                       #敵キャラクターのアニメーションカウンターを
                       #ダウン中に変更
                       enemy_anime_count[j] = (enemy_anime_change * 4)
                       
                       #弾を初期値に戻す
                       char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                       pos_char_tama[i][x] = -64
                       pos_char_tama[i][y] = 600
                       char_tama_anime_count[i] = -1
                       setSpritePos(img_char_tama_name, pos_char_tama, i)
                       
                       #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
                       #効果音
                       se_id = playSound(se_hit);  setSoundVolume(se_id, se_vol)
                       #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
                       
                       j = max_enemy
                    end

#ここから↓は省略




  最後に、ゲーム終了前に音楽を停止します。
#ここから↑は省略

endInput()     #入力受付の終了

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
fadeOutMusicStop(500)  #音楽の停止
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

if char_damage
    goBadEnding()  #ゲームオーバー
else
    goEnding()     #ゲームのクリア
end

  「fadeOutMusicStop」関数は、音楽をフェードアウトさせながら停止します。
 引数はフェードアウトする時間をミリ秒で指定します。



  ここまでで、音楽と効果音が再生されるようになりました。
 完成したら、テストプレーを行ってみましょう。



05-04 ゲームクリアの条件を表示しよう




  このままゲームオーバーになるまでエンドレス、という
 ゲームの種類もありますが、今回は一定数の敵キャラクターを撃破したとき
 ゲームクリアとなるようにします。

  同時に、現在の撃破数が分かるように、
 テキストの表示も行ってみましょう。



  まずは、使用する定数の準備から。
#ここから↑は省略

#敵キャラクターの設定
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

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#残撃破数の設定
gekiha_max = 30
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#音楽・効果音の設定
bgm_main = 77253

bgm_vol = 0.7

se_hit = 63622

se_vol = 1

#ここから↓は省略

  「gekiha_max」にゲームクリアの条件となる撃破数を設定しています。



  続いて、撃破数を表示するためのテキストボックスを準備します。
#ここから↑は省略
setCreateSprite(img_enemy_name, img_no, get, set,
                set_z, pos_enemy, max_enemy)

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#----- テキストボックスの設定 -----
#残撃破数の設定
setTextFontSize(25)
setTextFontColor(200, 255, 220)

set[x] = 620;  set[y] = 11;   set[w] = 180;  set[h] = 27
text_zan = createText(set[x], set[y], set[w], set[h])
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#----- 変数の設定 -----

#キー入力フラグの設定
key_flg_left  = false;      key_flg_right = false
key_flg_up    = false;      key_flg_down  = false
key_flg_z     = false
#ここから↓は省略

  「setTextFontSize」関数はテキストボックスのフォントサイズを設定
 「setTextFontColor」関数はテキストボックスの文字色を設定しています。
 文字色は、「赤, 緑, 青」の順にそれぞれ、「0~255」の値で指定します。
 これを「カラーコード」と呼びます。
  なお、このカラーコードにつきましては、ikosamiさまがカラーコードを調べることができる
 ゲームを製作、公開されています。
カラーコード作成ツール - 【ノベルゲーム】

  最後に、「createText」関数でテキストボックスを作成しています。
 引数はスクリプトに書いたとおり、「X座標, Y座標, 横幅, 高さ」となっています。



  残り撃破数のカウンターの変数の準備と、
 ゲーム開始前にテキストの初期表示を行います。
#ここから↑は省略
#敵キャラクターの当たり判定範囲
enemy_atari = createArray()
i = 0
while i < max_enemy
    enemy_atari[i] = createArray()
    i = i + 1
end

#_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
#残撃破数の設定
gekiha_count = gekiha_max


#残撃破数の初期表示
str = "残り撃墜数 "
if gekiha_count < 10
     str = str + "0"
end
str = str + gekiha_count
setText(text_zan, str)
#_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/

#効果音の事前準備
se_id = playSound(se_hit);  setSoundVolume(se_id, 0)

#音楽の再生開始
playBGM(bgm_main);  setMusicVolume(bgm_vol)

#ここから↓は省略

  「str」に表示する文字列をセットした後、
 「setText」関数でテキストボックスに文字列をセットしています。



  敵キャラクターを撃破したときに、撃破数カウンターを更新します。
#ここから↑は省略
                       #弾を初期値に戻す
                       char_tama_syutugen_count = char_tama_syutugen_count - 1  #出現カウント
                       pos_char_tama[i][x] = -64
                       pos_char_tama[i][y] = 600
                       char_tama_anime_count[i] = -1
                       setSpritePos(img_char_tama_name, pos_char_tama, i)
                       
                       #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
                       #撃破カウント
                       gekiha_count = gekiha_count - 1
                       if gekiha_count == 0
                           #残撃破が0になったらゲームクリア
                           mainloop = false
                       end
                       #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
                       
                       #効果音
                       se_id = playSound(se_hit);  setSoundVolume(se_id, se_vol)
#ここから↓は省略




  メインループの画面の更新時に、撃破数の表示更新を行います。
#ここから↑は省略
        i = i + 1
    end
    
    #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
    #----- 残撃破数の表示 -----
    str = "残り撃墜数 "
    if gekiha_count < 10
         str = str + "0"
    end
    str = str + gekiha_count
    setText(text_zan, str)
    #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
    
    #----- 画面の更新 -----
    drawCanvas()
    
    waitTime(30)
end

#ここから↓は省略




  最後に、ゲームクリア、ゲームオーバー時に
 ゲームプレイの履歴を残す関数を実行します。
#ここから↑は省略

endInput()     #入力受付の終了

fadeOutMusicStop(500)  #音楽の停止

if char_damage
    #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
    feedstr = "残念。 残り "
    feedstr = feedstr + gekiha_count
    feedstr = feedstr + "体でした。"
    openActivityFeedWindow(feedstr)
    #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
    
    goBadEnding()  #ゲームオーバー
else
    #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
    feedstr = "見事 "
    feedstr = feedstr + gekiha_max
    feedstr = feedstr + "体撃破しました!"
    openActivityFeedWindow(feedstr)
    #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
    
    goEnding()     #ゲームのクリア
end


  「openActivityFeedWindow」関数は、
 ゲームプレイの履歴を残すかどうかの選択ウインドウを表示、
 履歴の記録を行います。



  スクリプト全体(一部、少し整理しています)

  これで、一通り完成です。
 保存、終了をして、テストプレーを行い、
 指定された数を撃破したとき、ゲームクリアとなるかどうか、
 確認してみましょう。




05-05 おわりに


  いかがでしたでしょうか。
 これで、シューティングゲームとして必要な要素は
 一通り揃いました。

  さて、次回は、いよいよ最終回。
 「より面白くするために」と題しまして、
 更なるテクニックをご紹介します。



  第01回 スクリプトって何?
  第02回 画面にキャラクターを描画する
  第03回 キャラクターをキー入力で操作する
  第04回 敵キャラクターを登場させる
  第05回 弾を発射させる
  第06回 より面白くするために

コメントする

コメントするには、ログインする必要があります。

コメント一覧

User icon mini 退会したユーザー(投稿日:2011/08/12 18:29, 履歴)
第6回で挫折したから5で終わりにしとこ
Cdv30200 aoi icon mini aoihikawa(投稿日:2011/08/09 13:20, 履歴)
>takumi2310さま

ゲームのクリア条件も変更されていて、
良いアレンジと思います。

攻撃の使い分けが、ハイスコア狙いの鍵となる
面白いアイデアですね(w
User icon mini 退会したユーザー(投稿日:2011/08/09 12:33, 履歴)
テストシューティング
今回はかなり本格的にアレンジしました^^

ID:takumi2310
パス:0132
User icon mini 退会したユーザー(投稿日:2011/08/09 09:48, 履歴)
弾の色違いをどう使うのかが気になる・・・!
Material 7186 1 mini ikosami(投稿日:2011/08/08 23:55, 履歴)
去年作ったSPACE BUSTERも、ただ敵機を倒すだけなので、
次回の「より面白くするために」ってのは興味ありますね(^^)
Material 71926 1 mini なとおとき(投稿日:2011/08/08 21:56, 履歴)
おお、まだじかいがありましたか、
スプリクト改造させていただいております。
次回も楽しみです。
User icon mini 退会したユーザー(投稿日:2011/08/08 21:19, 履歴)
キターーーーーーーーーーーー