JavaScript:无法读取未定义

时间:2017-06-08 17:21:23

标签: javascript arrays object phaser-framework pacman

我正在使用以下工具在JavaScript中创建Pacman游戏。

  • Phaser :JavaScript游戏库
  • 平铺:用于创建平铺地图

在我的主更新循环中,我有一个移动鬼魂的功能。它就像这样开始

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有四种可能的移动方向

  • 向上
  • 向下
  • 右键

我认为存储这些可能移动的最佳数据结构将是一个对象数组。每次移动都具有以下属性

  • 方向:这是上面列出的四个方向之一
  • 职位:除了简化下一个属性外,不使用此项
  • 距离:这是幽灵与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)
                }
            ];

我选择了一个数组,因为需要过滤此数据以仅显示合法移动,然后根据距离进行排序。以下两个变量显示

  • 将幽灵放置在最靠近吃豆子的地方(当红鬼追逐吃豆子时使用)
  • 将幽灵放在距离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;

这是我收到错误消息的地方。 无法读取未定义的属性方向

这是函数的其余部分,这些变量在其中发挥作用。问题可能不在这里,但这是为了在上下文中显示这些变量而添加的。

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'

如果你能解决这个问题,祝你好运。我一直坚持这个问题一个小时。

0 个答案:

没有答案