Jump to content

Cannot read property direction of undefined


evilwizard
 Share

Recommended Posts

I am creating a Pacman game in JavaScript and have ran into a problem. I am trying to implement the ghost's movement. 

On each loop, I record the Tile Position of the ghosts

var ghostX = Math.round(ghost.x / map.tileWidth);
var ghostY = Math.round(ghost.y / map.tileHeight);

There are four possible directions in which a ghost can move

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)
                }
            ];

As you can see, I thought the best data structure for this would be an array of objects. Each move has several properties including the name of the direction, how far the move will place the ghost from Pacman, and whether it's a legal move. To find the closest tile, you use the distance formula. This is the square root of the squares of the sums of the x and y coordinates.

I then created two variables to represent the closest and furthest tiles. This is where I received the error message

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;

I need to find only legal moves, so it was necessary to filter() the array to find only those moves. The arrays then needed to be sorted by their distance. The first such element will be the result of the variable. But it couldn't find the direction property.

The movement function is finished out like this

var ghostVelocity = levelState.getGhostVelocity();
                
                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);

As you can see, I am setting the ghost's direction property based on the closest tile to pacman.

For reference, here are the four functions that determine whether a direction is available. There doesn't seem to be a problem here.

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);
        });
    },

I've been working on this problem for some time but have ran into trouble. Any help is greatly appreciated

Link to comment
Share on other sites

 

 

I agree with @samme . It seems like your filter returns an empty array. When you try access the element at index 0, you are accessing an undefined object (otherwise it should not be throwing an error):

//error
var foo=undefined;
console.log(foo.direction);
//no error
var foo=[];
console.log(foo.direction);
//no error
var foo ='bar';
console.log(foo.direction);

 

Link to comment
Share on other sites

Sorry guys, but I ended up giving up. I spent hours today making that code, but I could never get it to work. It was too complicated with too much going on. I had to delete that and revert back to my older code. In other words, my entire effort was fruitless.

I would like to thank you all for your help though.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...