Slick Forums

Discuss the Slick 2D Library
It is currently Wed Nov 20, 2019 12:32 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Oct 21, 2007 5:10 pm 
Offline

Joined: Fri Oct 19, 2007 1:54 am
Posts: 42
Given about Bouncing object:
2 diameter Circle that knows it's x and y location, it's speed(dx and dy), and it know's it's center x and y
Circle knows it's theta where -90 = up, 90 = down, 180 = left, 0 = right.

Collision with TiledMap where:
Ground Layer has tiles that the Circle object can move.
if tileID == 0, Circle must "bounce" to correct angle.

Inherent problems:
The outer ring of the ground layer all have tileIds of 0
A tile who's id is 0 can be alone in the middle of the map, all faces are exposed for collision.
2 tiles who's ids are both 0 can share 1 face, 6 faces are exposed for collision.
In the case of the edges, only 1 face is exposed for collision.

If the Circle hits the left or right of the tile, dx *=-1
If the Circle hits the top or bottom, dy*=-1
If the Circle hit's a corner with a circle-square collision, dx*=-1 and dy*=-1

Some of the solutions I come up with have not worked fully. I'm not posting them as to not limit the solutions just because mine did not work. I'm going to continue to examine mine for flaws, I'm just wondering if anyone else can or has come up with one.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 22, 2007 7:01 pm 
Offline

Joined: Tue Jul 03, 2007 2:43 pm
Posts: 3
Location: Philadelphia, PA USA
Could you clarify a few things?

(1) What's a "2 diameter Circle"? All circles have an infinite number of diameters all of which are exactly the same length. Is this an ellipse? Something else?

(2) Why does a circle "know it's theta"? What does that mean?

(3) I don't quite understand "tiles who's ids are both 0 can share 1 face, 6 faces are exposed for collision". These tiles are square (right?), so each has 4 faces. Two adjacent tiles form a 2x1 rectangle with 4 faces. And it doesn't matter because if two square tiles share a face then a circle (or an ellipse) can only collide with 1 of them.

-- Michael Chermside


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 23, 2007 1:11 am 
Offline

Joined: Tue Oct 23, 2007 1:07 am
Posts: 33
Have a look at this:

http://www.harveycartel.org/metanet/tut ... rialA.html

see section 3 for circle/square


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 23, 2007 3:41 am 
Offline

Joined: Fri Oct 19, 2007 1:54 am
Posts: 42
mcherm wrote:
(1) What's a "2 diameter Circle"? All circles have an infinite number of diameters all of which are exactly the same length. Is this an ellipse? Something else?

What I meant was a circle that has a radius of 1, therefore the diameter is 2.

mcherm wrote:
(2) Why does a circle "know it's theta"? What does that mean?

In some of my early attempts, I allowed the circle to know theta, the angle of which the circle is traveling. I.E theta = 30 means that the circle is traveling at an angle of 30 degrees below the positive horizontal. for some reason, theta is flipped in java so if theta = -30, then it travels at an angle 30 degrees above the positive horizontal


mcherm wrote:
(3) I don't quite understand "tiles who's ids are both 0 can share 1 face, 6 faces are exposed for collision". These tiles are square (right?), so each has 4 faces. Two adjacent tiles form a 2x1 rectangle with 4 faces. And it doesn't matter because if two square tiles share a face then a circle (or an ellipse) can only collide with 1 of them.

What I was referring to was a tiled map. One representation would look like this if it displayed only the tile id. tileID of 0 is meant to represent a place where the circle cannot go.

0 0 0 0 0 0 0
0 x x x x x 0
0 x x x 0 x 0
0 x 0 0 x x 0 // This is the case I am talking about. where there are two 0's
0 x x x x x 0
0 0 0 0 0 0 0

One of my problems occurred where the ball would "slip" in between 2 tiles. It would travel in between them untill it came out of the top. due to the fact that it would only flip dx, and dy would continue to be the same


peabrain wrote:
http://www.harveycartel.org/metanet/tutorials/tutorialA.html

I'm retarded... I would've never look to n game for actual tutorials XD. I'll be sure to look into this. Thanks.

If anyone else has any ideas, please continue to post here.


Last edited by Apache787 on Wed Oct 24, 2007 12:03 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 23, 2007 6:09 pm 
Offline

Joined: Tue Jul 03, 2007 2:43 pm
Posts: 3
Location: Philadelphia, PA USA
Okay, with those clarifications it makes much more sense to me.

First of all, let me say that everything I put down here is completely untested. Following peabrain's link will probably help you more, but it seemed like a nice exercise, so I'm going to try to write up what I would do (but I haven't tested it). I'm going to completely ignore the practical realities of TiledMap and just go ahead and pretend that whatever functions I want are there.

First, some assumptions. Your circle has radius 1 and it interacts with tiles which are in a square grid with side length 1. This means a circle can, at any given instant, overlap with at most 9 tiles (the tile containing the center and the 8 surrounding it) -- a very managable number for simple iteration. If the circle is moving too fast then "terrible things" could happen between one check for overlap and the next -- for instance, it could go straight through a wall and out the other side in between one collision check and the next. If that's a danger you need fancier techniques; I'll assume that it moves slowly enough (or the collision tests are frequent enough) that the circle has time to overlap "just a little". The largest number of overlaps I can imagine at once would be four tiles, which would look like this:

Code:
XXXX   ---
XXXX  /   \
XXXX /     \
XXXX|       |
----|   .   |
XXXX|       |
XXXX \     /
XXXX  \   /
XXXX   ---
    XXXX|XXXX
    XXXX|XXXX
    XXXX|XXXX
    XXXX|XXXX


(The circle was coming down and to the left when it bumped into two walls at once, touching both near a boundary between tiles. It is touching all 8 tiles.) Simpler versions can be made by hitting only one wall and/or hitting in the middle of a tile not on the "crack" between tiles.

Another situation to watch out for is hitting a corner:

Code:
     ---
    /   \
   /     \
  |       |
  |   .   |
  |       |
   \     /
XXXX\   /
XXXX ---
XXXX
XXXX


(And it can also hit corners of two tiles at once, etc.)

Okay, so I've visualized the problem. Now let me start naming things.

Code:
Vx, Vy := velocity of the circle (in x and y components, as floats)
Cx, Cy := center of circle (x and y components, as floats)
Ci, Cj := the integer coordinates of the tile containin the center of the circle


IF the tiles started counting at (0,0) AND they size was 1 in the units that Cx and Cy use, then Ci = (int)Cx and Cj = (int)Cy, but both assumptions are unlikely, so there's some scaling and coordinate offset needed there.

Code:
Tile[i,j] := the tile at position (i,j). For instance Tile[Ci,Cj] contains the center of the circle.

Tile[i,j].solid() := a boolean telling whether the tile has "tileID of 0" (ie, the circle bounces off).


So just checking for overlap would look like this:

Code:
    boolean bouncesOffSomething() {
        for (int i=Ci-1; i<=Ci+1; i++) {
            for (int j=Cj-1; j<Cj+1; j++) {
                if (Tile[i,j].solid()) {
                    return true;
                }
            }
        }
        return false;
    }


Okay, I think I've got the notation down. Let's see if I can solve the problem. I'll consider the x direction first. An overlap with a tile in the column where i=Ci-1 means that we must have come from the right (Vx was negative) and should now bounce away to the right (Vx now positive). A similar argument (but reversed) applies to overlaps with tiles in the column where i=Ci+1. And the reasoning in the y direction works the same way. If the circle overlaps the cell in the middle (at Ci,Cj) then we're in trouble: it must not have overlapped the last time we detected collisions (because then it would have bounced) and so in between it must have traveled at least distance 1 -- much too far for our assumptions to hold.

Notice that I haven't had to check for particular sides of individual tiles -- that's a fortunate side-affect of moving slowly enough (sampling often enough) that the circle moves substantially less than a tile's width in each step.

So I come up with some logic like this:

Code:
    void checkForCollisionsAndChangeCourse(BouncingCircle circle) {
        if (Tile[Ci,Cj].solid()) throw new MovingTooFastException();
   
        boolean bounceRight = false; // does it bounce and head off to the right?
        boolean bounceLeft = false; // does it bounce and head off to the left?
        for (int j=Cj-1; j<Cj+1; j++) {
            if (Tile[Ci-1,j].solid()) {
                bounceRight = true;
            }
            if (Tile[Ci+1,j].solid()) {
                bounceLeft = true;
            }
        }
       
        boolean bounceUp = false; // does it bounce and head off to the right?
        boolean bounceDown = false; // does it bounce and head off to the left?
        for (int i=Cj-1; i<Ci+1; i++) {
            if (Tile[i,Cj-1].solid()) {
                bounceUp = true;
            }
            if (Tile[i,Cj+1].solid()) {
                bounceDown = true;
            }
        }
       
        if (bounceRight && bounceLeft) throw new ImpossiblePositionException();
        if (bounceUp && bounceDown) throw new ImpossiblePositionException();
       
        if (bounceRight || bounceLeft) circle.setVx(circle.getVx()*-1);
        if (bounceUp || bounceDown) circle.setVy(circle.getVy()*-1);
    }


Anyway, that's what I came up with. It was a fun exercise... if you do try to use it, let me know how it went.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 24, 2007 12:29 am 
Offline

Joined: Fri Oct 19, 2007 1:54 am
Posts: 42
Hmm... Both of the solutions look promising, and since I'm in no rush, I guess I'll see what happens after implementing it


Top
 Profile  
 
PostPosted: Fri Sep 06, 2019 9:26 am 
Offline

Joined: Thu Sep 05, 2019 11:34 am
Posts: 1
I'll also try to implement it. Let's see what happens


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: MSN [Bot] and 221 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:  
cron
Powered by phpBB® Forum Software © phpBB Group