スクリプト/RmakeでACTゲームをつくろう / 第01回 関数を再利用してみよう
      最終投稿者:
 aoihikawa
      更新:2013/04/01 16:28:26
    
    RmakeでACTゲームをつくろう
 第01回 関数を再利用してみよう
こんにちは。
フリーデザイナープログラマー(自称)の
簸川 葵(ひかわ あおい)と申します。
前回、Rmakeで自由なゲームをつくろう の連載では
スクリプトについての基本を学びながら、
シューティングゲーム(STG)をつくってみました。
今回はこのSTGを応用して
アクション(ACT)ゲームを作ってみましょう。
第01回は「関数を再利用してみよう」
というところから始めていきますね。
01-01 前回までのおさらい
Rmakeのゲームは絵や音楽などの素材と、
それをどのように動かすか指示することができる「スクリプト」
の組み合わせで出来ています。
このスクリプトを作り込むことで、
様々なゲームを作り出すことが出来ますが、
規模が大きくなってくるほど、沢山のスクリプトを
書く必要がでてくるため、大変になってきます。
しかし、前回の第1回にて解説いたしました、
自作の「関数」を利用することで、スクリプトを書く量を
ぐっと減らすことができます。
関数とは、処理を代行してくれる便利な纏まりのことです。
例えば、画像を表示したり、アニメーションさせたり、
当たり判定を行ったり、という内容はSTGでもACTでも変わりません。
こういった処理を自作の「関数」で行っている場合、
この関数をコピーしてくる(移植と呼びます)だけで、
同じ処理が行えるようになるわけです。
さて、それでは実際にスクリプトや関数の移植から始めてみましょう。
01-02 必要なスクリプトを移植しよう
第06回 より面白くするために のスクリプトから
まずは、そのまま利用できる関数を移植します。
#メニュー項目等の表示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
続いて、メイン処理の基盤部分を移植します。
場所は先ほどのスクリプトのすぐ後ろです。
#----- 定数の設定 -----
#FPS管理の設定
draw_setting = 30 #ゲームのメイン処理実行タイミングを設定(ミリ秒)
#----- 変数の設定 -----
#FPS管理の設定
fps = 0
fpscount = 0
oldfpstime = 0
draw_count = 0
olddrawtime = 0
draw_flg = false
#キー入力フラグの設定
key_flg_left  = false;      key_flg_right = false
key_flg_up    = false;      key_flg_down  = false
key_flg_z     = false
#画面の更新
drawCanvas()
setCanvasVisible(true)
setBaseTime()    #時間計測の開始
startInput()     #入力受付の開始
#メインループの開始
mainloop = true
while mainloop
    
    #----- FPSの計測と判定 -----
    timer = getTime() #差分の時間を取得
     
    fps = fps + 1 #FPSのカウント
    fpscount = timer - oldfpstime
     
    if fpscount < (draw_setting * fps)
        draw_flg = true #最低限のFPSを満たしている場合描画OK
    else 
        #最低限のFPSを満たしていない場合、前回描画したかどうか
        if draw_flg
            draw_flg = false
        else
            draw_flg = true
        end
    end
    
    if fpscount > 999
        #1秒を超えたらFPSのカウントをリセットする
        fps = 0
        oldfpstime = timer
        fpscount = fpscount % 1000
    end
    
    #----- ゲームのメイン処理実行判定 ----- 
    draw_count = timer - olddrawtime #メイン処理実行タイミングのカウント
    
    if draw_setting < draw_count 
        #ゲームのメイン処理実行タイミングになっていたら、カウントをリセットする
        olddrawtime = timer
        draw_count = draw_count % draw_setting
        
        
        #キー入力の判定
        while hasInput()
            takeInput()
            #----- キー入力の判定処理を入れる場所 -----
            if isKeyDown("LEFT")
                key_flg_left = true
            elsif isKeyUp("LEFT")
                key_flg_left = false
            elsif isKeyDown("RIGHT")
                key_flg_right = true
            elsif isKeyUp("RIGHT")
                key_flg_right = false
            elsif isKeyDown("UP")
                key_flg_up = true
            elsif isKeyUp("UP")
                key_flg_up = false
            elsif isKeyDown("DOWN")
                key_flg_down = true
            elsif isKeyUp("DOWN")
                key_flg_down = false
            elsif isKeyDown("Z")
                key_flg_z = true
            elsif isKeyUp("Z")
                key_flg_z = false
            end
        end
        
        #----- ゲームのメイン処理を入れる場所 -----
        #(ゲームの終了時はmainloopをfalseに)
        
        
        
        
        
        #----- 画面の更新 -----
        if draw_flg
            drawCanvas() #描画OKならキャンバスを更新 
        end
    else
        waitTime(1) #ゲームのメイン処理実行タイミングになるまで保留 
    end
end
endInput()     #入力受付の終了
これで、一通り基盤部分が完成しました。
01-03 チャプターで分割してみよう
スクリプトの量が増えてくると、修正したい箇所やエラーの発生した箇所が
探しにくくなってきます。
これまでは、1つのチャプターに全てのスクリプトを書いてきましたが、
複数のチャプターにスクリプトを分割することで、これを解消することができます。
チャプターについてもスクリプトと同様、上から順に流れるため、
関数などを1つめのチャプター、メイン処理などを2つめのチャプターというように、
スクリプトの流れ順に分割します。
チャプターを追加します。
追加したチャプターに初期スクリプトを書きます。
#メニュー項目等の表示OFF setMenuItemVisible(getMenuBackLog(), false) setMenuItemVisible(getMenuSave(), false) setMenuItemVisible(getMenuLoad(), false) setHelpVisible(false)
01-02の後半部分のスクリプトを切り取り、
追加したチャプターに貼り付けます。
今回は関数とメイン処理で分けたため、すんなりと分割できましたが、
チャプターを分割した場合、ローカル変数は引継ぎされないという点に
注意する必要があります。
ローカル変数を受け渡しする場合、通常変数に変更するか、
関数の引数や戻り値の仕組みを利用するように変更しましょう。
01-04 カスタマイズしながら移植してみよう
キャラクターと背景を描画する仕組みをつくります。
今回もまた、お手軽にスクリプトの作成までできるよう、
サンプルの素材を準備いたしました。
なお、BGMにつきましては助教授さまの音楽素材を利用いたします。
こちらを参考に、クリップからリソースへの登録まで行い、
すぐにスクリプトで利用できるように、準備してください。
まずはチャプター0にて、関数の追加から。
#ここから↑は省略
#キャラクターの表示内容を変更する関数
def setCharSpritePattern(no)
    img_char_name = "img_char"
    get_x = 0;    get_y = 0;    get_w = 96;   get_h = 96
    set_x = 0;    set_y = 0;    set_w = 96;   set_h = 96
    
    if no == 1
        get_x = 0;    get_y = 0
    elsif no == 2
        get_x = 96;   get_y = 0
    elsif no == 3
        get_x = 192;  get_y = 0
    elsif no == 4
        get_x = 288;  get_y = 0
    elsif no == 5
        get_x = 384;  get_y = 0
    elsif no == 6
        get_x = 480;  get_y = 0
    elsif no == 7
        get_x = 576;  get_y = 0
    elsif no == 8
        get_x = 672;  get_y = 0
    elsif no == 9
        get_x = 768;  get_y = 0
    elsif no == 10
        get_x = 864;  get_y = 0
    elsif no == 11
        get_x = 0;    get_y = 96
    elsif no == 12
        get_x = 96;   get_y = 96
    elsif no == 13
        get_x = 192;  get_y = 96
    elsif no == 14
        get_x = 288;  get_y = 96
    elsif no == 15
        get_x = 384;  get_y = 96
    elsif no == 16
        get_x = 480;  get_y = 96
    elsif no == 17
        get_x = 576;  get_y = 96
    elsif no == 18
        get_x = 672;  get_y = 96
    elsif no == 19
        get_x = 768;  get_y = 96
    elsif no == 20
        get_x = 864;  get_y = 96
    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
内容は、STGにもありました、
キャラクターの表示内容を変更する関数と同様です。
画像サイズと、アニメーションの画像数分、
if文による分岐が追加されています。
次はチャプター1にて、実際の描画処理を追加します。
まずは、初期設定から。
#ここから↑は省略 #----- 定数の設定 ----- #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ x = 0; y = 1; w = 2; h = 3 act_std = 0; act_wrk = 1; act_jmp = 2; act_dmg = 3 #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #FPS管理の設定 draw_setting = 30 #ゲームのメイン処理実行タイミングを設定(ミリ秒) #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/ #キャラクターの設定 char_speed = 7 char_w_max = 800 - 63; char_h_max = 600 - 80 char_anime_change = 6 char_hit = createArray() char_hit[x] = 30; char_hit[y] = 10 char_hit[w] = 33; char_hit[h] = 80 #音楽・効果音の設定 bgm_main = 66498 bgm_vol = 0.7 #----- 画像の設定 ----- get = createArray() set = createArray() #キャラクター画像の設定 img_no = 87833 img_char_name = "img_char" get[x] = 0; get[y] = 96; get[w] = 96; get[h] = 96 set[x] = 0; set[y] = 0; set[w] = 96; set[h] = 96 set_z = 7 pos_char = createArray() pos_char[x] = 96; pos_char[y] = 478 setCreateSprite(img_char_name, img_no, get, set, set_z, pos_char) setSpriteIndependentCamera(getVariable(img_char_name), true) #背景画像の設定 img_no = 79101 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[x] = 0; pos_bg[y] = 0 setCreateSprite(img_bg_name, img_no, get, set, set_z, pos_bg) setSpriteIndependentCamera(getVariable(img_bg_name), true) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #----- 変数の設定 ----- #FPS管理の設定 fps = 0 fpscount = 0 oldfpstime = 0 draw_count = 0 olddrawtime = 0 draw_flg = false #キー入力フラグの設定 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_muki = 1 char_act = act_std #キャラクターの当たり判定範囲 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] #音楽の再生開始 playBGM(bgm_main); setMusicVolume(bgm_vol) #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/ #ここから↓は省略
基本な構造はSTGのから変更はありませんが、
画像ID、音楽IDの変更と、
新たにsetSpriteIndependentCamera関数が追加されています。
setSpriteIndependentCamera関数は、
カメラ移動に連動させて画像を動かすかどうかを設定します。
今回は「true」つまり、カメラが移動しても画像も連動して移動するため、
カメラの位置にとらわれず、常に同じ位置に表示されるようになります。
キー入力による座標の移動をメインループ内に追加します。
#ここから↑は省略
        #----- ゲームのメイン処理を入れる場所 -----
        #(ゲームの終了時はmainloopをfalseに)
        
        #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
        
        #----- キャラクターの移動 -----
        if key_flg_left
            #左
            pos_char[x] = pos_char[x] - char_speed
            char_muki = 0
            char_act = act_wrk
        elsif key_flg_right
            #右
            pos_char[x] = pos_char[x] + char_speed
            char_muki = 1
            char_act = act_wrk
        else
            char_act = act_std
        end
        
        #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
        
#ここから↓は省略
変数「char_muki」はキャラクターの方向、
「char_act」はキャラクターの状態を格納しています。
これらの変数の状態によって、
アニメーション種類の切り替えを行います。
最後に、アニメーション処理をメインループ内に追加します。
先ほどのスクリプトのすぐ下です。
#ここから↑は省略
        #_/_/_/_/_/_/_/_/_/_/_/_/ 追加分 _/_/_/_/_/_/_/_/_/_/_/_/
        #----- キャラクターのアニメーション -----
        
        #アニメーション用カウンター
        char_anime_count = char_anime_count + 1
        if char_anime_count == (char_anime_change * 4)
            char_anime_count = 0
        end
        
        #キャラクターの表示を切替
        if char_act == act_wrk
            if char_anime_count < (char_anime_change)
                setCharSpritePattern(3 + (char_muki * 10))
            elsif char_anime_count < (char_anime_change * 2)
                setCharSpritePattern(4 + (char_muki * 10))
            elsif char_anime_count < (char_anime_change * 3)
                setCharSpritePattern(5 + (char_muki * 10))
            else
                setCharSpritePattern(6 + (char_muki * 10))
            end
        else
            if char_anime_count < (char_anime_change * 2)
                setCharSpritePattern(1 + (char_muki * 10))
            else
                setCharSpritePattern(2 + (char_muki * 10))
            end
        end
        
        #キャラクターの当たり判定範囲
        if key_flg_left || key_flg_right
            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]
            
            if pos_char[x] < -(char_hit[x])
                pos_char[x] = -(char_hit[x])
            elsif pos_char[x] > char_w_max
                pos_char[x] = char_w_max
            end
            setSpritePos(img_char_name, pos_char)
        end
        
        #_/_/_/_/_/_/_/_/_/_/_/_/ここまで_/_/_/_/_/_/_/_/_/_/_/_/
        
        #----- 画面の更新 -----
        if draw_flg
            drawCanvas() #描画OKならキャンバスを更新 
        end
#ここから↓は省略
アニメーションのカウンターと種類を元に
キャラクターを描画する関数の変数を変更し、画像を切り替えています。
また、キャラクターの当たり判定を元に、
キャラクターを画面内で移動させています。
スクリプト全体
これで、一通り完成です。
保存、終了をして、テストプレーを行い、
背景とキャラクターの描画、キャラクターの移動が行えるか
確認してみましょう。
01-05 おわりに
いかがでしたでしょうか。
このように、移植の仕方やコツを理解できれば、
以前の作品を元にして、簡単に新しいゲームを作成することができます。
また、他の方が作成された関数やスクリプトも、
効率的に利用できるようになります。
さらに、その仕組みを理解することができれば、
アレンジも自由自在です。
さて、次回は新しい関数を利用して、
「マップを表示してみよう」を実践してみましょう。
第01回 関数を再利用してみよう
第02回 マップを表示してみよう
第03回 敵・アイテムを追加してみよう
第04回 敵の動きや背景の演出を入れてみよう
番外 外部ツールと連携してみよう
この記事についてご質問等がありましたら
こちらのブログ記事のコメントへご投稿、
よろしくお願いいたします。
コメントする
コメントするには、ログインする必要があります。
う~ん・・・ギコのデザインとか作ったあとはこれのどうとかどうやってとか・・・