我正在使用以下工具在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'

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