Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Collision Detection for tiled map via cross products?  (Read 583 times)
0 Members and 1 Guest are viewing this topic.
Offline CyanPrime
« Posted 2013-01-16 08:04:36 »

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();
    }

}

Offline h3ckboy

JGO Coder


Medals: 5



« Reply #1 - Posted 2013-01-16 09:34:12 »

well, with your current setup it might be a little tricky. This is something I've seen very commonly with people using Slick.

Instead of checking each time which keys are down for movement, you could respond to the events keyPressed and keyReleased, and then set a velocity for your sprite (rectangular form), and then if you run into a wall going up, you just set your y component to zero which won't affect your x component at all.

Does that make sense?
Offline HeroesGraveDev

JGO Kernel


Medals: 238
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #2 - Posted 2013-01-16 09:36:22 »

This may annoy you being so simple. Grin

All you have to do is move by axis.

That means checking x+movex, y
After that, check x, y+movey
(Or vice versa)

Basically what this does is do 2 separate movements (one for each axis) allowing the wall-sliding effect you want.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline CyanPrime
« Reply #3 - Posted 2013-01-16 09:39:22 »

Thanks for the replies, guys. I think I got it  Grin

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  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
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 val, boolean vertical){
      Vector2f momentum = new Vector2f(0,0);
     
      if(!vertical) momentum.x = val;
      else momentum.y = val;
     
      System.out.println("momentum: " + momentum.x + " --- " + momentum.y);
      Vector2f npos = playerPos.copy();
      npos.add(momentum);
     
      Rectangle r = new Rectangle(npos.x, npos.y, size, size);
      if(r.intersects(tile)){
         Vector2f perp = momentum.getPerpendicular();
         Vector2f oldMomentum = momentum.copy();
         
         if(oldMomentum.x < 0) momentum.x = -perp.x;
         else if(oldMomentum.x > 0) momentum.x = perp.x;
         else momentum.x = 0;
         
         if(oldMomentum.y < 0) momentum.y = -perp.y;
         else if(oldMomentum.y > 0) momentum.y = perp.y;
         else momentum.y = 0;
         
      }
     
      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(-2.5f, true);
      if(input.isKeyDown(Input.KEY_DOWN)) move(2.5f, true);
      if(input.isKeyDown(Input.KEY_LEFT)) move(-2.5f, false);
      if(input.isKeyDown(Input.KEY_RIGHT)) move(2.5f, false);
     
   }
   
   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();
    }

}
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (24 views)
2014-07-24 01:59:36

Riven (24 views)
2014-07-23 21:16:32

Riven (18 views)
2014-07-23 21:07:15

Riven (21 views)
2014-07-23 20:56:16

ctomni231 (50 views)
2014-07-18 06:55:21

Zero Volt (45 views)
2014-07-17 23:47:54

danieldean (36 views)
2014-07-17 23:41:23

MustardPeter (39 views)
2014-07-16 23:30:00

Cero (54 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!