Coliision Point

Previous topic - Next topic

AMateus

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

backslider

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

Slydog

#2
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.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Crivens

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
Current fave quote: Cause you like musicians and I like people with boobs.

AMateus

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

Crivens

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
Current fave quote: Cause you like musicians and I like people with boobs.

AMateus

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

Dabz

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

Slydog

BTW, GLBasic has bit shifting:
Code (glbasic) Select
ASL()
ASR()
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Dabz

Know what it is.... I looked and ruddy looked for bit shifting commands in the docs... Bugger! :D

Dabz

matchy

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.

AMateus

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

ampos

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...
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

matchy

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.


AMateus

@matchy do you use the "sprite bigger than physics body" trick?