This site requires JavaScript, please enable it in your browser!
Greenfoot back
ParticleCollision
ParticleCollision wrote ...

2016/11/30

Detect wall before moving? Method returning true/false if actor can move?

ParticleCollision ParticleCollision

2016/11/30

#
Hello! Im creating an AI for the Wombat scenario, the part Im currently stuck at is detecting a wall before the wombat would move. GetIntersectingObjects did not lead me to victory, the wombat once steps on a wall, it stays there since GetIntersectingObjects is returning true. My code below. act() calls the actual movement, if the way is free, it should move.
public void act()
    {
        if(foundLeaf()) {
            eatLeaf();
        }
        
        else if(canMove()){
            smarterMove();
            if (IsWombatOnWall()){
            smarterMove();
            }
        }
        else {
            randomDirection();
        }
    }
This one just spins the wombat with randomDirection(), and moves it by one block.
public void smarterMove()
    {
         randomDirection();
         move();
    }
randomDirection() makes a random turn on the actor.
public void randomDirection()
    {
        int i = (int )(Math.random() * 4 + 1);
       
        direction = i;
        
        switch(direction){
        case 1:
            setDirection(EAST);
            break;
        case 2:
            setDirection(NORTH);
            break;
        case 3:
            setDirection(WEST);
            break;
        case 4:
            setDirection(SOUTH);
            break;
        }
        
    }
IsWombatOnWall() method, this one is making the wombat stuck on a wall.
public boolean IsWombatOnWall(){
        
        if (!getIntersectingObjects(Wall.class).isEmpty()){
            return true;
            }
        else
        {
            return false;
        }        
    }
The extra I got in the Wombat scenario is a Wall class, its an empty one. Is there a way to detect an object before moving the wombat? Or can isTouching() be modified to return the direction of the Wall.class, where its positioned by the wombat?
Super_Hippo Super_Hippo

2016/11/30

#
Right now you try to detect if it can move and then it moves in a random direction. If you want to test if it can move, you need to know in which direction it moves. You could just move in a direction, check if it is touching a wall and if it does, move it back to where it was and try a different direction. You could also use the getObjectsAtOffset method and check for the cell next to the wombat where it wants to move.
ParticleCollision ParticleCollision

2016/11/30

#
Thank you Super_Hippo. Made a new method, which should forecast if a wall is present at the location the vombat would move. Now it keeps spinning, getOneObjectAtOffset(x,y,Wall.class) is always returning with a null. I feel Im really close to figuring this out, but the debugging window is not helping me. Am I missing something obvious here?
public boolean noWallInFront()
    {
        int currentDirection = getRotation();
        String directionName = "null";
        
        switch(currentDirection) {
            case 90 :
                directionName = "SOUTH";
                break;
            case 0 :
                directionName = "EAST";
                break;
            case 270 :
                directionName = "NORTH";
                break;
            case 180 :
                directionName = "WEST";
                break;
            }
        
        int x = getX();
        int y = getY();
        switch(directionName) {
            case "SOUTH" :
                y++;
                break;
            case "EAST" :
                x++;
                break;
            case "NORTH" :
                y--;
                break;
            case "WEST" :
                x--;
                break;
        }
        boolean wallAtLocation = false;
        
        if (getOneObjectAtOffset(x,y,Wall.class) == null){
            wallAtLocation = false;
        }
        else{
            wallAtLocation = true;
        }
        
        return wallAtLocation;
    }
Super_Hippo Super_Hippo

2016/11/30

#
In lines 21 and 22, you need to set x and y to 0. The getOneObjectAtOffset method needs the "offset", so the distance in each direction. It is also enough to just have one switch there.
ParticleCollision ParticleCollision

2016/11/30

#
Oh god. Setting those values to 0 really worked, I couldnt understood, what the parameters are meaning. I put the noWallInFront() method into the move() method, so the line looks like this:
if (!canMove() || !noWallInFront()) {
           return;
        }
switch(direction) {
            case SOUTH :
                setLocation(getX(), getY() + 1);
                break;
            case EAST :
                setLocation(getX() + 1, getY());
                break;
            case NORTH :
                setLocation(getX(), getY() - 1);
                break;
            case WEST :
                setLocation(getX() - 1, getY());
                break;
Thank you very much Super_Hippo.
You need to login to post a reply.