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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| 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(); }
} |