Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (522)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (590)
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 again. Good detection system.  (Read 3277 times)
0 Members and 1 Guest are viewing this topic.
Offline Szinek

Senior Newbie





« Posted 2012-09-08 16:05:59 »

Hi, I'm working on gravity-based logic game. Please, look at this gif:
Click to Play

Lower and upper rectangles detect collision correctly, but as you can see left-right is the problem. I have no idea how to fix it.
My check() method is called from game loop.
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  
   public void check() {
      man_CenterX = (int) game.man.getBounds().getCenterX();
      man_CenterY = (int) game.man.getBounds().getCenterY();
      for (int i = 0; i < game.level1.getX().size(); i++) {
         System.out.println(i + " " + intersects);
         lvl_CenterX = (int) game.level1.getBounds(i).getCenterX();
         lvl_CenterY = (int) game.level1.getBounds(i).getCenterY();
         intersects = game.man.getBounds().intersects(game.level1.getBounds(i));
         if (intersects) {
            if (man_CenterY - lvl_CenterY > 0) {
               game.man.setY(3);
               System.out.println("HEJ1");
            //   break;
            } else if (man_CenterY - lvl_CenterY < 0) {
               game.man.setY(-3);
               System.out.println("HEJ2");
               //break;
            } else if (man_CenterX - lvl_CenterX > 0) {
               game.man.setX(-3);
               System.out.println("HEJ3");
            //   break;
            } else if (man_CenterX - lvl_CenterX < 0) {
               game.man.setX(3);
               System.out.println("HEJ4");
            //   break;
            }
         }
      }
   }
Offline UprightPath
« Reply #1 - Posted 2012-09-08 16:22:41 »

Ah, tell us what's printing out from your print statements as well next time (They're giving some important debug data there.)

Further, this code snippet doesn't tell us everything we need to know:How are you figuring out the center? Is it grid based, something else? What's the units for it? How does it equate to the number of pixels on the screen.

General advice: If you're allowing diagonal movement, separate the X intersections from the Y intersections, otherwise, you're liable to have the Xs become unreachable.

Offline Szinek

Senior Newbie





« Reply #2 - Posted 2012-09-08 17:46:48 »

I split (splitted, splote? No idea Emo) check() method into two:
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  
   public void checkX() {
      System.out.println("X" + intersectsX);
      man_CenterX = (int) game.man.getBounds().getCenterX();
      for (int i = 0; i < game.level1.getX().size(); i++) {
         lvl_CenterX = (int) game.level1.getBounds(i).getCenterX();
         intersectsX = game.man.getBounds().intersects(game.level1.getBounds(i));
         if (intersectsX) {
            if (man_CenterX - lvl_CenterX > 0) {
               game.man.setX(3);
            //    break;
            } else if (man_CenterX - lvl_CenterX < 0) {
               game.man.setX(-3);
            //    break;
            }
         }
      }
   }

   public void checkY() {
      System.out.println("Y" + intersectsY);
      man_CenterY = (int) game.man.getBounds().getCenterY();
      for (int i = 0; i < game.level1.getY().size(); i++) {
         lvl_CenterY = (int) game.level1.getBounds(i).getCenterY();
         intersectsY = game.man.getBounds().intersects(game.level1.getBounds(i));
         if (intersectsY) {
            if (man_CenterY - lvl_CenterY > 0) {
               game.man.setY(3);
               //break;
            } else if (man_CenterY - lvl_CenterY < 0) {
               game.man.setY(-3);
               //break;
            }
         }
      }
   }
}


My game is based on the rectangles, not tiles.

Now gif again. This is happening after splitting the check():
Click to Play
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2012-09-08 18:05:48 »

I split (splitted, splote? No idea Emo) check() method into two:
It's "I split" for present and past so you were correct Smiley

So I'm assuming your problem is fixed? That's usually how you go about checking different axis so you are fine Smiley

Offline Szinek

Senior Newbie





« Reply #4 - Posted 2012-09-08 19:28:27 »

Well, I think I need to get rid of this moving when collision detected on Y-axis. In my game player will be able to change the gravity direction, so there shouldn't be any auto-move while standing on the ground.
Offline Best Username Ever

Junior Devvie





« Reply #5 - Posted 2012-09-08 20:54:25 »

What's the problem? It isn't obvious what is going on.
Offline Szinek

Senior Newbie





« Reply #6 - Posted 2012-09-09 07:51:59 »

Look at the second gif again.
Using WASD I can change the gravity's direction. When player's rectangle collides with left or right wall it works well, doesn't move and stay near (not in) the wall. When gravity is changed on up or down, player's rectangle stops before wall, but it's automatically moving to right or left.
You probably still don't understand me, so here's the "game":
http://www.mediafire.com/?adrhfc1uw2vscfo
Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2012-09-09 08:46:51 »

One think to try out if it is a general collision problem inside one of these methods or another problem is: Try to switch the calls to checkX() and checkY() so you call them in a differnent order.

Also one little thing: please rename some of your methods and variables. I don't quite understand what lvl_CenterX is, and I don't think this is the variable for describing the x mid of the whole level Smiley
And I think setX() should be named moveX(). But all this is not a must do. Other then that this is really good code Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Szinek

Senior Newbie





« Reply #8 - Posted 2012-09-09 11:59:00 »

Also one little thing: please rename some of your methods and variables. I don't quite understand what lvl_CenterX is, and I don't think this is the variable for describing the x mid of the whole level Smiley
lvl_CenterX (and Y) is a center X of every rectangle on the map. When we'll get rid of the problem I should do some refactoring.

Now I'm calling checkY() before checkX() and this is happening:
Click to Play

Upper and lower platform collision works well, but left-right makes player's rectangle... you see, it shouldn't be like that.
Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #9 - Posted 2012-09-09 12:16:45 »

Sorry... I really have no Idea why this is happening... could you maybe post the code for the key handling? maybe there is somewhere a bug... any maybe also post where you do the checkX() and checkY().

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Szinek

Senior Newbie





« Reply #10 - Posted 2012-09-09 12:44:09 »

gameLoop() is called from initialize():
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
   private void gameLoop() {
      timer = new Timer();
      timer.schedule(game, 0, 1000 / 60);
   }

   TimerTask game = new TimerTask() {
      public void run() {
         gravity.pulling();
         collision.checkY();
         collision.checkX();
         repaint();
      }
   };

keyTyped() and pulling() in Gravity:
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  
public void keyTyped(KeyEvent kevt) {
      char c = kevt.getKeyChar();
      if (!game.man.isFalling) {
         if (c == 'w') {
            vspeed = 0;
            gUp = true;
            gDown = false;
            gLeft = false;
            gRight = false;
         } else if (c == 's') {
            vspeed = 0;
            gDown = true;
            gUp = false;
            gLeft = false;
            gRight = false;
         } else if (c == 'a') {
            vspeed = 0;
            gLeft = true;
            gUp = false;
            gDown = false;
            gRight = false;
         } else if (c == 'd') {
            vspeed = 0;
            gRight = true;
            gUp = false;
            gDown = false;
            gLeft = false;
         }
      } else {

      }
   }
   public void pulling() {
      if (gUp) {
         //vspeed += gravity / 2;
         game.man.setY(-3);
      } else if (gDown) {
         //vspeed += gravity / 2;
         game.man.setY(3);
      } else if (gRight) {
         //vspeed += gravity / 2;
         game.man.setX(3);
      } else if (gLeft) {
         //vspeed += gravity / 2;
         game.man.setX(-3);
      }
   }

Offline tarlek

Junior Devvie


Medals: 2
Projects: 1



« Reply #11 - Posted 2012-09-09 13:00:26 »

It might work better if you determine the amount of overlap in both directions. Then you can use that data to move the player back the proper amount (instead of always +-3).

Some sample code adapted from my own collision detection scheme:

edit: you can also just remember the old player position and put it back if there was a collision

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  
    // find overlapping box
    int ix1 = Math.max(bx11, bx12);
    int iy1 = Math.max(by11, by12);
    int ix2 = Math.min(bx21, bx22);
    int iy2 = Math.min(by21, by22);

    int swap;

    if(ix2 < ix1)
    {
      swap = ix1;
      ix1 = ix2;
      ix2 = swap;
    }

    if(iy2 < iy1)
    {
      swap = iy1;
      iy1 = iy2;
      iy2 = swap;
    }

    // return if no overlap
    if(ix2 < ix1 && iy2 < iy1)
      return false;

    // width and height of overlapping area
    int iw = ix2 - ix1;
    int ih = iy2 - iy1;

Offline Best Username Ever

Junior Devvie





« Reply #12 - Posted 2012-09-09 21:55:26 »

You would benefit from having more debugging information on screen. You should use drawString to print the current direction of the gravity and maybe a few other variables or statistics like x velocity, y velocity, etc.
Offline philfrei
« Reply #13 - Posted 2012-09-09 23:01:55 »

I downloaded your game and gave it a run.

So, when the 'man' collides with the box-border on the right, the movement that follows (man starts to move towards bottom) indicates two things:
1) x movement stops, because gravity and the pushback caused by the horizontal border collision code cancel each other out.
2) y movement starts, AS IF the pushback from the vertical border collision code is giving the man a +y movement.

I'm guessing (2) happens again and again because with (1), the collision is triggered over and over each frame.

This is based on the assumption that during the demo action:
(a) you NEVER change the gravity
(b) the only things which move the man are gravity and the pushback when colliding with a wall.

I also observe that the movement, upon collision, is either up or down based on whether the man collides with the right wall above or below its midpoint, which adds to the evidence that the vertical movement is caused by the repeatedly triggered y-checks.

Looking at your "intersection" test: you seem to be using the same test for xIntersects and yIntersects:
1  
game.man.getBounds().intersects(game.level1.getBounds(i));


The only way you might not be getting BOTH an x & y intersect = true each time would be if there were two lists of "bounding rectangles" -- one that can only result from a vertical and one that can only result a horizontal collision, and the segregated collision tests only test for intersection with the appropriate list of boundary boxes.

Hope this analysis helps.

"It's after the end of the world! Don't you know that yet?"
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.

trollwarrior1 (29 views)
2014-11-22 12:13:56

xFryIx (71 views)
2014-11-13 12:34:49

digdugdiggy (50 views)
2014-11-12 21:11:50

digdugdiggy (44 views)
2014-11-12 21:10:15

digdugdiggy (38 views)
2014-11-12 21:09:33

kovacsa (62 views)
2014-11-07 19:57:14

TehJavaDev (67 views)
2014-11-03 22:04:50

BurntPizza (64 views)
2014-11-03 18:54:52

moogie (80 views)
2014-11-03 06:22:04

CopyableCougar4 (79 views)
2014-11-01 23:36:41
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

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
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!