敵キャラ(クリボ)の描画(プログラムでマリオを作る第24回)

敵キャラ(クリボ)の描画をするプログラムを書きます。

クリボを管理するクラスを作成します。

中身と必要な変数はマリオとほとんど変わりありませんが、ジャンプせず、
歩くだけという設定なので、マリオに必要な処理が不要になるため、
クラスを分けて作成します。

基本となる部分をbaseクラス(Enemyなど)として定義して、それを継承して
クラスを作成していくのも、重複するコードを書かなくて済むテクニックの一つですが、
今回は行なっていません。

解説

今回は敵キャラの描画をやります。
クリボーと同じ動きをするキャラを作りたいと思います。

まず、クリボーの画像をresourceフォルダに追加してください。

slime

続いて、kuribo.jsファイルを作って、
クリボの処理を書いていきます。

kuribo.js

クリボクラスの定義をします。

とりあえず、描画するだけなので、位置を示すメンバ変数のposX,posY
だけ定義します。

function Kuribo(posX,posY){
  this.posX = posX;
  this.posY = posY;
}

続いて、描画関数の定義をします

/**
  描画関数
  ctx:context
  texture:img class
*/
Kuribo.prototype.draw = function(ctx,texture){
  ctx.drawImage(texture,0,32,32,32,this.posX,this.posY,32,32);
}

次にmain.jsを開いてください

main.js

テクスチャを保存するグローバル変数を定義します。

var gKuriboTex;

クリボクラスもとりあえず、グローバル変数として定義します。

var gKuribo;

続いて、onload関数内でクリボクラスを生成・初期化します。
クリボの座標はとりあえず、適当に置いておきます。

gKuribo = new Kuribo(216,384);

続いて、画像の読み込みをloadTexture()
内で行います。

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

テクスチャを読み込んだので、クリボを描画させます。

function Draw(){
  drawMap(gMapChip);
  gKuribo.draw(g_Ctx,gKuriboTex);
  gMario.draw(g_Ctx,gMarioTex);
}

最後に、index.htmlファイルにkuribo.jsを読み込ませます。

index.html

<script lang="JavaScript" src=kuribo.js></script>

これで、描画が完成したはずなので、htmlを起動してみましょう。

次回は、クリボの動き処理を入れたいと思います。

githubはこちら

今回修正したソースファイル

kuribo.js

function Kuribo(posX,posY){
  this.posX = posX;
  this.posY = posY;
}

/**
  描画関数
  ctx:context
  texture:img class
*/
Kuribo.prototype.draw = function(ctx,texture){
  ctx.drawImage(texture,0,32,32,32,this.posX,this.posY,32,32);
}

main.js

var g_Canvas;
var g_Ctx;

// texture
var gMarioTex;
var gMapTex;
var gKuriboTex;

var gMario;
var gKuribo;

// 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 gMapChip = [
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,64,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,0,0,0,64,64,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,64,0,0,0,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,64,0,0,0,64,64,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,64,0,64,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,64,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,64,64,64,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,0,64,0,0,64,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,64,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,64,64,64,64,64,64,64,64,64,0,0,0,64,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,0,0,0,0,64,0,0,0,64,64,64,64,64,64,64,64,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,64,64,64,64,64,0,0,0,0,64,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,0,64,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114],
  [128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130],
];

/**
	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();
    // mario
    gMario = new Mario(0,384);
    gKuribo = new Kuribo(216,384);

    // キーの登録
    window.addEventListener('keydown', keyDown, true);
    window.addEventListener('keyup', keyUp, true);
    requestNextAnimationFrame(animate);		// loopスタート
};

/*
	テクスチャのロード
*/
function loadTexture(){
	gMarioTex = new Image();
	gMarioTex.src = "resource/main.png";
  gMapTex = new Image();
  gMapTex.src = "resource/map512.png";
  gKuriboTex = new Image();
  gKuriboTex.src = "resource/slime.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(){
  drawMap(gMapChip);
  gKuribo.draw(g_Ctx,gKuriboTex);
	gMario.draw(g_Ctx,gMarioTex);
}

/**
  マップチップを描画

  map:対象のマップチップ配列
*/
function drawMap(map){
  // y軸
  for(var y = 0;y < MAX_MAP_Y;++y){
    // x軸
    for(var x = gMario.minDrawMapX;x < gMario.maxDrawMapX;++x){
      var indexX = 32 * ((map[y][x] + 16) % 16);
      var indexY = 32 * Math.floor(map[y][x] / 16);
      g_Ctx.drawImage(gMapTex,indexX,indexY,32,32,x * 32 - gMario.mapScrollX,y * 32,32,32);
    }
  }
}


function move(){
  // マップ座標の更新
  gMario.updateMapPosition();
	// 左キーが押されている状態
	if(gLeftPush){
    if(gSpacePush){
        gMario.setIsDash(true);
		    gMario.moveX(gMapChip,-DASH_SPEED);
    }
    else{
      gMario.setIsDash(false);
      gMario.moveX(gMapChip,-NORMAL_SPPED);
    }
	}
	// →キーが押されている状態
	if(gRightPush){
    if(gSpacePush){
        gMario.setIsDash(true);
		    gMario.moveX(gMapChip,DASH_SPEED);
    }
    else{
      gMario.setIsDash(false);
      gMario.moveX(gMapChip,NORMAL_SPPED);
    }
	}

  // ジャンプ動作
  if(gUpPush){
    // ジャンプ設定をオンにする
    gMario.setJumpSettings(gSpacePush);
  }
  // ジャンプ処理
  gMario.jumpAction(gUpPush,gMapChip);

  // scroll処理
  gMario.doMapScrollX();
}

/*
	キーを押した時の操作
*/
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;
	}
}

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="main.css">
<script lang="JavaScript" src=const.js></script>
<script lang="JavaScript" src=collisionUtils.js></script>
<script lang="JavaScript" src=mario.js></script>
<script lang="JavaScript" src=kuribo.js></script>
<script lang="JavaScript" src=main.js></script>
</head>

<body>
<div id="fps"></div>
<div id="canvas_wrapper">
	<canvas id="id_canvas" width="640" height="480"></canvas>
</div>
</body>
</html>
Pocket
LINEで送る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です