Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (475)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (530)
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 3033 times)
0 Members and 1 Guest are viewing this topic.
Offline Szinek

Senior Newbie





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

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

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 18: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 19: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():
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2012-09-08 20: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 21: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 Member





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

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

Senior Newbie





« Reply #6 - Posted 2012-09-09 09: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: 106
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2012-09-09 10: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 13: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:

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: 106
Projects: 3


You think about my Avatar right now!


« Reply #9 - Posted 2012-09-09 14: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 14: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 Member


Medals: 2
Projects: 1



« Reply #11 - Posted 2012-09-09 15: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 Member





« Reply #12 - Posted 2012-09-09 23: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-10 01: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.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
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.

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

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

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

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

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

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

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

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

Riven (48 views)
2014-07-14 18:02:53

OpenGLShaders (38 views)
2014-07-14 16:23:47
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!