ESipalis
ESipalis

Reputation: 431

Collision detection - preventing player from moving after he hits object

I have the following code:

if(input.isKeyDown(Input.KEY_RIGHT)){
  player = movingRIGHT;
  pposX -= 0.15f;
  if(playerR.intersects(rec1)){
    pposX += 0.15f;
  }
}

if(input.isKeyDown(Input.KEY_LEFT)){
  player = movingLEFT;
  pposX += 0.15f;
  if(playerR.intersects(rec1)){
    pposX -= 0.15f;
}

And two players - playerR and rec1:

playerR = new Rectangle(shiftX-174,shiftY+200,player.getWidth(),player.getHeight());
rec1 = new Rectangle(448+pposX, 640-128+pposY, 32, 32);

My player doesn't stop after he hits the wall. I wanted to know if coordinates are good enough, so I tried do draw rectangles at exactly same coordinates without problem. However, my player just goes through.

I'm using java slick2d with this code:

package javagame;

import org.lwjgl.input.Mouse;
import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class Play extends BasicGameState {

Animation player,movingUP,movingDOWN,movingLEFT,movingRIGHT;
Image worldMap;
Image cat;
boolean quit = false;
int [] duration = {200,200,200,200};
int [] duration2 = {200,200};
float pposX;
float pposY;
float shiftX = pposX + 430;
float shiftY = pposY + 320;
float height;
int x = 0;
int y = 0;
boolean jumping = false;
float verticalSpeed;
float mapPosX = 0;
float mapPosY = 0;
Rectangle rec1;
Rectangle rec2;
Rectangle rec3;
Rectangle rec4;
Rectangle rec5;
Rectangle rec6;
Rectangle rec7;
Rectangle rec8;
Rectangle playerR;
boolean Win;
String a = "Victory!";
public Play (int state){

}

public void init(GameContainer gc,StateBasedGame sbg) throws SlickException{
    worldMap = new Image("res/map.png");
    Image[] walkUp = {new Image("res/buckysBack.png") , new Image("res/buckysBack.png")};
    Image[] walkLeft = {new Image("res/1L.png") , new Image("res/2L.png"), new Image("res/3L.png"), new Image("res/4L.png")};
    Image[] walkRight = {new Image("res/1R.png") , new Image("res/2R.png"), new Image("res/3R.png"), new Image("res/4R.png")};
    Image[] walkDown = {new Image("res/buckysFront.png") , new Image("res/BuckysFront.png")};


    movingLEFT = new Animation(walkLeft , duration , true);
    movingRIGHT = new Animation(walkRight,duration,true);
    movingUP = new Animation(walkUp,duration2,false);
    movingDOWN = new Animation(walkDown,duration2,false);

    rec1 = new Rectangle(448+pposX, 640-128+pposY, 32, 32);
    rec2 = new Rectangle(480,640-160,32,32);
    rec3 = new Rectangle(512,640-192,64,32);


    player = movingRIGHT;
}

public void render(GameContainer gc,StateBasedGame sbg,Graphics g)throws SlickException{
    worldMap.draw(pposX,pposY);
    player.draw(shiftX-174,shiftY+200);
    g.drawRect(448+pposX, 640-128+pposY, 32, 32);
    g.drawRect(shiftX-174,shiftY+200,player.getWidth(),player.getHeight());
    g.setColor(Color.blue);
    g.drawString("Your position x: " + pposX * -1 + "\n              y: " + pposY  , 600, 30);
    int mx = Mouse.getX();
    int my = Mouse.getY();
    g.drawString("Your mouse x: " + mx + "y: " + my, 400,400);
    playerR = new Rectangle(shiftX-174,shiftY+200,player.getWidth(),player.getHeight());


    if(quit == true){
        g.drawString("Resume(R)", sbg.getContainer().getWidth()/2, 100);
        g.drawString("Main Menu(M)", sbg.getContainer().getWidth()/2, 150);
        g.drawString("Quit(Q)", sbg.getContainer().getWidth()/2, 200);
        if(quit==false){
            g.clear();
        }
    }
    if(Win){
        g.setColor(Color.red);
        g.drawString(a,sbg.getContainer().getWidth()/2 - a.length()/2,300);
    }


}

public void update(GameContainer gc,StateBasedGame sbg,int delta)throws SlickException{
    Input input = gc.getInput();

    if(input.isKeyDown(Input.KEY_UP)){
        pposY += 0.15f;
    }
    if(input.isKeyDown(Input.KEY_DOWN)){
        pposY -= 0.15f;
    }

    if(jumping){
        verticalSpeed += .007f * delta;
    }
    pposY += verticalSpeed;



    if(input.isKeyDown(Input.KEY_RIGHT)){
        player = movingRIGHT;
        pposX -= 0.15f;
        if(playerR.intersects(rec1)){
        pposX += 0.15f;
        }
        if(pposX>3100){
            Win = true;
        }
    }
    if(input.isKeyDown(Input.KEY_LEFT)){
        player = movingLEFT;
        pposX += 0.15f;
        if(playerR.intersects(rec1)){
        pposX -= 0.15f;
        }
        if(pposX> -1.5f){
            pposX-= 0.15f;
        }
    }

}
public int getID(){
    return 1;
}
}

How can I get the player to stop at the wall?

Upvotes: 0

Views: 2221

Answers (2)

Daniel Langdon
Daniel Langdon

Reputation: 5999

One very common problem with collisions is one the discrete nature of updates. Since you update the position, it basically teleports, and can do so over the object it should collide with. So check if the step is small enough compared with the area of that and other objects (or walls).

Upvotes: 0

tckmn
tckmn

Reputation: 59273

playerR = new Rectangle(shiftX-174,shiftY+200,player.getWidth(),player.getHeight());

First of all, I have no clue what shiftX is. You have to update the rectangle every frame. Example:

playerR = new Rectangle(pposX, pposY, player.getWidth(), player.getHeight());

Now put that code right before your collision detection. Note that you should store the width and height in a variable to make it faster instead of having to invoke getWidth and getHeight every frame.

Upvotes: 2

Related Questions