Alright, so I’m having some trouble with collision for a top down Zelda-like game. So far I have a collision box on my player that has to change shape based on his direction or he gets stuck, and while I’m sure I could get this down after a while it would be really ugly, and baddly coded. I had a thought: What if I could use cross products to get my desired collision detection like I did that one time in my 3d game (Thanks to a JGO user who showed me how).
So what I want is this. If the player is going up and left, and hits the bottom of a tile, he continues to go left. Same for right, Down/Left, and Down/Right. All the while using a collision box that is always the same size, and shape (a square).
My question right now isn’t HOW to do this, but rather where I should start, or if it’s even possible/worth it.
I found this tutorial, but it’s based on poly to poly collision (http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/) Should I use this? Or is there a simpler way to achieve what I want?
edit:-------------------------------------------------------------------------
Alright, so I tried something in Slick real quick, and it works kinda, but it only sends you one way, regardless of what your angle was (I.E. when hitting the bottom of a wall going Up/Left it sends you right).
here is the source so far:
package cypri.games.crosscol;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
public class CrossCol extends BasicGame{
Vector2f playerPos;
int size = 32;
float speed = 2.5f;
Rectangle tile;
public CrossCol(String title) {
super(title);
}
public void move(float angle){
Vector2f momentum = new Vector2f((float) (Math.sin(Math.toRadians(angle)) * speed),(float) -( Math.cos(Math.toRadians(angle)) * speed));
Vector2f npos = playerPos.copy();
npos.add(momentum);
Rectangle r = new Rectangle(npos.x, npos.y, size, size);
if(r.intersects(tile)){
momentum = momentum.getPerpendicular();
}
playerPos.add(momentum);
}
@Override
public void render(GameContainer gc, Graphics g) throws SlickException {
g.setColor(Color.white);
g.fillRect(0, 0, 800, 600);
g.setColor(Color.red);
g.fill(tile);
g.setColor(Color.cyan);
g.fillRect(playerPos.x, playerPos.y, size, size);
}
@Override
public void init(GameContainer gc) throws SlickException {
playerPos = new Vector2f(300,300);
tile = new Rectangle(200,200,size, size);
}
@Override
public void update(GameContainer gc, int delta) throws SlickException {
Input input = gc.getInput();
if(input.isKeyDown(Input.KEY_F4)) System.exit(0);
if(input.isKeyDown(Input.KEY_UP)) move(0);
if(input.isKeyDown(Input.KEY_DOWN)) move(180);
if(input.isKeyDown(Input.KEY_LEFT)) move(270);
if(input.isKeyDown(Input.KEY_RIGHT)) move(90);
}
public static void main(String[] args)
throws SlickException
{
AppGameContainer app =
new AppGameContainer(new CrossCol("Test"));
app.setDisplayMode(800, 600, false);
app.setTargetFrameRate(60);
app.start();
}
}