Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (482)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (548)
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  
  One of Those Collision Threads  (Read 1851 times)
0 Members and 1 Guest are viewing this topic.
Offline RylandAlmanza

Junior Member


Medals: 3



« Posted 2012-02-07 21:21:14 »

So I'm trying to make collision work in my platformer. I have a player entity, and a collision component that I'm adding to the entity. Here's the update function in the collision component:

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  
    @Override
    public void update(GameContainer gc, StateBasedGame sb, int delta) {
        Vector2f position = owner.getPosition();
       
        position.x += owner.getVelocity().x;
        rect.setLocation(position);
        for (int i = 0; i < map.getWidth(); i++) {
            for (int j = 0; j < map.getHeight(); j++) {
                if (map.getTileId(i, j, 0) > 0) {
                    Rectangle tileRect = new Rectangle(i*16, j*16, 16, 16);
                   
                    if (rect.intersects(tileRect)) {
                        if (owner.getVelocity().x < 0) {
                            position.x = tileRect.getX()+tileRect.getWidth();
                        }
                        if (owner.getVelocity().x > 0) {
                            position.x = tileRect.getX()-rect.getWidth();
                        }
                        rect.setLocation(position);
                    }
                }
            }
        }
       
        position.y += owner.getVelocity().y;
        rect.setLocation(position);
        for (int i = 0; i < map.getWidth(); i++) {
            for (int j = 0; j < map.getHeight(); j++) {
                if (map.getTileId(i, j, 0) > 0) {
                    Rectangle tileRect = new Rectangle(i*16, j*16, 16, 16);
                   
                    if (rect.intersects(tileRect)) {
                        if (owner.getVelocity().y < 0) {
                            position.y = tileRect.getY()+tileRect.getHeight();
                        }
                        if (owner.getVelocity().y > 0) {
                            position.y = tileRect.getY()-rect.getHeight();
                        }
                        rect.setLocation(position);
                    }
                }
            }
        }
       
        owner.setPosition(position);
       
    }


If you're having trouble understanding what the code does, here's some pseudo code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
-Move the player's Rectangle across the x axis according to the players x velocity
-Check to see if the player's Rectangle collides with any of the tiles' rectangles
-if it does:
    -if the player is going left:
        -set the player'
s x position to be just right of the tile
    -if the player is going right:
        -set the player's x position to be just left of the tile

-Move the player's Rectangle across the x axis according to the player's y velocity
-Check to see if the player's Rectangle collides with any of the tiles' rectangles
-if it does:
    -if the player is going up:
        -set the player'
s y position to be just below the tile
    -if the player is going down:
        -set the player's y position to be just above the tile


This works well until I start moving the player across the x-axis. When the player moves right or left, suddenly the player is shot to the edge of the very left tile in the row. Anyone know how to fix this?

Offline UprightPath
« Reply #1 - Posted 2012-02-07 22:34:09 »

Try setting the y position at the same time you're setting the x.

Otherwise, your entity is starting out at a y = 0, which will always intersect anything in your array at height = 0.

Offline ra4king

JGO Kernel


Medals: 345
Projects: 2
Exp: 5 years


I'm the King!


« Reply #2 - Posted 2012-02-07 23:03:23 »

Why can't you just combine them into 1 set of double for loops? The above code takes twice as long and twice as much memory than it should Smiley

EDIT: Also, your player gets shot to the end because you keep looping to the end. You check intersection against each and every tile on the map! Shouldn't you be only checking against the tile that you moved to?

1  
2  
3  
4  
//apply velocities to X and Y

if(map.getTileId(position.x/16,position.y/16) > 0 && /* check for rect v rect collision */)
    //you intersected, move back

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Embedded

Junior Member


Medals: 1



« Reply #3 - Posted 2012-02-07 23:20:10 »

Only way i could get it to work is to make two collison methods to check X and then Y collision separately,  if x returned true the player moved x and if y = true then player.moveY..

The meathods create a temporary variable which represents where the player will be, for the x method for example
int newX = player.getX() + player.getVelY()
work out where he is on the grid by divison to work out the tile he is on. Work out a tile for each corner of the player e.g. the top left point, on 64x64 tiles
tileTopLeftPointX = newX/64;
tileTopRightPointY = player.getY()/64; // as this is just checking x collision player.getY() is just as it is

Then if this new tile is solid that means if the player moves he will be colliding with something so return the meathod false so the player doesnt move.
To stop the player from having a gap between him and the wall hes walking into if he has a high x velocity try to find the minmum x velocity the player could have moved and not intersect with the tile, if this is found then set the player velocty X to this value so he will squish against the wall, you can change how accurate you want it to be e.g.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
if(tiles[i][p].isSolid()){          // where i, p are integers worked out previously of the tile the top left player point is currently on
           if(tiles[i][p].getBounds().contains(topLeftX, topLeftY)){
               while(!(nDX > -0.2 && nDX < 0.2)){ // so if velocity is between here stop the loop becuase it is negligable
                 if(nDX > 0){
                     nDX -= 0.02;    //you could change the 0.02 smaller or larger to make it more or less accurate
                 }else if(nDX < 0){
                     nDX += 0.02;
                  }
                  topLeftX = (int) (player.getX() + nDX); // store where the player would be to see if he can now move
                 if(!(tiles[i][p].getBounds().contains(topLeftX, topLeftY))){ // if he can move set his velocity and return true to move x
                    player.setDX(nDX);
                     return true;
                  }
               }
               return false; // the while loop broke meaning he is close to the wall
           }else if // check the other points around the player for collision as say the bottom right of the player rect may be one a diffrent tile


Offline RylandAlmanza

Junior Member


Medals: 3



« Reply #4 - Posted 2012-02-08 05:33:12 »

Why can't you just combine them into 1 set of double for loops? The above code takes twice as long and twice as much memory than it should Smiley
I was trying to port this python code to java. This code worked perfectly in python.

EDIT: Also, your player gets shot to the end because you keep looping to the end. You check intersection against each and every tile on the map! Shouldn't you be only checking against the tile that you moved to?

1  
2  
3  
4  
//apply velocities to X and Y

if(map.getTileId(position.x/16,position.y/16) > 0 && /* check for rect v rect collision */)
    //you intersected, move back

If I understand correctly, this assumes that the player has the same dimensions as my tiles (16x16,) but my player is actually 39x60 pixels. Will this still work?
Offline UprightPath
« Reply #5 - Posted 2012-02-08 06:00:37 »

Bwarg! Don't use 'magic' constants please. It makes things difficult to read/edit at times (In other words, make the replace the various 16 with an int variable equal to 16, perhaps two, to ensure that you can easily update things later.)

If I read it correctly, that will not work if your character is larger than the tile size. Since it will only return a single object (That's located at some corner/position relative to your character).



My advice? Check what your position is prior to that. And find out which block is actually causing you to jump to the left side. That will at least tell you which block is giving you an odd result. Collect some other data as well, see if there's some odd value of speed that is causing it. If you can tell us what your map looks like and which of the blocks is causing your algorithm to break, we can probably give you better input on the 'why'.

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.

atombrot (27 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (61 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (37 views)
2014-08-06 19:49:38

BurntPizza (67 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!