我正在使用以下工具在JavaScript中创建Pacman游戏。
在我的主更新循环中,我有一个移动鬼魂的功能。它就像这样开始
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有四种可能的移动方向
我认为存储这些可能移动的最佳数据结构将是一个对象数组。每次移动都具有以下属性
这是阵列。我猜这个问题就在这里。
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)
}
];
我选择了一个数组,因为需要过滤此数据以仅显示合法移动,然后根据距离进行排序。以下两个变量显示
变量
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;
这是我收到错误消息的地方。 无法读取未定义的属性方向
这是函数的其余部分,这些变量在其中发挥作用。问题可能不在这里,但这是为了在上下文中显示这些变量而添加的。
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);
以下是确定移动是否合法的四个功能。问题很可能不在于此。
平铺会创建由图层组成的图块地图
我的游戏有一个 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'
如果你能解决这个问题,祝你好运。我一直坚持这个问题一个小时。