我正在使用以下工具在JavaScript中创建Pacman游戏 .
-
Phaser :一个JavaScript游戏库
-
Tiled :用于创建切片贴图
在我的主要更新循环中,我有一个移动鬼魂的功能 . 它就像这样开始
moveGhosts: function() {
ghosts.forEachExists(function(ghost) {
if (ghost.y <= 210) {
ghost.mobilized = true;
}
if (ghost.mobilized) {
var ghostX = Math.round(ghost.x / map.tileWidth);
var ghostY = Math.round(ghost.y / map.tileHeight);
我在每个循环上更新重影的X和Y坐标 .
在Phaser中,瓦片图以瓦片而不是像素来测量 . 要获得切片位置,只需将x和y坐标分别除以tilemap的宽度和高度即可 .
Pacman可以移动四个方向
-
起来
-
下来
-
左
-
对
我认为存储这些可能移动的最佳数据结构将是一个对象数组 . 每次移动都具有以下属性
-
Direction: 这是上面列出的四个方向之一
-
Position: 除了简化下一个属性外,不使用此方法
-
Distance: 这是幽灵与Pacman位置的距离 . 为了找到距离,我使用了距离公式 .
-
Available: 这确定给定的移动是否有效 . 也就是说,如果沿着那个方向有一条路径 .
这是阵列 . 我猜这个问题就在这里 .
var moves = [
{
'direction': 'left',
'position': map.getTileLeft(0, ghostX, ghostY).x,
'distance': Math.sqrt(Math.pow((map.getTileLeft(0, ghostX, ghostY).x - pacmanX), 2) +
Math.pow((map.getTileLeft(0, ghostX, ghostY).y - pacmanY), 2)),
'available': levelState.pathLeftAvailable(ghostX, ghostY)
},
{
'direction': 'right',
'position': map.getTileRight(0, ghostX, ghostY).x,
'distance': Math.sqrt(Math.pow((map.getTileRight(0, ghostX, ghostY).x - pacmanX), 2) +
Math.pow((map.getTileRight(0, ghostX, ghostY).y - pacmanY), 2)),
'available': levelState.pathRightAvailable(ghostX, ghostY)
},
{
'direction': 'up',
'position': map.getTileAbove(0, ghostX, ghostY).y,
'distance': Math.sqrt(Math.pow((map.getTileAbove(0, ghostX, ghostY).x - pacmanX), 2) +
Math.pow((map.getTileAbove(0, ghostX, ghostY).y - pacmanY), 2)),
'available': levelState.pathUpAvailable(ghostX, ghostY)
},
{
'direction': 'down',
'position': map.getTileBelow(0, ghostX, ghostY).y,
'distance': Math.sqrt(Math.pow((map.getTileBelow(0, ghostX, ghostY).x - pacmanX), 2) +
Math.pow((map.getTileBelow(0, ghostX, ghostY).y - pacmanY), 2)),
'available': levelState.pathDownAvailable(ghostX, ghostY)
}
];
我选择了一个数组,因为需要对这些数据进行过滤以仅显示合法移动,然后根据距离进行排序 . 以下两个变量显示
-
将幽灵放置在最靠近吃 beans 子的地方(当红鬼追逐吃 beans 子时使用)
-
将鬼魂放置在距离Pacman最远的地方(鬼魂易受攻击时使用)
变量
var closestTile = moves.filter(m => m.available).sort((a,b) => a.distance - b.distance)[0].direction;
var furthestTile = moves.filter( m => m.available).sort((a,b) => b.distance - a.distance)[0].direction;
这是我收到错误消息的地方 . Can't read property direction of undefined
以下是这些变量的其余功能 . 问题可能不在这里,但这是为了在上下文中显示这些变量而添加的 .
this.game.physics.arcade.collide(ghost, wallLayer, function() {
var ghostDirection;
if (ghost.direction == 'up' || ghost.direction == 'down') {
ghost.y += ghost.direction == 'up' ? 1 : -1;
if (ghost.vulnerable) {
ghostDirection = furthestTile;
}
else {
if (ghost == redGhost) {
ghostDirection = closestTile;
}
else {
ghostDirection = Math.random() > 0.5 ? 'left' : 'right';
}
}
ghost.body.velocity.y = 0;
ghost.body.velocity.x = ghostDirection == 'left' ? -ghostVelocity : ghostVelocity;
}
else if (ghost.direction == 'left' || ghost.direction == 'right') {
ghost.x += ghost.direction == 'left' ? 1 : -1;
if (ghost.vulnerable) {
ghostDirection = furthestTile;
}
else {
if (ghost == redGhost) {
ghostDirection = closestTile;
}
else {
ghostDirection = Math.random() > 0.5 ? 'up': 'down';
}
}
ghost.body.velocity.x = 0;
ghost.body.velocity.y = ghostDirection == 'up' ? -ghostVelocity : ghostVelocity;
}
ghost.direction = ghostDirection;
}, null, this);
以下是确定移动是否合法的四个功能 . 这个问题最有可能不在于此 .
Tiled 创建由图层组成的图块 Map
我的游戏有一个显示墙壁的 Wall Layer . 此图层的索引为0.如果没有墙阻挡路径,则移动是合法的 . 对不起,如果这让一些人困惑 .
pathRightAvailable: function(x, y) {
return [x, x + 1, x + 2].every(function(xPosition) {
return !map.hasTile(xPosition, y, 0);
});
},
pathLeftAvailable: function(x, y) {
return [x, x - 1, x - 2].every(function(xPosition) {
return !map.hasTile(xPosition, y, 0);
});
},
pathUpAvailable: function(x,y) {
return [y, y - 1, y - 2].every(function(yPosition) {
return !map.hasTile(x, yPosition, 0);
});
},
pathDownAvailable: function(x,y) {
return [y, y + 1, y + 2].every(function(yPosition) {
return !map.hasTile(x, yPosition, 0);
});
},
以下是将变量记录到控制台的一些结果 .
console.log(moves)
=>
0:Object
available:true
direction:"left"
distance:35.4682957019364
position:26
__proto__:Object
1:Object
available:true
direction:"right"
distance:34.20526275297414
position:28
__proto__:Object
2:Object
available:true
direction:"up"
distance:35.608987629529715
position:36
__proto__:Object
3:Object
available:false
direction:"down"
distance:34.058772731852805
position:38
__proto__:Object
length:4
__proto__:Array(0)
console.log(closestTile)
=> 'down'
如果你能解决这个问题,祝你好运 . 我一直坚持这个问题一个小时 .