GLBasic forum

Main forum => GLBasic - en => Topic started by: AMateus on 2011-Oct-04

Title: Coliision Point
Post by: AMateus on 2011-Oct-04
Hello,

Another weird problem from me lol

I have a ball bouncing around and a platform. I would like to know in which side the ball collide to change the direction accordingly (could be left, right, top or bottom).

Currently the collision based on y is working fine. Problem is when the ball collides with the left or right side of the block. I've tried some ideas taken from chating, but I'm having some problems implementing it. And unfortunately SPRCOLL doesn't give any info about the collision =)

So, has anyone done this before or has some solution/idea?

Thanks,
António
Title: Re: Coliision Point
Post by: backslider on 2011-Oct-04
Hm,

Maybe you could check the collision and if the ball collides you could calculate the angle between the ball and the middle of the box?

cheers
Title: Re: Coliision Point
Post by: Slydog on 2011-Oct-04
Your ball is moving in two directions, one horizontally, and the other vertically.
Do you have two directions variables such as: dirX=1, dirY=1?

I would check one at a time, such as:

Code (glbasic) Select
' X Direction
INC ballX, dirX
IF SPRCOL(1, "ball at new x position") THEN ' We know it collides using this new x position so . . .
  dirX = -dirX ' Reverse the x direction
  INC ballX, dirX ' Undo previous move that collided
ENDIF

' Y Direction
INC ballY, dirY
IF SPRCOL(1, "ball at new y position") THEN ' We know it collides using this new y position so . . .
  dirY = -dirY ' Reverse the y direction
  INC ballY, dirY ' Undo previous move that collided
ENDIF


This way it will reverse the direction no matter what side it collided with.

The dirX and dirY can be any value, which would represent the ball speed in that direction.
Title: Re: Coliision Point
Post by: Crivens on 2011-Oct-04
Or just do the one collision and check the current location against the last ok one. Obvious then which way you are moving and can then respond accordingly.

Cheers
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-04
Quote from: Crivens on 2011-Oct-04
Or just do the one collision and check the current location against the last ok one. Obvious then which way you are moving and can then respond accordingly.

Cheers

Not quite :) If are alway moving in 2 directions in a bouncing ball. So do you collide because you're falling or because you're falling left? ;)

Another solution is to break the ball in 4 sprites (up, down, left and right). But it could lead to a major fps drop, if you are testing 1 ball against 100 or so platforms. Slydog's option is probably the best on, even if I have to change the logic a bit eheh...

Thanks guys, for your help :)
António
Title: Re: Coliision Point
Post by: Crivens on 2011-Oct-04
Ah sorry am a bit ill today and was speed reading. Was thinking more of a move around a maze type effort where you put the object back to the last known good location if you hit a collision. Must get less ill... :)

Why not just box2d and it handle all that?

Cheers
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-04
That was my intention but I had two problems (correct me if I'm wrong):

- The callbacks for collisions are not implemented

- Could not create bounding box for preventing the ball from leaving the screen (left and right - top and bottom I used create ground successfully)

So I give up and now I'm trying to implement it manually.

António
Title: Re: Coliision Point
Post by: Dabz on 2011-Oct-04
Generally, I use array checking for collisions, so, if the ball is at ballX and ballY, I do something like this (Blitz p-code as it uses bit shifting commands Shl and Shr, in GLBasic, you can do the same in INLINE blocks using << or >>):-

Local bx:Int = ballX Shr 5              'If the tiles are 32x32, also, we'll assume the handle to the ball is at the centre
Local by:Int = ballY Shr 5              'Also, this assumes the tilemap is located top left of the screen, with no offsets.

Check centre of the ball, which, you wont really do, but, as an example I'll do something like (Note: No boundary checking either):-

If tileMap[bx,by] = WALL_TILE
' Do something
Endif

Now, what I do, is change that to cover points on the outside edge of the ball, say, 8 points, then, do something like:-

If tileMap[((ballX-15) Shr 5),ballY Shr 5] = WALL_TILE    <------ Check left edge of ball
If tileMap[((ballX+15) Shr 5),ballY Shr 5] = WALL_TILE    <------ Check right edge of ball
If tileMap[ballX Shr 5,((ballY-15) Shr 5)] = WALL_TILE    <------ Check top edge of ball
If tileMap[ballX-15 Shr 5),((ballY+15) Shr 5)] = WALL_TILE    <------ Check bottom edge of ball
etc
etc
etc

You can then use SlyDogs flag way to handle which points are to be used to check collisions, because obviously, if your going left, there's no need to check anything on the right, and vice versa.

People tend to take the water that I use bitshifting, and they try to ram that modern computers can cope to multiplication and division, as in X * 32 or X / 32, but, I've used bitshifting since 8bit, its never failed me, its a cheap optimization that doesn't do any harm, and as such, the above is the exact same way I built my Croco remake here:-

http://www.denathorn-games.net/?page_id=73

Hope that helps! :)

Dabz
Title: Re: Coliision Point
Post by: Slydog on 2011-Oct-05
BTW, GLBasic has bit shifting:
Code (glbasic) Select
ASL()
ASR()
Title: Re: Coliision Point
Post by: Dabz on 2011-Oct-05
Know what it is.... I looked and ruddy looked for bit shifting commands in the docs... Bugger! :D

Dabz
Title: Re: Coliision Point
Post by: matchy on 2011-Oct-05
I've got to try that cool bit shifting.  8)

A suppose an another alternative, like in pool ball rebounds, is to filter the distance and get the angle from and of nearby objects, for example; moving enemies AND angled wall tiles.
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-05
Nice :)

I will also try bit shifting (prototyping is a bliss lol) =)

Last night I give another shot at Box2D and was able to achieve the effect I want to (sort of). Now, if there was Collision Listeners ;)

Thanks,
António
Title: Re: Coliision Point
Post by: ampos on 2011-Oct-05
Quote from: Slydog on 2011-Oct-04
Your ball is moving in two directions, one horizontally, and the other vertically.
Do you have two directions variables such as: dirX=1, dirY=1?

I would check one at a time, such as:

Code (glbasic) Select
' X Direction
INC ballX, dirX
IF SPRCOL(1, "ball at new x position") THEN ' We know it collides using this new x position so . . .
  dirX = -dirX ' Reverse the x direction
  INC ballX, dirX ' Undo previous move that collided
ENDIF

' Y Direction
INC ballY, dirY
IF SPRCOL(1, "ball at new y position") THEN ' We know it collides using this new y position so . . .
  dirY = -dirY ' Reverse the y direction
  INC ballY, dirY ' Undo previous move that collided
ENDIF


This way it will reverse the direction no matter what side it collided with.

The dirX and dirY can be any value, which would represent the ball speed in that direction.

This is the method I used on Krakout and worked fine. Of course, if your surfaces are horizontal or vertical. If there is strange angles...
Title: Re: Coliision Point
Post by: matchy on 2011-Oct-05
Quote from: AMateus on 2011-Oct-05
Last night I give another shot at Box2D and was able to achieve the effect I want to (sort of). Now, if there was Collision Listeners ;)

Well here is my prototype of 3D pool using Box2D and just radius collision needed for sound.

Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-05
@matchy do you use the "sprite bigger than physics body" trick?
Title: Re: Coliision Point
Post by: matchy on 2011-Oct-06
AMateus, I'm not sure what you mean because I use no 2D sprites nor any form of trickery, just texture sprite mapping in 3D.
Title: Re: Coliision Point
Post by: erico on 2011-Oct-06
great prototype you have there!
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-06
Quote from: matchy on 2011-Oct-06
AMateus, I'm not sure what you mean because I use no 2D sprites nor any form of trickery, just texture sprite mapping in 3D.

To my knowledge, the Box2D wrapper doesn't have collision listeners implemented, so in GLB I'm unable to detect Box2D collisions. Normally the workaround is to have a sprite bigger than the physics body and detect the sprite collision before the physics collision and act accordingly.

If you don't use this trick, how do you know that a collision in Box2D has occurred to play the sound?

António
Title: Re: Coliision Point
Post by: Ian Price on 2011-Oct-06
Matchy gets his balls out, videos them and everyone want to have a play with them! What has this forum come to?

Looks cool =D
Title: Re: Coliision Point
Post by: matchy on 2011-Oct-06
Just dusting off that one year old video. :P

Quote from: AMateus on 2011-Oct-06
If you don't use this trick, how do you know that a collision in Box2D has occurred to play the sound?

Although I do agree that internal Box2D collisions are needed (and I have attempted to understand it), there are ways around it for now.

I think I'm mentioned twice that I use distance collision (from the center point of the white ball to nearby balls' center point). Obviously if an object is equal or less than the radius, then reverse the vectors and play a sound. Note that a simple calculation/bit shift can cater for this saving on calc/call cycles.

The other method is to check the vector, x and y velocity. Check for a reserve change, which could mean a rebound.

For a better commercial demo of Box2D with sound, check out djtoon's technique!
http://www.glbasic.com/forum/index.php?topic=7037.0
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-06
Quote from: matchy on 2011-Oct-06Again, please don't refer to it a trickery as the proper and respectable term is technique, especially if you have no code to show for.

English is not my main language and it appears I have mistaken the meaning of the word "trick" (probably used in the wrong context or something). I didn't meant to sound disrespectful. But point taken. My apologies.

Thank you for your help. I will give it a try

Regards,
António
Title: Re: Coliision Point
Post by: Kitty Hello on 2011-Oct-06
I updated the Box2D example here in the forums to get collision feedbacks.

I forgot the point of collision. Is that of any value?
Title: Re: Coliision Point
Post by: AMateus on 2011-Oct-06
Thank you so much =)

It was exactly this I was looking for. I think the point of collision could be of some value yes. If there is a intention of for example, deforming the sprite based on the impact point ;)

But at least for me, now, I'm pretty happy.

Thank you again =)
António