Skip to content

shi3z式ゲームプログラミング入門 #2 あと48時間でゲームプログラマになる方法

やあみんな。shi3zだよ。

三日間の短期集中連載だからガンガンポストしていくよ。

さて、前回の最後のプログラムは実行してみたかな?
マウスカーソルに不思議な動きで宇宙船がついてくるね。

この動きの秘密は、もちろんプログラムにある。


       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
                this.x += (mouseX-this.x)/10;
                this.y += (mouseY-this.y)/10;
       };  

ひとつずつ解説しよう。

(続きは以下から)

まず、this.xのあとに続く記号、+=は、this.xに右の式の値を足し込むという意味になる。
this.x+=1だと、this.x=this.x+1と同じ意味になるわけ。これはゲームでは異常によく使う記号だから覚えておこう。

次に、mouseXという謎の変数が突然出てくる。
これはお察しの通り、僕の作った最速ゲーム学習用システムが用意している変数だ。

この変数には常にマウスカーソルのX座標が格納されている。
ではmouseYには・・・そう。マウスカーソルのY座標だ。

この式は、mouseXからthis.xを引いた値を10で割ったものをthis.x自身に足し込んでる。

これは一体どういうことなのか?

まず、プログラムとしてはマウスカーソルに宇宙船を近づけたい。
それにはいくつか別のもっとわかりやすい方法もある。

例えば次のようなプログラムだ。


       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
            if(this.x > mouseX) this.x-=10;
            if(this.x < mouseX) this.x +=10;                if(this.y > mouseY) this.y-=10;
            if(this.y < mouseY) this.y +=10;
       };  

こんどは動きはどう変わっただろうか?前回のコードではヌルっという動きでマウスカーソルをまっすぐ追いかけた。

今回のコードでは斜めにしばらく進んだ後、横または縦方向にまっすぐカーソルを追いかけてくるようになるはずだ。

この動きの差はどうしてうまれるのか?すべての秘密はソースコードにある。

前回示したコードより、後者のif文を沢山使ったコードのほうが理解しやすいはずだ。

もし、自分の位置(this.xとthis.y)がマウスの位置と違ったら、それぞれ10ドットずつ移動しろ、という命令を書いているわけだね。

けれども、カーソルがたとえば45度以外の斜め方向に居るとき、x、yの増加量はともに10ずつとなって、結局斜め45度の動きになってしまう。

この動きは非常にぎこちなく、なんだか変な感じだ。

 

それにくらべると、最初の例に用いた式は、シンプルだが効果的だ。

この数式がどういう動きを生み出すのか。下の図を見てほしい。

マウスカーソルの座標から宇宙船の現在座標を引くと、これは宇宙船からマウスカーソルへ伸びるベクトルになる。

これを足すと、宇宙船がいきなりマウスカーソルの位置にワープすることになる。

これはもっとシンプルなプログラムで試すことができる。


       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
                this.x += mouseX-this.x;
                this.y += mouseY-this.y;
       };  

10で割るのをやめてみると、いきなり宇宙船がマウスカーソルに張り付いたような動きになるはずだ。

これを10で割ることで、マウスカーソルに近づけば近づくほど細かい動きになっていき、あの独特のヌルっとした動きになるのだ。

このヌルっとした動きがなんとなく「気持ちよく」感じられるのはなぜだろうか?

 

ひとつはこの動きにリアリティ(現実感)があるからだ。

実は、こうした動きは実際のモノの動きに良く似ている。

クルマは急に止まれない、という言葉があるけれど、本当に急に止まれない。
止まるには少しずつ減速していかないとならない。

全速力で走っていて、急に止まろうとしたら勢いで二三歩余計に歩いてしまう、そんな経験が誰にもあるだろう。

そういう感覚がこうした動きにはあるのだ。

さて、宇宙船しかいなかったらつまらないから、宇宙船以外のものも表示してみよう。

宇宙だから岩がいい。それにはforループを使うのが簡単だ。


function onLoad() {     var ship= new Image('img/starship.png');
       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
                this.x += (mouseX-this.x)/10;
                this.y += (mouseY-this.y)/10;
       };  

       for(i=0;i<10;i++){
              rock = new Image('img/rock.png');
              rock.x = Math.random()*320;
              rock.y = Math.random()*480;
       }
     gameStart();
}

実行すると次のような画面になる。

白い宇宙空間に岩がゴロゴロ。
小惑星、というわけだ。

ところがこの宇宙船、小惑星にぶつかってもびくともしない。
それではつまらないから、小惑星にぶつかったらゲームオーバーになることにしよう。


function onLoad() {
     var ship= new Image('img/starship.png');
       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
                this.x += (mouseX-this.x)/10;
                this.y += (mouseY-this.y)/10;
       };

       ship.onHit = function(){ //衝突した!
              alert("CRASHED!");
       }  

       for(i=0;i<10;i++){
              rock = new Image('img/rock.png');
              rock.x = Math.random()*320;
              rock.y = Math.random()*480;
       }
     gameStart();
}

ただし、これは極めていい加減なプログラムなので、衝突すると「CRASHED」という警告ウィンドウが出続ける。

やめるにはマウスカーソルを正しい位置に逃がして、リロードする必要がある。

alertは、JavaScriptが元々もっている命令(関数)のひとつで、警告ウィンドウを表示する機能を持っている。
ship.onHit関数もまた、システムが呼び出す特別な関数で、なにか他のImageと衝突したときに呼び出される。

この場合、宇宙船(ship)がなにか別の物体とぶつかったとき、警告ウィンドウを表示する、というゲームになったわけだ。

これをもとにして、以下の課題に挑戦してみよう。また次回。次回はすぐだよ

1)rockをforループと乱数を使わずに並べて、電流イライラ棒ゲームを作ってみよう
2)rock.tickを定義して、隕石のほうも動かしてみよう
3)動く隕石と動かない隕石を作ってみよう

このエントリーをはてなブックマークに追加
はてなブックマーク - shi3z式ゲームプログラミング入門 #2 あと48時間でゲームプログラマになる方法
Post to Google Buzz
Share on GREE

Related posts:

  1. shi3z式ゲームプログラミング入門 #1 72時間でゲームプログラマになる方法
  2. かんたんプログラミング #3 関数ってどんな数?

Facebook comments:

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*