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

2013/6/1

Not moving after a while

Nike.Sprite Nike.Sprite

2013/6/1

#
Hi I'm making a Pacgame, with automatic ghost movements. I tried this (see code), but there are some problems... sometimes my ghost won't go on, he stops at a wall, how can I prevent this ? Kind regards Nike ;)
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Ghost here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Ghost extends Actor
{
    boolean free = false;

    int orientatie;
   

    public Ghost(String naam)
    {
        setImage(naam+".png");

        do{
           orientatie = Greenfoot.getRandomNumber(4);
        }
        while(orientatie == 1);
    }

    public void setOrientatie(int graden) // geef een orientatie mee aan de pacman
    {
        orientatie = graden;
        switch(orientatie) 
        {
            case 0: // right
            setRotation(0);
            break;

            case 1: // down
            setRotation(0);
            break;

            case 2: // left
            setRotation(0);
            break;

            case 3: // up
            setRotation(0);
            break;
        }
    }

    public void act()
    {
        sides();
        setOrientatie(orientatie);

        if (canMove(orientatie)== true)
        {
            move();
        }
    }

    private boolean canMove(int orientatie) // kijk of er geen wall in de weg staat
    {

        switch(orientatie)
        {
            case 0: // right
            Actor wall = getOneObjectAtOffset(1,0, Wall.class);
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 1: // down
            wall = getOneObjectAtOffset(0,1, Wall.class);
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 2: // left
            wall = getOneObjectAtOffset(-1,0, Wall.class);
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 3: // up
            wall = getOneObjectAtOffset(0,-1, Wall.class);
            if (wall == null)
            {
                return true;
            }
        }
        return false;
    }

    private boolean canTurn(int i)
    {
        switch (i)
        {
            case 0: // right
            Actor wall = getOneObjectAtOffset(1, 0, Wall.class); // kijk of er een blokje rechts staat
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 1: // down        
            wall = getOneObjectAtOffset(0, 1, Wall.class);  // kijk of er een blokje onderaan staat
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 2: // left
            wall = getOneObjectAtOffset(-1, 0, Wall.class); // kijk of er een pacman links staat
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }

            case 3: // up
            wall = getOneObjectAtOffset(0, -1, Wall.class); // kijk of er een pacman bovenaan staat
            if (wall == null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }

    public void move()
    {
        if (Greenfoot.getRandomNumber(4) == 0 && canTurn(0)) // right
        {
            setOrientatie(0);
            setLocation(getX()+1, getY());
        }
        if (Greenfoot.getRandomNumber(4) == 1 && canTurn(1)) // down
        {
            setOrientatie(1);
            setLocation(getX(), getY()+1);
        }
        if (Greenfoot.getRandomNumber(4) == 2  && canTurn(2)) // left
        {
            setOrientatie(2);
            setLocation(getX()-1, getY());
        }
        if (Greenfoot.getRandomNumber(4) == 3 && canTurn(3)) // up
        {
            setOrientatie(3);
            setLocation(getX(), getY()-1);
        }
    }

    public void sides() // nog kijken of dit OK is...
    {
        if (getX()==0 && getY()==9)
        {
            setLocation(24,9);
        }

        if (getX()==24 && getY()==9)
        {
            setLocation(0,9);
        }
    }
}
danpost danpost

2013/6/2

#
Three things strike me as I review your code: (1) in your 'setOrientatie' method, all cases set the rotation to zero; (2) both the 'canMove' and 'canTurn' methods do exactly the same thing; and, (3) it is possible that no 'if' is satisfied in the 'move' method.
Nike.Sprite Nike.Sprite

2013/6/2

#
(1) indeed I could leave the SetRotation(0) in the cases, but my ghosts can't turn so that is why they have the same orientatation. (2) what is wrong with the canTurn() methode ? (3) what do you mean ? they must walk if canMove is true and if they can turn they must turn
danpost danpost

2013/6/2

#
(1) then you should not need to set any rotations at all (since rotation starts out at zero anyway); (2) nothing, just wasted code (since calling 'canMove' does exactly the same thing); (3) you should already have a valid 'orientatie' value by the time you call the 'move' method; that method can be reduced to:
public void move()
{
    if (orientatie == 0)
    {
        setLocation(getX()+1, getY());
    }
    if (orientatie == 1)
    {
        setLocation(getX(), getY()+1);
    }
    if (orientatie == 2)
    {
        setLocation(getX()-1, getY());
    }
    if (orientatie == 3)
    {
        setLocation(getX(), getY()-1);
    }
}
However, you need to work on getting an appropriate value in the 'orientatie' field. Using 'setOrientatie(orientatie);' in the 'act' method is useless; like saying 'orientatie = orientatie;'. What are the steps involved in determining a valid value for 'orientatie'? well, first you would count how many different ways you can proceed (without backtracking). Of course, if you counted zero ways, you would have to backtrack. Otherwise, you would randomly choose one of the forward paths. I came up with the following when working with someone else. The 'direction' field holds the direction in 90 degree increments, but acts basically like your 'orientatie' field (times 90).
private void move()  
{
    setRotation(direction); // face current moving direction
    // count possible forward paths
    int dirs = 0;
    turn(-90);
    for (int i=0; i<3; i++) {   
        if (canMove()) dirs++;
        turn(90);
    }
    // if forward paths available, randomly choose one
    if (dirs > 0) {
        // randomly choose a path
        int choice = Greenfoot.getRandomNumber(dirs);
        // determine path chosen
        while (choice>=0) {  
            turn(90);  
            if (canMove()) choice--;  
        }
    }
    direction = getRotation(); // save 'new' move direction
    move(1); // move
    setRotation(0); // reset rotation to zero
}

private boolean canMove()  
{  
    move(1);  // move forward
    Actor wall = getOneIntersectingObject(Wall.class);  // check wall
    move(-1);  // move back
    return wall == null;  // can move status returned
}
You need to login to post a reply.