index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="../crafty-0.6.1.js"></script>
<script type="text/javascript" src="game.js"></script>
<script type="text/javascript" src="scene.js"></script>
<script>
window.οnlοad=function(){
Game.start();
//console.log("make map "+i+","+j);
}
</script>
<title>AStar</title>
</head>
<body>
</body>
</html>
scene.js
Crafty.scene('Main', function(){
//
console.log("main scene is load...");
var walls = new Array();
var wallNodes = new Array();
var pathCubes = new Array();
for(var i = 0; i < Game.tileX; i++){
for(var j = 0; j < Game.tileY; j++){
if(Crafty.math.randomNumber(1, Game.tileX-1)<9 && i>0 && i<Game.tileX-1 && j>0 && j<Game.tileY-1){
//floor
var wall = Crafty.e("2D, Canvas, Color, Solid").color("#A52A2A").attr({
w: Game.tileWidth, h: Game.tileHeight,
x: Game.tileWidth*i, y: Game.tileHeight*j
});
walls.push(wall);
wallNodes.push(new Node(i, j));
}else{
//floor
Crafty.e("2D, Canvas, Color, Mouse").color("#778899").attr({
w: Game.tileWidth, h: Game.tileHeight,
x: Game.tileWidth*i, y: Game.tileHeight*j
}).bind('Click', function(e){
//alert(Math.floor(e.clientX/Game.tileWidth)+","+Math.floor(e.clientY/Game.tileHeight));
pathCubes.length = 0;
/*
for(el in pathCubes){
el.destroy();
}
*/
var path = Game.findPath(new Node(player.x, player.y), new Node(e.clientX, e.clientY), wallNodes);
//console.log(path);
for(var k=0; k<path.length; k++){
var pathCube = Crafty.e("2D, Canvas, Color").color("#00FF00").attr({
w: Game.tileWidth, h: Game.tileHeight,
x: Game.tileWidth*path[k].x, y: Game.tileHeight*path[k].y
}).timeout(function(){
this.destroy();
}, 3000);
pathCubes.push(pathCube);
}
var dest = path.shift();
player.x = dest.x * Game.tileWidth;
player.y = dest.y * Game.tileHeight;
});
}
}
}
//
var player;
var flag = true;
while(flag){
var playerX = Crafty.math.randomInt(1,Game.tileX-1);
var playerY = Crafty.math.randomInt(1,Game.tileY-1);
console.log("playerX:"+playerX+",playerY:"+playerY);
for(var i=0; i<walls.length; i++){
if(walls[i].x != playerX && walls[i].y != playerY){
player = Crafty.e("2D, Canvas, Color").color("orange").attr({
w: Game.tileWidth, h: Game.tileHeight,
x: playerX*Game.tileWidth, y: playerY*Game.tileHeight, z: 99
});
flag = false;
break;
}
}
}
});
game.js
Game={
tileWidth: 16,
tileHeight: 16,
width: 1280,
height: 480,
tileX: 80,
tileY: 30,
start: function(){
Crafty.init(Game.width, Game.height);
Crafty.background('rgb(87, 109, 20)');
Crafty.scene('Main');
},
findPath: function(start, dest, walls){
if(start.x == undefined || start.y == undefined || dest.x == undefined || dest.y == undefined){
return undefined;
}
start.x = Math.floor(start.x/Game.tileWidth);
start.y = Math.floor(start.y/Game.tileHeight);
dest.x = Math.floor(dest.x/Game.tileWidth);
dest.y = Math.floor(dest.y/Game.tileHeight);
console.log("start:"+start.x+","+start.y+"/dest:"+dest.x+","+dest.y);
var openList = new Array();
var closeList = new Array();
start.costFromStart = 0;
start.costToObject = start.getCost(dest);
openList.push(start);
while(openList.length > 0){
var firstNode = openList.shift(); //返回并删除第一个元素
if(firstNode.x == dest.x && firstNode.y == dest.y){
return Game.makePath(firstNode);
}else{
closeList.push(firstNode);
var neighbors = firstNode.getNeighborNodes();
for(var i=0; i<neighbors.length; i++){
var neighborNode = neighbors[i];
//是否在打开列表
var isOpended = neighborNode.isPosCollided(openList);
//是否在关闭列表
var isClosed = neighborNode.isPosCollided(closeList);
//是否和障碍碰撞
var isCollideWithWall = neighborNode.isPosCollided(walls);
if(!isOpended && !isClosed && !isCollideWithWall){
neighborNode.costFromStart = firstNode.costFromStart + 1;
neighborNode.costToObject = neighborNode.getCost(dest);
neighborNode.parentNode = firstNode;
//
openList.push(neighborNode);
Crafty.e("2D, Canvas, Color, Solid").color("lightblue").attr({
w: Game.tileWidth, h: Game.tileHeight,
x: Game.tileWidth*neighborNode.x, y: Game.tileHeight*neighborNode.y
}).timeout(function(){this.destroy();}, 1500);
//按近-远排序
openList.sort(function(node1, node2){
return (node1.costFromStart + node1.costToObject) - (node2.costFromStart + node2.costToObject);
});
}
}
}
}
openList = undefined;
closeList = undefined;
return undefined;
},
makePath: function(node){
var path = new Array();
while(node.parentNode != undefined){
path.push(node);
node = node.parentNode;
}
//add last node
path.push(node);
return path;
},
};
function Node(posX, posY){
this.x = posX;
this.y = posY;
this.costFromStart = undefined;
this.costToObject = undefined;
this.parentNode = undefined;
};
Node.prototype = {
constructor: Node,
getCost: function(node){
if(node == undefined){
return undefined;
}
return Crafty.math.distance(node.x, node.y, this.x , this.y);
},
getNeighborNodes: function(){
var neighbors = new Array();
neighbors.push(new Node(this.x + 1, this.y));
neighbors.push(new Node(this.x, this.y + 1));
neighbors.push(new Node(this.x - 1, this.y));
neighbors.push(new Node(this.x, this.y - 1));
return neighbors;
},
isPosCollided: function(arr){
for(var i=0; i<arr.length; i++){
if(arr[i] != undefined && arr[i].x == this.x && arr[i].y == this.y){
return true;
}
}
return false;
}
};
顺便吐槽一下firefox32.0.3,改用360浏览器7.1挺好