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

2017/12/21

Impassible Walls

jett jett

2017/12/21

#
I'm trying to make a game for the class I'm in and I'm having trouble preventing the player from passing through a wall without stopping the game. I'd like it to get to the wall, not be able to move through it and lose a life. I know I can subtract from the X or Y value but it would have to depend on the location of the player. Here is my code:
public void move()
        {
          if (Greenfoot.isKeyDown("up"))   //Move UP one "square" 
            {      
                    setLocation(getX(), getY() - 3); 
                    walkFrame++;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
            } 
          if (Greenfoot.isKeyDown("down"))   //Move down one "square" 
            {      
                    setLocation(getX(), getY() + 3); 
                    walkFrame++;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                } 
          if (Greenfoot.isKeyDown("right"))   //Move right one "square" 
            {      
                    setLocation(getX() + 3, getY()); 
                    walkFrame++;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                } 
          if (Greenfoot.isKeyDown("left"))   //Move left one "square" 
            {      
                    setLocation(getX() - 3, getY());       
                    walkFrame++;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                }   
        }
    public void checkCollision(){
        int originalX = getX();
        int originalY = getY();
        if(getOneIntersectingObject(Wall.class) != null || getOneIntersectingObject(Block.class) != null){
            // where i plan to place the move back code
            Greenfoot.playSound("hurt.wav");
            lives--;
        }
    }
danpost danpost

2017/12/21

#
What is the code to the act method?
jett jett

2017/12/21

#
danpost wrote...
What is the code to the act method?
public void act() 
    {
        move();
        checkCollision();
        homeTouched();
    }    
jett jett

2017/12/21

#
Okay so I changed some things around in the act method and the move method. However, it is not working when I approach the wall at an angle.
    public void act() 
    {
        if(hit == true){
            if(right == true){
                setLocation(getX() - 3, getY());
                hit = false;
            }
            else if(left == true){
                setLocation(getX() + 3, getY());
                hit = false;
            }
            else if(down == true){
                setLocation(getX(), getY() - 3);
                hit = false;
            }
            else if(up == true){
                setLocation(getX(), getY() + 3);
                hit = false;
            }
        }
        else{
            move();
        }
        checkCollision();
        homeTouched();
    }    
    public void move()
        {
          if (Greenfoot.isKeyDown("up"))   //Move UP one "square" 
            {      
                    setLocation(getX(), getY() - 3); 
                    walkFrame++;
                    up = true;
                    left = false;
                    right = false;
                    down = false;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
            } 
          if (Greenfoot.isKeyDown("down"))   //Move down one "square" 
            {      
                    setLocation(getX(), getY() + 3); 
                    walkFrame++;
                    down = true;
                    left = false;
                    right = false;
                    up = false;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                } 
          if (Greenfoot.isKeyDown("right"))   //Move right one "square" 
            {      
                    setLocation(getX() + 3, getY()); 
                    walkFrame++;
                    right = true;
                    left = false;
                    down = false;
                    up = false;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                } 
          if (Greenfoot.isKeyDown("left"))   //Move left one "square" 
            {      
                    setLocation(getX() - 3, getY());       
                    walkFrame++;
                    left = true;
                    right = false;
                    down = false;
                    up = false;
                    if(walkFrame == 15){
                        setImage(walk2);
                    }
                    else if(walkFrame == 30 ){
                        setImage(walk1);
                        walkFrame = 0;
                    }
                }   
        }
    public void checkCollision(){
        if(getOneIntersectingObject(Wall.class) != null || getOneIntersectingObject(Block.class) != null){
            hit = true;
            Greenfoot.playSound("hurt.wav");
            lives--;
        }
    }
danpost danpost

2017/12/21

#
jett wrote...
danpost wrote...
What is the code to the act method?
public void act() 
    {
        move();
        checkCollision();
        homeTouched();
    }    
This is before your moving things around. What I see here is that you move and then check for collision. But the 'originalX' and 'originalY' are acquired after moving; so, it is like -- good luck moving back. That is, they acquire the new coordinates of the actor -- not the original ones.. Now, with the new code, I see you checking collision before moving. How is this to work if the actor is to stay off of the walls and blocks ?! You need to attack the problem with a planned strategy. Obviously, the actor needs to move before collision checking is done. Also, you need to save the original location of the actor before it moves (or at least save the change in horizontal and vertical position) so you can move back if a collision is indeed detected. Both in your original code and in the revised code, there is a lot of repetition of code. Also, the added booleans in the revised code just makes things worse. Think about what happens if more than one key is down. You set a boolean in one block and destroy it in another. If adjacent keys are detected, the actor will move diagonally, but retreat off an intersecting object horizontally, allowing the actor to pass vertically through another object. Another thing to note is as the actor is "pressed" on an object, multiple act cycles will occur, meaning that, as coded, lives will zip off quickly as the detection of a pressed key will continue over several act steps. The reduction of lives is something that will need to be more strictly controlled. To start, I will provide a better way to detect the movement keys:
// variables needed for movement
int dx = 0; // for horizontal movement direction
int dy = 0; // for vertical movement direction
// detecting movement keys
if (Greenfoot.isKeyDown("up")) dy--;
if (Greenfoot.isKeyDown("down")) dy++;
if (Greenfoot.isKeyDown("left")) dx--;
if (Greenfoot.isKeyDown("right")) dx++;
// if no movement, do nothing more
if (dx == 0 && dy == 0) return;
// move
setLocation(getX()+3*dx, getY()+3*dy);
// walk animation
walkFrame = (walkFrame+1)%30;
if (walkFrame == 0) setImage(walk1);
if (walkFrame == 15) setImage(walk2);
This would be followed by collision checking:
if (isTouching(Wall.class) || isTouching(Block.class))
where, if touching, the actor is moved back (using 'dx' and 'dy') and, if was not touching on last act step, play "hurt" sound and decrement lives. The value of lives should then be immediately checked to see if life still exists.
You need to login to post a reply.