敵キャラ(クリボ)の移動処理の実装をします。
基本的な部分はマリオと一緒になりますが、マリオはキー入力で動いている一方
クリボは決められた行動パターンを元に動いていきます。
クリボは左右に動くだけのキャラなので、とりあえず一方方向に動かすような
プログラムを書いていきます。
解説
前回は、クリボを描画したので、今回はクリボの移動処理を行います。
まず、kuribo.jsを開いてください
kuribo.js
クリボのメンバー変数に
X軸の加算量とanimation用のカウント変数と
方向となる変数を定義します。
また、初期値として方向を示すdirを引数にいれます。
function Kuribo(posX,posY,dir){
this.posX = posX;
this.posY = posY;
// chapter25敵の移動
this.addPosX = 0;
// どのタイミングでアニメーションを切り替えるか
this.animCnt = 0;
// 切り出す始点のX座標
this.animX = 0;
this.direction = dir;
}
続いて、描画関数drawを修正します。
アニメーションができるようにオフセットを入れるのと、
マップスクロールが適応されるように、引数としてマップスクロール変数を
入れます。
/*
描画関数
ctx:context
texture:img class
scrollX:X軸のスクロール量
*/
Kuribo.prototype.draw = function(ctx,texture,scrollX){
ctx.drawImage(texture, (this.animX * 32) + (this.direction * 128),32,32,32,this.posX - scrollX,this.posY,32,32);
}
続いて、クリボを動かすためのmove関数を定義します。
対象がクリボなので、左右に動かすのみになります。
引数にマップチップと加算量を示す。
moveNumをとります。
/*
動かす役割
moveNum:移動量
*/
Kuribo.prototype.move = function(mapChip,moveNum){
// 向きにより加算量を調整する
moveNum = this.direction == LEFT_DIR ? -moveNum : moveNum;
// 加算量を代入する
this.addPosX = moveNum;
this.posX += this.addPosX;
// animation
if(this.animCnt++ >= 12){
this.animCnt = 0;
// 一定以上に達したらアニメーションを更新する
if(++this.animX > 3){
this.animX = 0;
}
}
}
これで、クリボで必要な処理は書いたので、続いて
main.jsを開いてください
main.js
まず、クリボの初期化関数のところで、方向を入力します。
左に進ませたいので、LEFT_DIRを入れます。
gKuribo = new Kuribo(608,384,LEFT_DIR);
続いて、描画関数のところに、マリオのスクロール量を入れることにより、
スクロールに対応させます。
gKuribo.draw(g_Ctx,gKuriboTex,gMario.mapScrollX);
続いて、move関数内で、kuriboのmoveを呼び出したいんですが、
今後を考えて、enemyMove関数を作ってその中で、
kuriboのmove関数を呼び出したいと思います。
function enemyMove(){
gKuribo.move(gMapChip,1);
}
move関数の最後でenemyMove関数を呼びます。
function move(){
...
enemyMove();
}
これで、修正が終わったので確認して見ましょう。
今回修正したソース
kuribo.js
function Kuribo(posX,posY,dir){
this.posX = posX;
this.posY = posY;
// chapter25敵の移動
this.addPosX = 0;
// どのタイミングでアニメーションを切り替えるか
this.animCnt = 0;
// 切り出す始点のX座標
this.animX = 0;
this.direction = dir;
}
/*
描画関数
ctx:context
texture:img class
scrollX:X軸のスクロール量
*/
Kuribo.prototype.draw = function(ctx,texture,scrollX){
ctx.drawImage(texture, (this.animX * 32) + (this.direction * 128),32,32,32,this.posX - scrollX,this.posY,32,32);
}
/*
動かす役割
moveNum:移動量
*/
Kuribo.prototype.move = function(mapChip,moveNum){
// 向きにより加算量を調整する
moveNum = this.direction == LEFT_DIR ? -moveNum : moveNum;
// 加算量を代入する
this.addPosX = moveNum;
this.posX += this.addPosX;
// animation
if(this.animCnt++ >= 12){
this.animCnt = 0;
// 一定以上に達したらアニメーションを更新する
if(++this.animX > 3){
this.animX = 0;
}
}
}
main.js
var g_Canvas;
var g_Ctx;
// texture
var gMarioTex;
var gMapTex;
// chapter24
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(608,384,LEFT_DIR);
// キーの登録
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);
gMario.draw(g_Ctx,gMarioTex);
gKuribo.draw(g_Ctx,gKuriboTex,gMario.mapScrollX);
}
/**
マップチップを描画
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();
enemyMove();
}
function enemyMove(){
gKuribo.move(gMapChip,1);
}
/*
キーを押した時の操作
*/
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;
}
}