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
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
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:
' 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.
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
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
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
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
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
BTW, GLBasic has bit shifting:
ASL()
ASR()
Know what it is.... I looked and ruddy looked for bit shifting commands in the docs... Bugger! :D
Dabz
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.
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
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:
' 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...
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.
@matchy do you use the "sprite bigger than physics body" trick?
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.
great prototype you have there!
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
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
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
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
I updated the Box2D example here in the forums to get collision feedbacks.
I forgot the point of collision. Is that of any value?
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