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

2012/6/19

stopping actor when it hits a wall

jcoode jcoode

2012/6/19

#
I am new to greenfoot. I am creating a maze game on greenfoot. At the moment my character goes through the walls but i would like him to stop when he hits the wall. i have this code in the actors bit: public void move() { if (canSee (wall.class)) { if (getRotation()== 270)//north 3 setLocation(getX(), getY() +8); if (getRotation() == 90) //south 1 setLocation(getX(), getY()-8); if (getRotation() == 0)//east 0x setLocation(getX() - 8, getY()); if (getRotation() == 180)//west 180 setLocation (getX() + 8, getY()); } have i missed something obvious?
danpost danpost

2012/6/19

#
If you can see the wall before you move, it is already to late! The order of events and checks should be: 1) move 2) if sees wall a) move back b) turn I will assume your grid-size is 1 pixel, indicated by the movement value of 8 above (although that appears to be an attempt to stay off the wall. At any rate, I do not see anything that would be an initial movement or any turns!
danpost danpost

2012/6/19

#
For the collision checking, if you are moving 8 pixels at a time, you should probably iterate through the move 1 pixel at a time, each time checking for the wall; then if found move back once and turn. Since all the moving and turning are in the move method, just change the 8's to 1's, and instead of calling it with 'move()',call it with 'for (int i = 0; i < 8; i++) move();'. This will ensure that you will not jump passed the wall.
jcoode jcoode

2012/6/20

#
i just realised i used code thats for something that is constantly moving. my actor uses the arrow keys to move. i used this code: if (Greenfoot.isKeyDown("left")) { move(-4); } if (Greenfoot.isKeyDown("right")) { move(4); } if (Greenfoot.isKeyDown("up")) { setLocation(getX(), getY() - 4); } if (Greenfoot.isKeyDown("down")) { setLocation(getX(), getY() + 4); } should i use a different code to stop it when it hits a wall?
danpost danpost

2012/6/20

#
I prefer using code that is something like this:
// in act method, use:
move(4); // to move maximum of 4 pixels
// where move(int) is defined as
public void move(int moveAmt)
{
    // determine direction by keypress checking
    int dx = 0, dy = 0;
    if (Greenfoot.isKeyDown("right")) dx += 1;
    if (Greenfoot.isKeyDown("left")) dx -= 1;
    if (Greenfoot.isKeyDown("down")) dy += 1;
    if (Greenfoot.isKeyDown("up")) dy -= 1;
    // check for wall on each step of move in both vertical and horizontal directions
    for (int i = 0; i < moveAmt; i++)
    {
        setLocation(getX() + dx, getY());
        if (getOneIntersectingObject(Wall.class) != null) setLocation(getX() - dx, getY());
        setLocation(getX(), getY() + dy);
        if (getOneIntersectingObject(Wall.class) != null) setLocation(getX(), getY() - dy);
    }
}
jcoode jcoode

2012/6/21

#
it says line 04. is an illegal start of expression.
plcs plcs

2012/6/21

#
That is probably because you have move(4) at the class level, you need to add it to your act() method.
public void act()
{
   move(4);
}
crazyjack12 crazyjack12

2012/6/22

#
pics if he uses that code his actor would just continuously move, Jcoode in my opinion it would be easier to use four actors for walls: wall1 - horizontal wall, prevents users moving 'down' through the wall wall2 - horizontal wall, prevents users moving 'up' through the wall wall3 - vertical wall, prevents users moving 'left' through the wall wall4 - vertical wall, prevents users moving 'right' through the wall using if statements inside the avatar's actor, restrict the precise movement depending on which wall actor he/she is intercepting. obviously this isn't an efficient way of preventing the player not to move through the walls considering you have to layout each wall individually as well, however it will work evidently. now this is an example of the code you may use, by using an integer 'oi' which you will have to declare, once the user has moved away from the wall will you then take off the movement restriction by using an if statement to detect the value of oi, depending the value of the oi int, a movement function will run which will allow the avatar to move using all buttons, instead of being restricted continuously.
x = getX();
y = getY();

 if(getOneIntersectingObject(wall3.class) != null)
{
oi = 1;
 if(Greenfoot.isKeyDown("d"))
        {
        
         
         setLocation(x + 2, y);
      oi = 0;
        }
 if(Greenfoot.isKeyDown("s"))
        {
        
         
         setLocation(x , y + 2);
      oi = 0;
        }
 if(Greenfoot.isKeyDown("w"))
        {
        
         
         setLocation(x, y - 2);
      oi = 0;
        }
    }
if (oi == 0)
{
movement();
}
This code restricts the user from using the key press a, resulting in the user not being able to go past one of your vertical walls anymore. I hope you get a vague understanding from this concept and that you find it helpful.
danpost danpost

2012/6/22

#
@crazyjack12, why would you want to create 4 seperate Wall classes when there is no problem with using just one? Would you not have to duplicate your code 4 times to cover the possibilities for all 4 possible intersections? The code provided in my previous post on this thread will have the actor move on keystroke with a speed of 4 and will not penetrate any Wall object (even if the wall is only 1 pixel thick!)
crazyjack12 crazyjack12

2012/6/22

#
it's really down to your own problem solving skills, i'd prefer to use my own way as it may be easier to understand and can definitely work, although it may slightly increase compiling time.
danpost danpost

2012/6/22

#
Not exactly. What it does do is this: after determining the direction of the move by check keypresses, it moves the actor 1 pixel at a time, checking for an intersecting wall each time. If a wall is found to be present, it takes back the last 1 pixel move, resulting in a stop in that direction (because a wall was there). Because it breaks down the whole movement into 1 pixel moves, it matters not the speed of the actor (you cannot 'jump' or 'skip' over the obstacle).
danpost danpost

2012/6/22

#
crazyjack12, NVM, four classes and multiple checks, that is your way. One class and one check, that is mine. BTW, with your code, if the actor was in a corner, it could find one wall and then move into the other one, unchecked!
jcoode jcoode

2012/6/22

#
ok. at the moment i have this. public void act() { move(4); } public void move(int moveAmt) { // determine direction by keypress checking int dx = 0, dy = 0; if (Greenfoot.isKeyDown("right")) dx += 1; if (Greenfoot.isKeyDown("left")) dx -= 1; if (Greenfoot.isKeyDown("down")) dy += 1; if (Greenfoot.isKeyDown("up")) dy -= 1; // check for wall on each step of move in both vertical and horizontal directions for (int i = 0; i < moveAmt; i++) { setLocation(getX() + dx, getY()); if (getOneIntersectingObject(wall.class) != null) setLocation(getX() - dx, getY()); setLocation(getX(), getY() + dy); if (getOneIntersectingObject(wall.class) != null) setLocation(getX(), getY() - dy); } } { if (Greenfoot.isKeyDown("left")) { move(-1); } if (Greenfoot.isKeyDown("right")) { move(1); } if (Greenfoot.isKeyDown("up")) { setLocation(getX(), getY() - 1); } if (Greenfoot.isKeyDown("down")) { setLocation(getX(), getY() + 1); } } } greenfoot accepts it but when i run it, the man doesn't move. i have also tried it without the code to move at the bottom but it still doesn't work.
danpost danpost

2012/6/22

#
You should not have the code at the bottom; and it should work, unless there is a problem elsewhere. The only thing I can think of, at the moment, that would prevent the man from moving is if he was added to the world within a wall or a wall was added on top of him; but there could be other reasons, I guess. The code you just posted is in the Man class (if that is what you called it)? The code I provided has been checked and works properly.
crazyjack12 crazyjack12

2012/6/22

#
use mine dan's code is too complex :D
You need to login to post a reply.