JavaScript Maniax

■シューティングゲームをつくる その1

まずはシューティングゲームの自機の動きを再現します。
基礎編で学習した内容で、
・キー判定
・タイマーをつかった再帰処理
・指定した位置に文字表示
が出来るようになりました。
シューティングゲームの自機は、キーを押した方向に移動してくれればよいわけですから、「キー判定」⇒「座標計算」⇒「文字表示」というロジックを、「タイマー」をつかって定期的におこなってやることで、キーによって動く自機を表示させることが出来ます。

思いつくままにプログラミングしてみましょう。
<SCRIPT language="javascript">
var mx, my;
mx=100;
my=100;
kCode=new Array(256);
for (i=0;i<256;i++){
    kCode[i]=0;
}
function keyDown(){
    kCode[event.keyCode]=1;
}
function keyUp(){
    kCode[event.keyCode]=0;
}
function main(){

    if (kCode[38]) my-=5;
    if (kCode[37]) mx-=5;
    if (kCode[40]) my+=5;
    if (kCode[39]) mx+=5;

    text="text01"
    document.all.item(text).style.left=mx;
    document.all.item(text).style.top=my;

    window.setTimeout("main()",50)
}
document.onkeydown = keyDown;
document.onkeyup = keyUp;
</SCRIPT>
あとはBODYタグにonLoad="main()"と書いて呼び出すだけです。
やっていることは単純です。
キーコードを元に、
・カーソルキーの↑(keyCode=38)が押されていたらy座標を−5
・カーソルキーの←(keyCode=37)が押されていたらx座標を−5
・カーソルキーの↓(keyCode=40)が押されていたらy座標を+5
・カーソルキーの→(keyCode=39)が押されていたらx座標を+5
と計算し、その座標にキャラクタを表示しています。

[
sample-a] [DL]


無事、キー入力のとおりキャラクタを動かすことができました!



応用編

さて、無事に言うことを聞くようになった文字ですが、残念乍らこれではシューティングゲームの自機とは呼び難いものがあります。
このカクカクの動きはどうにかならないものでしょうか?

そこで、座標計算のロジックを修正してみます。
本格的なものにするには加速度や重力、空気抵抗に慣性、磁力や電力云々と膨大な計算が必要になってしまいますが、慣性の法則を取り入れるだけでかなりスムーズな動きをするようになります。

慣性の法則はゲームで言えばつまり「飛行機は急にはとまれないし急には動けない」という事です。
この再現方法はいろいろありますが、自分が良く使用する方法を記載します。

上記サンプルでは、キーを押した瞬間に移動距離を算出、それを現座標に加算という処理をしていました。
新しいサンプルでは、新たに目標速度および現在の移動速度を変数としてもたせました。
処理の流れとしては、

・キーが押される(例えば[→]キー)と、目標速度を設定します(例えば右に10px)
メインの関数では、現在の移動速度(初期値は0)と目標速度を比較し、目標速度に少しづつ近づけます。
・実際の座標には現在の移動速度を加算します。

これをもとに以下の関数では、横(x)軸、縦(y)軸それぞれに、目標速度(vx,vy)を設定し、現在の移動速度(ax,ay)を計算して動作するよう作成されています。
//--sample--
function move(){
    //目標速度の設定
    if(kCode[38]>kCode[40]){           //↑(38)が押してあって↓(40)が押していない時
        vy=-10;
    } else if(kCode[38]<kCode[40]){    //↑(38)が押していなくて↓(40)が押してある時
        vy=10;
    } else {                           //↑(38)と↓(40)が共に押してある、もしくは共に押していない時
        vy=0;
    }
    if(kCode[37]>kCode[39]){           //←(37)が押してあって→(39)が押していない時
        vx=-10;
    } else if(kCode[37]<kCode[39]){    //←(39)が押していなくて→(40)が押してある時
        vx=10;
    } else {                           //←(37)と→(39)が共に押してある、もしくは共に押していない時
        vx=0;
    }

    //現移動速度の設定
    if(ax<vx){
        ax+=2;
    } else if(ax>vx){
        ax-=2;
    }
    if(ay<vy){
        ay+=2;
    } else if(ay>vy){
        ay-=2;
    }

    //現座標の計算
    mx+=ax;
    my+=ay;
}
//--sample--
vx,vy,ax,ayはグローバル変数にするのを忘れないようにしてください。
あとは、上記関数をメイン関数から呼ぶようにすれば移動処理の完成です。
ちなみにこのSampleには上記に記載していない裏技を仕込んであります。探してみてください

[sample-b] [DL]
[top] [index]
トップメニュー 基礎編 実践編 外部リンク