Slick Forums

Discuss the Slick 2D Library
It is currently Tue May 21, 2013 9:38 am

All times are UTC




Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Jan 22, 2012 12:30 pm 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
So a sidescroller...
The problem here is the collisiondetection. I made it somehow to run it but there is
one annyoing bug:

http://staxx6.bplaced.net/bilder/bug.jpg

You see there are 4 Collision areas (and +1 vor Slopes). The red arrow show the
problem, rarely you jump on the create corner and you cant move left or fall down.
The red rectangel say you can't fall and the blue say you can't move left.

Any suggestion how to improve this?

_________________
.


Top
 Profile  
 
PostPosted: Sun Jan 22, 2012 10:56 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
I would suggest arranging your shapes so that they do not have indents on the corners. Alternatively, you could use just one rectangle for your collision detection. However, the most common solution to resolving this kind of collision is to handle the first character collision, and then the second, then the third, and then handle them all one more time. This will likely give you a fairly realistic collision that, while not completely accurate, will probably end up moving the falling block to the right just enough to keep it and the character from colliding.

Of course, if you wanted to throw caution to the wind, you could use JBox2D, or Fizzy. I'll admit that JBox2D is really difficult to work with, so I understand why you would make your own collision handling.

Does this help?

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Tue Jan 24, 2012 9:13 pm 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
Cant remove the indents beacause on the ground it would say: "Collision with left and the lower Shape". And scaling it down "only" the chance decrease but not total kill the problem.
Sure one shape is better but how i suppose to do this? How i locate the direction from the collision? That was my problem at beginning and the activator for my solution now. :)

I would love physiks in my game, but jbox2d etc. lacks of tutorials. Im new to java so the Api only is hard for me and take a long time.

_________________
.


Top
 Profile  
 
PostPosted: Wed Jan 25, 2012 5:19 am 
Offline

Joined: Fri Jan 13, 2012 10:19 pm
Posts: 27
I'm not sure why you have 4 boxes for the 4 edges of your character. Why not just have one polygon? I was able to create a very simple and easy collision detector just by using intersect() to test if any polygons overlap... http://slick.cokeandcode.com/javadoc/org/newdawn/slick/geom/Shape.html#intersects(org.newdawn.slick.geom.Shape)

_________________
http://www.wrapperapps.com
for more info on Prime Mover, my first game based on Java/Slick 2D.


Top
 Profile  
 
PostPosted: Wed Jan 25, 2012 6:11 am 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
@deviouskoopa

staxx6 wrote:
Cant remove the indents beacause on the ground it would say: "Collision with left and the lower Shape". And scaling it down "only" the chance decrease but not total kill the problem.
Sure one shape is better but how i suppose to do this? How i locate the direction from the collision? That was my problem at beginning and the activator for my solution now. :)

I would love physiks in my game, but jbox2d etc. lacks of tutorials. Im new to java so the Api only is hard for me and take a long time.

_________________
.


Top
 Profile  
 
PostPosted: Wed Jan 25, 2012 1:45 pm 
Offline

Joined: Fri Jan 13, 2012 10:19 pm
Posts: 27
Oh ok haha, my bad. I don't think the direction should matter. Just update the location of your polygon as the direction is input by the player. Then check if the player's polygon intersects with any of the crates/ground/etc's polygons. If it doesn't then prevent the polygons from overlapping by keeping the player's polygon on the collided item's polygon's edge. Does that make sense? Sorry I'm not the most articulate or helpful haha...

_________________
http://www.wrapperapps.com
for more info on Prime Mover, my first game based on Java/Slick 2D.


Top
 Profile  
 
PostPosted: Wed Jan 25, 2012 5:18 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
If you need to figure out the direction of collision of a single polygon, you can check how much each side overlapps with the other object, and choose the smallest error direction as the collision direction. I could barely understand myself when I typed that, so here is an example of what this code might look like:

public void handleCollision(Rectangle a, Rectangle b){
if (a.getX()+a.getWidth>b.getX()&&//if a is not to the left of b
a.getX()<b.getX()+b.getWidth()&&//and a is not to the right of b
a.getY()+a.getHeight>b.getY()&&//and if a is not above b
a.getY()<b.getY()+b.getHeight())//and a is not below b
{//then these rectangles intersect.

//now see which edges are the closest
float overlapLeft=Math.abs(a.getX()+a.getWidth-b.getX());//the left edge of a
float overlapRight=Math.abs(a.getX()-(b.getX()+b.getWidth()));//the right edge of a
float overlapUp=Math.abs(a.getY()+a.getHeight-b.getY());//the top of a
float overlapDown=Math.abs(a.getY()<(b.getY()+b.getHeight()));//the bottom of a
float minOverlap=Math.min(overlapLeft,overlapRight,overlapUp,overlapDown);//the smallest of these
if (minOverlap==overlapLeft){
//Here is what you do if a is hitting on the left side
}
}
}

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Wed Jan 25, 2012 5:32 pm 
Offline

Joined: Fri Jan 13, 2012 10:19 pm
Posts: 27
Mr. Kenkron wrote:
public void handleCollision(Rectangle a, Rectangle b){
if (a.getX()+a.getWidth>b.getX()&&//if a is not to the left of b
a.getX()<b.getX()+b.getWidth()&&//and a is not to the right of b
a.getY()+a.getHeight>b.getY()&&//and if a is not above b
a.getY()<b.getY()+b.getHeight())//and a is not below b
{//then these rectangles intersect.


With rectangles, or any shapes, you can just use intersect() instead of all that.

Mr. Kenkron wrote:
//now see which edges are the closest
float overlapLeft=Math.abs(a.getX()+a.getWidth-b.getX());//the left edge of a
float overlapRight=Math.abs(a.getX()-(b.getX()+b.getWidth()));//the right edge of a
float overlapUp=Math.abs(a.getY()+a.getHeight-b.getY());//the top of a
float overlapDown=Math.abs(a.getY()<(b.getY()+b.getHeight()));//the bottom of a
float minOverlap=Math.min(overlapLeft,overlapRight,overlapUp,overlapDown);//the smallest of these
if (minOverlap==overlapLeft){
//Here is what you do if a is hitting on the left side
}
}
}


That could work (I don't have time to test it), but here is the code I had for determining direction of polygon collision:

Code:
      if(polyCam.getMaxX() < polyPlayer.getMinX())
      {
        //player is off screen to right
      }
      else if(polyCam.getMinX() > polyPlayer.getMaxX())
      {
        //player is off screen to left
      }
     
      if(polyCam.getMaxY() < polyPlayer.getMinY())
      {
        //player is off screen to bottom
      }
      else if(polyCam.getMinY() > polyPlayer.getMaxY())
      {
        //player is off screen to top
      }


I hope one of these methods works for you!

_________________
http://www.wrapperapps.com
for more info on Prime Mover, my first game based on Java/Slick 2D.


Top
 Profile  
 
PostPosted: Thu Jan 26, 2012 6:29 pm 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
Quote:
Code:
      if(polyCam.getMaxX() < polyPlayer.getMinX())
      {
        //player is off screen to right
      }
      else if(polyCam.getMinX() > polyPlayer.getMaxX())
      {
        //player is off screen to left
      }
     
      if(polyCam.getMaxY() < polyPlayer.getMinY())
      {
        //player is off screen to bottom
      }
      else if(polyCam.getMinY() > polyPlayer.getMaxY())
      {
        //player is off screen to top
      }



this seems like good code for detecting when something is (as you comment) offscreen, or outside of a box, but I think staxx6 is looking for collisions between two boxes, that is, when tow boxes are not outside of each other. Thus code of the form:
Code:
      if(polyCam.getMaxX() < polyPlayer.getMinX())
      {
        //player is off screen to right
      }

wouldn't be effective. If two polygons were colliding on the right side, then by nature, the first one's maxX would be greater than the second one's minX.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Fri Jan 27, 2012 1:01 am 
Offline

Joined: Fri Jan 13, 2012 10:19 pm
Posts: 27
Mr. Kenkron wrote:
... If two polygons were colliding on the right side, then by nature, the first one's maxX would be greater than the second one's minX.


Yes that is correct, sorry for the confusion; I meant that those could be modified for 2 colliding polygons but didn't explicitly say so.

For example:
Code:
if(polyCrate.getMaxX() < polyPlayer.getMaxX())
{
//player is on the right side of the crate
}


I hope this is clearer now, my bad!

_________________
http://www.wrapperapps.com
for more info on Prime Mover, my first game based on Java/Slick 2D.


Top
 Profile  
 
PostPosted: Sat Jan 28, 2012 6:34 pm 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
heyo,

thank you for the help! So I tried a litte bit with the methode:

Code:
float overlapLeft = Math.abs(getX() + 32 - 300); //the left edge of a
...
if(minOverlap == overlapRight) {
   collision = true;
}


For the left and right side it work nice, but starting with the up/down collision there is a prob..
http://staxx6.bplaced.net/bilder/bug2.jpg
The player stuck on left/right.

I show you a part from my player code (Hope dont cut to many things):
http://pastebin.com/S5pqTycZ

EDIT: Understandable that this happen but hmmm, now? :D

_________________
.


Top
 Profile  
 
PostPosted: Sun Jan 29, 2012 2:24 am 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
I think I see the problem. You have separate minOverlaps for the y axis and x axis collisions. This means that it will have collisions on the y axis and x axis for each shape. You should have one minOverlap variable that is the smallest of any direction, so that the collision can only happen on one side of a square at once. In your example, the player and the box should collide on only the right side of the player. However, the box is closer to the bottom than the top. Because you have it comparing the y axis collisions separately, the code doesn't realize that the two boxes are already touching on the right side, and the right side is clearly the one that has the smallest overlap.

by the way your comment about how bad making four separate methods is correct. You currently have it so that collisions are handled only in the direction that your player is moving. It would be cleaner, and probably faster, to handle input first, then perform collisions for all sides in a single method.

Code:
         /* Check collision with hardcoded Shape */
         private void checkCollisionAll() {
                boolean collision = false;
               
                if(collisionArea.intersects(testShape)) {
                        System.out.println("Jup!");
                       
                        float overlapLeft = Math.abs(getX() + 32 - 300); //the left edge of a
                        float overlapRight = Math.abs(getX()-( 300 + 100)); //the right edge of a
                        float overlapUp = Math.abs(getY() + 64 - (-100)); //the top of a
                        float overlapDown = Math.abs(getY() - ((-100) + 100)); //the bottom of a
                        float minOverlap1 = Math.min(overlapLeft, overlapRight);
                        float minOverlap2 = Math.min(overlapUp, overlapDown);
                       
                        if(minOverlap1 == overlapRight) {
                                x=testShape.getMinX()-(width of player);
                        }
                        if(minOverlap1 == overlapLeft) {
                                x=testShape.getMaxX();
                        }

                        if(minOverlap1 == overlapUp) {
                                x=testShape.getMinX()-(h of player);
                        }
                        if(minOverlap1 == overlapDown) {
                                x=testShape.getMaxX();
                        }
                }
        }


BTW, I think overlapLeft and overlapRight are switched in your code. Same with up and down. Hope this helps.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
PostPosted: Sun Jan 29, 2012 12:21 pm 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
I will test it later, thank you!
OverlapRight / Left is switched because for the player is box.left = player.right collision or so.
Hm, u know :P

_________________
.


Top
 Profile  
 
PostPosted: Mon Jan 30, 2012 6:50 pm 
Offline
User avatar

Joined: Thu Oct 27, 2011 5:30 pm
Posts: 42
Left and Right sides works fine...
But on the top it isnt every time collision "up". Hard to explain, so

I made a runable (.Batch data - Windows) Game:
http://staxx6.bplaced.net/filemanager/W ... tversions/
("R" for respawn)

The part of Code:

Code:
   private int checkCollision() {
      int colli = 0;
      
      if(collisionArea.intersects(testShape)) {
         System.out.println("TEST!");
         
         float overlapLeft = Math.abs(getX() + 32 - 300);
         float overlapRight = Math.abs(getX()-( 300 + 100));
         float overlapUp = Math.abs(getY() + 64 - (-100));
         float overlapDown = Math.abs(getY() - ((-100) + 100));
         float minOverlap1 = Math.min(overlapLeft, overlapRight);
         float minOverlap2 = Math.min(overlapUp, overlapDown);
         float minOverlap = Math.min(minOverlap1, minOverlap2);
         
         if(minOverlap == overlapRight) {
            System.out.println("Rechts"); //Right
            colli = 1;
         }
         if(minOverlap == overlapLeft) {
            System.out.println("Links"); //Left
            colli = 2;
         }
         if(minOverlap == overlapUp) {
            System.out.println("Oben"); //Up
            colli = 3;
         }
         if(minOverlap == overlapDown) {
            System.out.println("Unten"); //Down
            colli = 4;
         }
      }
      return colli;
   }


I calculated the position player: x = 280; y = -90
overlapUp = 74
overlapLeft = 120

Up win :) and its correct for my needs but the game say other things...

_________________
.


Top
 Profile  
 
PostPosted: Tue Jan 31, 2012 4:46 am 
Offline
Oldbie
User avatar

Joined: Thu Jan 13, 2011 4:42 pm
Posts: 349
actually, based on your code, if x=280, then overlapLeft=280+32-300=12. Can you compile your source into a jar for me to run? the zip file contained only source files, and I am currently between computers.

_________________
"Artificial intelligence will never be a match for human stupidity" - "Jamos Kennedynos"


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group