<body>
<div id="container"></div>
<script src="https://rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/Detector.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
<script src = "https://dl.dropboxusercontent.com/s/zjt32xn2mlyflvy/easystar-0.3.1.min.js"</script>
<link href='https://fonts.googleapis.com/css?family=Barrio' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Butcherman' rel='stylesheet'>
<div id="loader"></div>
</body>
var astar = {
init: function (graph) {
for (var x = 0; x < graph.length; x++) {
//for(var x in graph) {
var node = graph[x];
node.f = 0;
node.g = 0;
node.h = 0;
node.cost = 1.0;
node.visited = false;
node.closed = false;
node.parent = null;
}
},
cleanUp: function (graph) {
for (var x = 0; x < graph.length; x++) {
var node = graph[x];
delete node.f;
delete node.g;
delete node.h;
delete node.cost;
delete node.visited;
delete node.closed;
delete node.parent;
}
},
heap: function () {
return new BinaryHeap(function (node) {
return node.f;
});
},
search: function (graph, start, end) {
astar.init(graph);
//heuristic = heuristic || astar.manhattan;
var openHeap = astar.heap();
openHeap.push(start);
while (openHeap.size() > 0) {
// Grab the lowest f(x) to process next. Heap keeps this sorted for us.
var currentNode = openHeap.pop();
// End case -- result has been found, return the traced path.
if (currentNode === end) {
var curr = currentNode;
var ret = [];
while (curr.parent) {
ret.push(curr);
curr = curr.parent;
}
this.cleanUp(ret);
return ret.reverse();
}
// Normal case -- move currentNode from open to closed, process each of its neighbours.
currentNode.closed = true;
// Find all neighbours for the current node. Optionally find diagonal neighbours as well (false by default).
var neighbours = astar.neighbours(graph, currentNode);
for (var i = 0, il = neighbours.length; i < il; i++) {
var neighbour = neighbours[i];
if (neighbour.closed) {
// Not a valid node to process, skip to next neighbour.
continue;
}
// The g score is the shortest distance from start to current node.
// We need to check if the path we have arrived at this neighbour is the shortest one we have seen yet.
var gScore = currentNode.g + neighbour.cost;
var beenVisited = neighbour.visited;
if (!beenVisited || gScore < neighbour.g) {
// Found an optimal (so far) path to this node. Take score for node to see how good it is.
neighbour.visited = true;
neighbour.parent = currentNode;
if (!neighbour.centroid || !end.centroid) debugger;
neighbour.h = neighbour.h || astar.heuristic(neighbour.centroid, end.centroid);
neighbour.g = gScore;
neighbour.f = neighbour.g + neighbour.h;
if (!beenVisited) {
// Pushing to heap will put it in proper place based on the 'f' value.
openHeap.push(neighbour);
} else {
// Already seen the node, but since it has been rescored we need to reorder it in the heap
openHeap.rescoreElement(neighbour);
}
}
}
}
// No result was found - empty array signifies failure to find path.
return [];
},
heuristic: function (pos1, pos2) {
return distanceToSquared(pos1, pos2);
},
neighbours: function (graph, node) {
var ret = [];
for (var e = 0; e < node.neighbours.length; e++) {
ret.push(graph[node.neighbours[e]]);
}
return ret;
}
};
var scene, renderer, camera;
var cube;
var controls;
var mega1, mega2;
var grid, finder;
var enemy, player, enemy2, player2;
var easystar;
// Map generation (visit rooms)
// Create a 2D array of booleans.
// True means we can walk on, false means it's a wall.
function createHuntsMaze(w, h, cx, cy)
{
// With and height not set? stop
if (!w || !h)
return [];
// Store all the visited areas
var visited = [];
// Build the array
var map = [];
// Creates the 2nd dimension of the array
for (var i = 0; i < w; i++)
map[i] = [];
// Offset if the array doesn't fit our needs.
var offX = 1 - (cx % 2);
var offY = 1 - (cy % 2);
// Init the map and the visited array
for (var i = 0; i < w; i++)
{
for (var j = 0; j < h; j++)
{
map[i][j] = false;
visited[i + j * w] = false;
}
}
// Fill each 2nd cell with a true (those are the rooms)
for (var i = 0; i < w - offX; i++)
{
for (var j = 0; j < h - offY; j++)
{
if (i % 2 == 1 && j % 2 == 1 && i < w - (1 + offX) && j < h - (1 + offY))
map[i + offX][j + offY] = true;
else
map[i + offX][j + offY] = false;
}
}
// Set the start point of the visit
var todo = [{ x: 1 + offX, y: 1 + offY }];
var done = [];
visited[todo[0].x + todo[0].y * w] = true;
var maxSteps = Math.round(w * h / 3);
// While we have something to visit
while (todo.length > 0 && maxSteps > 0)
{
maxSteps--;
// Pick a random item from the todo
var s = Math.floor(Math.random() * todo.length);
var c = todo[s];
done[done.length] = c;
todo.splice(s, 1);
// Check if we can go to a room left (2 cells left)
if (c.x > 1 + offX && visited[(c.x - 2) + c.y * w] == false)
{
todo[todo.length] = { x: c.x - 2, y: c.y };
visited[(c.x - 2) + c.y * w] = true;
// Open the wall to left
map[(c.x) - 1][c.y] = true;
}
// Check if we can go to a room up (2 cells up)
if (c.y > 1 + offY && visited[(c.x) + (c.y - 2) * w] == false)
{
todo[todo.length] = { x: c.x, y: c.y - 2 };
visited[(c.x) + (c.y - 2) * w] = true;
// Open the wall to up
map[c.x][(c.y) - 1] = true;
}
// Check if we can go to a room right (2 cells right)
if (c.x + 2 < w - 1 && visited[(c.x + 2) + c.y * w] == false)
{
todo[todo.length] = { x: c.x + 2, y: c.y };
visited[(c.x + 2) + c.y * w] = true;
// Open the wall to right
map[(c.x) + 1][c.y] = true;
}
// Check if we can go to room right (2 cells down)
if (c.y + 2 < h - 1 && visited[(c.x) + (c.y + 2) * w] == false)
{
todo[todo.length] = { x: c.x, y: c.y + 2 };
visited[(c.x) + (c.y + 2) * w] = true;
// Open the wall to bottom
map[c.x][(c.y) + 1] = true;
}
}
return map;
}
init();
animate();
function init()
{
renderer = new THREE.WebGLRenderer( {antialias:true} );
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize (width, height);
document.body.appendChild (renderer.domElement);
scene = new THREE.Scene();
//scene.fog = new THREE.FogExp2(0x1E2630, 0.002);
renderer.setClearColor("yellow");
var cubeGeometry = new THREE.BoxGeometry (10,10,10);
var cubeMaterial = new THREE.MeshLambertMaterial ({color: 0x1ec876});
// Create a maze and render it
// Create a maze and render it
var maze = createHuntsMaze(20,20,65,65);
function buildMaze()
{
for(var x=0;x < maze.length;x++)
{
for(var y=0;y < maze.length;y++)
{
if(maze[x][y] === true)
continue;
// Our built-in 'sphere' shape. Params: name, subdivs, size, scene
cube = new THREE.Mesh (cubeGeometry, cubeMaterial);
cube.position.set (50, 0, 0);
scene.add (cube);
// Move the sphere upward 1/2 its height
cube.position.x = x*120;
cube.position.z = y*120;
cube.scale.z = 10;
cube.scale.y = 10;
cube.scale.x = 10;
}
}
}
buildMaze();
var player = {
x: 0,
y: 0
};
var enemy = {
x: 2,
y: 2
};
mega1 = new THREE.Mesh (new THREE.BoxGeometry (80,80,80), new THREE.MeshLambertMaterial ({color: "blue"}));
mega1.position.set(player.x, 0, player.y)
scene.add (mega1);
player2 = {
x: 0*mega1.position.x,
y: 0*mega1.position.z
};
mega2 = new THREE.Mesh (new THREE.BoxGeometry (40,40,40), new THREE.MeshLambertMaterial ({color: "red"}));
mega1.position.set(enemy.x, 0, enemy.y)
scene.add (mega2);
enemy2 = {
x: 5*mega2.position.x,
y: 4*mega2.position.z
}
var mze = [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[ 1, 0, 1, 0, 0, 0, 0, 0, 1, 0],
[ 0, 0, 0, 0, 1, 1, 1, 0, 1, 0],
[ 0, 1, 1, 0, 0, 0, 1, 0, 1, 0],
[ 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
[ 1, 0, 1, 0, 0, 0, 1, 0, 1, 0],
[ 1, 0, 1, 0, 1, 0, 1, 0, 0, 0],
[ 1, 0, 1, 0, 1, 0, 0, 1, 1, 0],
[-1, 0, 1, 0, 1, 1, 0, 0, 0, 0]
];
//easystar
var graph = new Graph(mze, { diagonal: false });
var start = graph.grid[enemy.x][enemy.y];
var end = graph.grid[player.x][player.y];
//var result = astar.search(graph, [0, 0], [2, 2]);
var result = astar.search(graph, start, end);
function pathToString(result) {
return result.map(function(node) {
return "(" + node.x + "," + node.y + ")";
}).join("");
}
var current = result.shift();
for(var i = 0; i<result.length; i++){
console.log(result[i])
}
easystar = new EasyStar.js();
easystar.setGrid(maze)
easystar.setAcceptableTiles([false]);
easystar.enableDiagonals();// we want path to have diagonals
easystar.disableCornerCutting();// no diagonal path when walking at wall corners
easystar.setIterationsPerCalculation(1000);
grid = new PF.Grid(mze.length, mze.length, mze);
finder = new PF.AStarFinder({allowDiagonal: true});
var path = finder.findPath(0, 0, 3, 3, grid.clone());
var current = path.shift();
console.log(path)
for(var i = 0; i<path.length; i){
// console.log("x"+path[i][0]+" y"+path[i][1]);
// console.log(dy);
// var tween = createjs.Tween.get(mega2.position, {loop: false})
//.to({x: path[i][0], z: path[i][1]}, 70);
}
camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000);
camera.position.y = 160;
camera.position.z = 400;
camera.lookAt (new THREE.Vector3(0,0,0));
controls = new THREE.OrbitControls (camera, renderer.domElement);
var gridXZ = new THREE.GridHelper(100, 10);
gridXZ.setColors( new THREE.Color(0xff0000), new THREE.Color(0xffffff) );
scene.add(gridXZ);
function canMove(x, y){
return (y>=0) && (y<world.length) && (x >= 0) && (x < world[y].length) && (world[y][x] != true);
}
document.addEventListener("keyup", function(e){
if((e.which == 38) && canMove(mega1.position.x, mega1.position.z-1))//Up arrow
mega1.position.z--;
else if((e.which == 40) && canMove(mega1.position.x, mega1.position.z+1)) // down arrow
mega1.position.z++;
else if((e.which == 37) && canMove(mega1.position.x-1, mega1.position.z))
mega1.position.x--;
else if((e.which == 39) && canMove(mega1.position.x+1, mega1.position.z))
mega1.position.x++;
//find collision
// var path = new astar();
//path.init(mze)
console.log("this"+astar.search(maze,[0, 1], [2, 3]))
e.preventDefault();
});
var pointLight = new THREE.PointLight (0xffffff);
pointLight.position.set (0,300,200);
scene.add (pointLight);
window.addEventListener ('resize', onWindowResize, false);
}
function onWindowResize ()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize (window.innerWidth, window.innerHeight);
}
function animate()
{
controls.update();
requestAnimationFrame ( animate );
renderer.render (scene, camera);
}
This Pen doesn't use any external CSS resources.