キー入力処理を受け付けて、マリオを動かす(プログラムでマリオを作る)

今回は、キーボードからのキー入力処理を受けつけて、マリオを動かして見ます。

キーボードの入力値について

キーボードからのキー入力を受けつている時に使っている数値はDefaultで決められたものです。
これをわかりやすいように、プログラム中で定義していますが、こういうものを定数と呼んでいます。

キーボードのイベント登録について

onload関数内に書いたキーの登録処理
addEventListenerには、それぞれキーが押された時(keydown)
キーが話された時(keyup)に呼ばれる関数の登録をしています。

今回は、それぞれ

keyDown

keyUp

関数としていますが、この命名は任意になります。
onKeyDownなどでもOKですが、
その場合は

function onKeyDown(event){}

として定義する必要があります。

解説

今回は、キーボードの操作を受け付けて
マリオを動かして見たいと思います。

main.jsを開いてください

キーボード処理

まず、キーボードが押されているかどうか判定する変数を定義します。

// key
var gSpacePush = false; // space
var gLeftPush = false;	// left
var gRightPush = false;	// right
var gUpPush = false;	// up
var gDownPush = false;	// down

続いて、キーとして定義されている値をわかりやすいように
定数として定義します。

この番号はブラウザの標準として決められている番号になります。

// keyの定義
var SPACE_KEY = 32;
var LEFT_KEY = 37;
var RIGHT_KEY = 39;
var UP_KEY = 38;
var DOWN_KEY = 40;

続いて、キーボードが押された時に、呼び出す関数を
登録します。

キー入力イベントを登録する

keydown命名がキーが押された時に呼びされる定義名で、その際にkeyDownを呼び出すという意味になります。

// キーの登録
window.addEventListener('keydown', keyDown, true);     
window.addEventListener('keyup', keyUp, true);

マリオをの移動関数を書きます。

キーが入力された際の関数の定義をする

続いて、キーを押した時に呼ばれる関数の定義をします。

/*
	キーを押した時の操作
*/
function keyDown(event) {
	var code = event.keyCode;       // どのキーが押されたか
	switch(code) {
	    // スペースキー
	    case SPACE_KEY:
            	// スクロールさせないため
            	event.returnValue = false;		// ie
            	event.preventDefault();		// firefox
	        gSpacePush = true;
	        break;
	    // ←キー
	    case LEFT_KEY:
	        gLeftPush = true;
	        break;
	    // →キー
	    case RIGHT_KEY:
	        gRightPush = true;
	        break;
	    // ↑キー
	    case UP_KEY:
            	event.returnValue = false;	// ie
            	event.preventDefault();	// firefox
		gUpPush = true;
	        break;
            // ↓キー
	    case DOWN_KEY:
            	event.returnValue = false;	// ie
            	event.preventDefault();	// firefox
	    	gDownPush = true;
	        break;
	}
}

続いて、キーが離された時に呼ばれる関数の定義をします。

/*
	キーを離した時のイベント
*/
function keyUp(event){
	// どのキーが押されたか
	var code = event.keyCode;
	switch(code){
		case SPACE_KEY:
		gSpacePush = false;
		break;
		
		// 左キー
		case LEFT_KEY:
			gLeftPush = false;
			break;

		// 右キー
		case RIGHT_KEY:
			gRightPush = false;
			break;
		// 上キー
		case UP_KEY:
			gUpPush = false;
			break;
		// 下キー
		case DOWN_KEY:
			gDownKey = false;
			break;

	}
}

マリオを動かす

続いて、マリオを動かすためのmove関数を書きます

function move(){
	// 左キーが押されている状態
	if(gLeftPush){
          gMarioPosX -= 4;
	}
	// 右キーが押されている状態
	if(gRightPush){
	  gMarioPosX += 4;
	}
}

マリオを動かすための変数を定義します。

var gMarioPosX = 0;

マリオの位置を動かすために、描画位置が変更されるようにします。

g_Ctx.drawImage(gMarioTex,0,0,24,24,gMarioPosX,gMarioPosY,24,24);

これで、処理を書き終えたのでマリオを移動することができるのか確認して見ましょう。
キーボード操作でマリオを移動させることができました。

今回変更したコード

main.js

var g_Canvas;
var g_Ctx;
var gMarioTex;

// key
var gSpacePush = false; // space
var gLeftPush = false;	// left
var gRightPush = false;	// right
var gUpPush = false;	// up
var gDownPush = false;	// down
// keyの定義
var SPACE_KEY = 32;
var LEFT_KEY = 37;
var RIGHT_KEY = 39;
var UP_KEY = 38;
var DOWN_KEY = 40; 

// マリオを動かすための仮変数
var gMarioPosX = 0;

/**
	onload
	最初に呼び出される関数
*/
onload = function () {
    // キャンバスに代入
    g_Canvas = document.getElementById('id_canvas'); 
    // cavasに対応していない
    if (!g_Canvas || !g_Canvas.getContext) {
        alert("html5に対応していないので、実行できません");
        return false;
    }

    g_Ctx = g_Canvas.getContext('2d');          // ctx
    loadTexture();
    // キーの登録
    window.addEventListener('keydown', keyDown, true);     
    window.addEventListener('keyup', keyUp, true);
    requestNextAnimationFrame(animate);		// loopスタート
};

/*
	テクスチャのロード
*/
function loadTexture(){
	gMarioTex = new Image();
	gMarioTex.src = "resource/main.png";
}

function animate(now) {
    move();
    // 描画
    Draw();
    requestNextAnimationFrame(animate);
}

/*
	60fps毎に処理を実行
*/
window.requestNextAnimationFrame =
(function () {
   var originalWebkitRequestAnimationFrame = undefined,
       wrapper = undefined,
       callback = undefined,
       geckoVersion = 0,
       userAgent = navigator.userAgent,
       index = 0,
       self = this;

   // Workaround for Chrome 10 bug where Chrome
   // does not pass the time to the animation function

   if (window.webkitRequestAnimationFrame) {
      // Define the wrapper

      wrapper = function (time) {
        if (time === undefined) {
           time = +new Date();
        }
        self.callback(time);
      };

      // Make the switch

      originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;

      window.webkitRequestAnimationFrame = function (callback, element) {
         self.callback = callback;

         // Browser calls the wrapper and wrapper calls the callback

         originalWebkitRequestAnimationFrame(wrapper, element);
      }
   }

   // Workaround for Gecko 2.0, which has a bug in
   // mozRequestAnimationFrame() that restricts animations
   // to 30-40 fps.

   if (window.mozRequestAnimationFrame) {
      // Check the Gecko version. Gecko is used by browsers
      // other than Firefox. Gecko 2.0 corresponds to
      // Firefox 4.0.

      index = userAgent.indexOf('rv:');

      if (userAgent.indexOf('Gecko') != -1) {
         geckoVersion = userAgent.substr(index + 3, 3);

         if (geckoVersion === '2.0') {
            // Forces the return statement to fall through
            // to the setTimeout() function.

            window.mozRequestAnimationFrame = undefined;
         }
      }
   }

   return window.requestAnimationFrame   ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame    ||
      window.oRequestAnimationFrame      ||
      window.msRequestAnimationFrame     ||

      function (callback, element) {
         var start,
             finish;


         window.setTimeout( function () {
            start = +new Date();
            callback(start);
            finish = +new Date();

            self.timeout = 1000 / 60 - (finish - start);

         }, self.timeout);
      };
   }
)
();


/*
	Draw
	描画
*/
function Draw(){
	g_Ctx.fillStyle = "rgb(255,0,0)";		// 赤に設定
	g_Ctx.fillRect(0,0,640,480);			// 塗りつぶす
	g_Ctx.drawImage(gMarioTex,0,0,24,24,gMarioPosX,gMarioPosY,24,24);
}

function move(){
	// 左キーが押されている状態
	if(gLeftPush){
		gMarioPosX -= 4;
	}
	// →キーが押されている状態
	if(gRightPush){
		gMarioPosX += 4;
	}

}

/*
	キーを押した時の操作
*/
function keyDown(event) {
	var code = event.keyCode;       // どのキーが押されたか
	switch(code) {
	    // スペースキー
	    case SPACE_KEY:
            	// スクロールさせないため
            	event.returnValue = false;		// ie
            	event.preventDefault();		// firefox
	        gSpacePush = true;
	        break;
	    // ←キー
	    case LEFT_KEY:
	        gLeftPush = true;
	        break;
	    // →キー
	    case RIGHT_KEY:
	        gRightPush = true;
	        break;
	    // ↑キー
	    case UP_KEY:
            	event.returnValue = false;	// ie
            	event.preventDefault();	// firefox
		gUpPush = true;
	        break;
            // ↓キー
	    case DOWN_KEY:
            	event.returnValue = false;	// ie
            	event.preventDefault();	// firefox
	    	gDownPush = true;
	        break;
	}
}

/*
	キーを離した時のイベント
*/
function keyUp(event) {
	code = event.keyCode;
	switch(code) {
	    // スペースキー
	    case SPACE_KEY:
	        gSpacePush = false;
	        break;
	    // ←キー
	    case LEFT_KEY:
	        gLeftPush = false;
	        break;
	    case RIGHT_KEY:
	        // →キー
	        gRightPush = false;
	        break;
	    case UP_KEY:
	        // ↑キー
		gUpPush = false;
	        break;
	    case DOWN_KEY:
	        // ↓キー
		gDownPush = false;
	        break;
	}
}