Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / 3D Arkanoid clone: is this the most accurate way to detect a collision between the ball and a brick?

Author
Message
Video Boy
21
Years of Service
User Offline
Joined: 21st Mar 2004
Location:
Posted: 22nd Aug 2008 16:55 Edited at: 22nd Aug 2008 17:00
In this "3D Arkanoid clone" I'm making, the ball moves along a 2D plane like in the original Arkanoid, the default velocity for the ball is 0.02 units per cycle on the X axis and 0.04 units on the Y axis, and the bricks are boxes 0.6 units wide, 0.4 units tall and 0.4 units deep.
Right now, to detect collisions between the ball and a brick, I proceed as follows:

1) for every iteration of the main program loop, I check the distance from the ball and every brick in the level by repeatedly calling this function:

where BALLPOSX#(0) and BALLPOSY#(0) are global variables storing the current X and Y position of the ball (the Z position is fixed).
If the function returns 1, it means the ball is actually colliding with a brick. To decide what kind of bounce the ball must make, I need to know what side of the brick it has touched, because if it touched the higher or lower side of the brick, the Y component of the ball's velocity must be inverted, while if it touched the left or right side of the brick, the X component of the ball's velocity must be inverted. Currently, I use this function to decide what side of the brick the ball touched:

After calling this function in the main program loop, I use this code to decide which component of the ball velocity to invert:

The problem with this approach is that as the ball velocity increases, the function becomes less precise and the ball may unpredictably bounce horizontally when it should bounce vertically, or viceversa. This is why I ask: is there a more accurate way to know which side of a brick the ball touched?
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 24th Aug 2008 06:08
Hello,

Is this "fake" 3d (2d in perspective) or is it real 3D, meaning using 3d objects? Actually if it is 2d, you can use the images and texture 3d plains with them and position them on top of hidden boxes to use this proposed solution:

There is a collision DLL that would come in real handy for this. It is referred to as Sparky's collision DLL. It's somewhere on the forums I can't find the link at present - you'll want the DBC version. With it, you cast a ray from a start point to an end point (the ball to a brick). It also calculates a bounce vector so you can ricochet the ball in the correct direction.

Enjoy your day.
Video Boy
21
Years of Service
User Offline
Joined: 21st Mar 2004
Location:
Posted: 28th Aug 2008 16:32 Edited at: 28th Aug 2008 16:35
Quote: "Is this "fake" 3d (2d in perspective) or is it real 3D, meaning using 3d objects?"

Real 3D. I use 3D objects for everything because that allows me to change the viewpoint at will.
Quote: "There is a collision DLL that would come in real handy for this. It is referred to as Sparky's collision DLL."

Is it freeware?
Van B
Moderator
22
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 28th Aug 2008 17:38
I think I just used a collision function then passed the previous and current ball locations to it. I used array collision but the idea should carry over to any collision system.

Something like this... Assuming colcheck(x,y) is a function that returns a 1 if there's a collision.

OldBallX#=BallX#
OldBallY#=BallY#
Inc BallX#,BallXS#
Inc BallX#,BallYS#

Ok so store that ball location then move it depending on the speeds. Then if there is a collision:

If colcheck(BallX#,BallY#)=1
If colcheck(OldBallX#,BallY#)=1 then BallY#=OldBallY# : BallYS#=0.0-BallYS#
If colcheck(BallX#,OldBallY#)=1 then BallX#=OldBallX# : BallXS#=0.0-BallXS#
Endif

So if there is a collision, it checks each axis in turn along with the previous axis, so if the new Y and old X return a collision, then there's a collision on Y, so invert the Y speed.

I used an array in my Arkanoid clone for the ball location, I would do that while working on your collision code, makes multi-balling so much easier.


Health, Ammo, and bacon and eggs!
Video Boy
21
Years of Service
User Offline
Joined: 21st Mar 2004
Location:
Posted: 29th Aug 2008 11:50 Edited at: 29th Aug 2008 11:51
Just one thing:
Quote: "If colcheck(BallX#,BallY#)=1
If colcheck(OldBallX#,BallY#)=1 then BallY#=OldBallY# : BallYS#=0.0-BallYS#
If colcheck(BallX#,OldBallY#)=1 then BallX#=OldBallX# : BallXS#=0.0-BallXS#
Endif"


Are the instructions I rewrote in bold always executed, as long as colcheck(BallX#,BallY#) returned 1?
Freddix
AGK Developer
22
Years of Service
User Offline
Joined: 19th Sep 2002
Location: France
Posted: 29th Aug 2008 12:12 Edited at: 29th Aug 2008 12:12
In my DarkANOID game I developed a system based on the direction the ball has.
That result in 4 ways :
x+/z+ ... x-/z+ ... x+/z- and x-/z-
for each direction I check 2 collisions
x+/z+ Top and Right
x-/z+ Top and left
x+/z- bottom and right
x-/z- bottom and left

Instead of detecting collision with object, I defined bricks in an array and detect collision between ball border and brick tile.

Regards,
Fred
Odyssey-Creators

Gandalf said: "All we have to decide is what to do with the time that is given to us"
Odyssey-Creators - X-Quad Editor - 3DMapEditor
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 29th Aug 2008 12:13
@Video Boy

Quote: "Quote: "There is a collision DLL that would come in real handy for this. It is referred to as Sparky's collision DLL."
Is it freeware? "


Yes. Here is a link:
http://forum.thegamecreators.com/?m=forum_view&t=31051&b=5

Since you are using 3d objects, that'll make things nice and neat with the collision DLL. Go through the instructions and the examples to get an idea of the setup. Basically, an imaginary ray is cast from a start point (most likely where ever the ball is) to an end point (somewhere in front of the ball in the direction it is traveling). If the ray intersects an object, the DLL will return the appropriate indicator. If your ray is too far in front of the ball, the ball may not be anywhere near where the collision is taking place. A decent length for the ray starting from the ball's position might be the ball's radius plus it's speed.

If you use ball speed on both axes, Van B's suggestion should flow quite nicely and it's very clean and easy to manage. I think, though, for Sparky's DLL, you'd have to cast rays in 4 directions around the ball: 0,90,180,270 so you'd be able to test the collision against each axis.

Enjoy your day.
Video Boy
21
Years of Service
User Offline
Joined: 21st Mar 2004
Location:
Posted: 29th Aug 2008 22:26
Van B: thanks for the suggestion. Your modification seems to work, even though it becomes imprecise (but less than my previous method) if the speed of the ball per cycle is too high.

Latch: do I need the "enhancements" for DBC to use that DLL?
Van B
Moderator
22
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 30th Aug 2008 01:22 Edited at: 30th Aug 2008 01:29
Yeah, I know what you mean. To get around that I just repeated the ball movements in smaller increments. Like if your maximum safe ball speed is 2.0, then something like this might get around it...



So you could take a copy of the ball speeds, then repeatedly cut them in half until they're both <2.0, and then count how many times they were cut in half. Then you know how many times to repeat the movement and collision check. After the ball has been moved the required number of times, you would reset the speed to the new temporary speed times the number of checks.

Untested code but I think that's a good way to start.

As for collision itself, I think you'd be better off looking into a ranged array collision, very fast...



Using an array with a type and mode being >0 if there's a block, it checks a 2D location and radius against the array. In my game I would destroy the block when finding a collision, not sure how your handling that.


Health, Ammo, and bacon and eggs!
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 30th Aug 2008 01:41
Quote: "Latch: do I need the "enhancements" for DBC to use that DLL?"


Yes. If you are using a non-trial version of DBC, you can get a free upgrade to 1.20 (which has enhancements) . If you purchased it through the TGC website, you should be able to get it through your order history. If you bought it in a store, contact TGC support. This seems to be what they would request you to do:

Quote: "I have the same problem, I contacted support and this was the reply:

If you did not purchase the software directly from us, please submit the following to (email address removed)

1) Create a profile on the TGC website
2) A photograph of yourself holding the DarkBASIC CD-ROM and packaging.
3) Your full name
4) Your full postal details
5) Your zip/ postcode
6) Include your profile's e-mail address."


Enjoy your day.

Login to post a reply

Server time is: 2025-06-07 07:05:52
Your offset time is: 2025-06-07 07:05:52