项目演示
项目演示地址:
项目源码:
代码结构
本节做完效果
Enemy.js
//敌人类 function Enemy(cxt,img,type,x,y,width,height){ this.cxt = cxt; this.img = img; this.x = x;//55 this.y = y;//0 this.width = width; this.height = height; //敌人类型 this.type = type; this.sp = 2; //移动的方向 this.dir = null; //下个移动位置 this.nextPosition = null; //记录已经走过的位置 this.hadWalk = {}; } Enemy.prototype = { //敌人在图片中对应的位置 enemyMap : [{x:0,y:0},{x:40,y:0},{x:80,y:0},{x:120,y:0},{x:160,y:0},{x:200,y:0},{x:240,y:0},{x:280,y:0},{x:320,y:0},{x:360,y:0}, {x:400,y:0},{x:440,y:0},{x:480,y:0},{x:520,y:0},{x:560,y:0},{x:600,y:0},{x:640,y:0},{x:680,y:0},{x:720,y:0},{x:760,y:0}], //画出敌人 draw : function(){ //冰冻中,画出冰冻图 if(this.frozenTime > 0){ Canvas.drawImg(this.cxt,this.img,this.enemyMap[this.type].x,this.enemyMap[this.type].y+40,this.width,this.height,this.x,this.y,this.width,this.height); } //画出正常图 else Canvas.drawImg(this.cxt,this.img,this.enemyMap[this.type].x,this.enemyMap[this.type].y,this.width,this.height,this.x,this.y,this.width,this.height); //计算血量百分比 var persen = Math.floor(this.life / this.maxLife * 100) / 2; //画出血量 Canvas.fillRect(this.cxt,this.x-5,this.y-5,persen,3,"rgba(38,223,116,0.8)"); }, //更新敌人信息 update : function(){ //超出坐标 if(this.x >= 500){ return false; } var xIndex = parseInt(this.x / 50,10),//1 yIndex = parseInt(this.y / 50,10);//0 //判断是否有下个移动位置信息,或者下哥移动位置信息是否已经走到了 if(!this.nextPosition || ((this.x >= this.nextPosition.x - 5 && this.x <= this.nextPosition.x) && (this.y >= this.nextPosition.y - 5 && this.y <= this.nextPosition.y)) ){ //走到最右侧 if(xIndex + 1 >= 10){ xIndex = -1; } else{ //判断往下能否走 if(MapData[xIndex][yIndex+1] && !this.hadWalk[xIndex+"_"+(yIndex+1)]){ this.dir = "down"; yIndex += 1; } //判断往右能否走 else if(MapData[xIndex+1][yIndex] && !this.hadWalk[(xIndex+1)+"_"+yIndex]){ this.dir = "right"; xIndex += 1; } else if(MapData[xIndex][yIndex-1] && !this.hadWalk[xIndex+"_"+(yIndex-1)]){ this.dir = "up"; yIndex -= 1; } else if(MapData[xIndex-1][yIndex] && !this.hadWalk[(xIndex-1)+"_"+yIndex]){ this.dir = "left"; xIndex -= 1; } } //是否走到最右侧 if(xIndex == -1){ this.nextPosition = {x:500,y:yIndex*50+5}; } //设置下个移动位置 else { this.nextPosition = {x:xIndex*50+5,y:yIndex*50+5}; //记录已经走过的位置 this.hadWalk[xIndex+"_"+yIndex] = true; } } //移动 switch(this.dir){ case "down": this.y += this.sp; break; case "up": this.y -= this.sp; break; case "left": this.x -= this.sp; break; case "right": this.x += this.sp; break; default: break; } } } //更新所有敌人信息 function updateEnemy(){ var enemy; for(var i=0,l=Game.enemyList.length;i<l;i++){ enemy = Game.enemyList[i]; if(!enemy)continue; enemy.update(); } } //画出所有敌人 function drawEnemy(){ var enemy; for(var i=0,l=Game.enemyList.length;i<l;i++){ enemy = Game.enemyList[i]; if(!enemy)continue; enemy.draw(); } }
game.js修改
每50次循环出一个敌人
tool.js新增
自动寻路算法解析
坐标系
向右为x轴
向下为y轴
整个地图为500*500
// 游戏对象 var hero = { speed: 2, // 每秒移动的像素 x: 55, y: 0, srcx:120, srcy:40, flood:50, //移动的方向 dir:null, //下个移动位置 nextPosition: null, //记录已经走过的位置 hadWalk:{} };
英雄像素转换为网格(10*10)坐标
var xIndex = parseInt(hero.y / 50, 10), yIndex = parseInt(hero.x / 50, 10);
最开始时,
xIndex = 1
yIndex = 0
初始时满足!hero.nextPosition
if (!hero.nextPosition || ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y)) )
进入后,满足往下走
else { //判断往下能否走 if(MapData[xIndex][yIndex+1] && !this.hadWalk[xIndex+"_"+(yIndex+1)]){ this.dir = "down"; yIndex += 1; }
此时
xIndex = 1
yIndex = 1
然后,
//设置下个移动位置 else { hero.nextPosition = {y: xIndex * 50 + 5, x: yIndex * 50 + 5}; //记录已经走过的位置 hero.hadWalk[xIndex + "_" + yIndex] = true; }
hero.nextPosition = {
x:55,y:55
}
然后,
//移动 switch(hero.dir){ case "down": hero.y += hero.speed; break; case "up": hero.y -= hero.speed; break; case "left": hero.x -= hero.speed; break; case "right": hero.x += hero.speed; break; default: break; }
此时,
hero = { speed: 2, // 每秒移动的像素 x: 2, y: 55,
循环回去:
然后在hero.x未满足条件:
if (!hero.nextPosition || ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y)) )
时,有25次(50/2),跳过上面条件里的代码,直接执行以下代码:
//移动 switch(hero.dir){ case "down": hero.y += hero.speed; break; case "up": hero.y -= hero.speed; break; case "left": hero.x -= hero.speed; break; case "right": hero.x += hero.speed; break; default: break; }
当再次hero.x满足条件:
if (!hero.nextPosition || ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y)) )
时,重复之前的逻辑。
如此循环。
such that