What's the simplest - yet best- way to create a bouncing ball in the Breakout mould?
I have made a ball graphic and want to ensure that I can bounce it all around an arena (basically a rectangle shape) before I add other stuff.
Printable View
What's the simplest - yet best- way to create a bouncing ball in the Breakout mould?
I have made a ball graphic and want to ensure that I can bounce it all around an arena (basically a rectangle shape) before I add other stuff.
Basically, there are 2 widely used methods. Giving the ball an angle, and a speed, or using a left/right (x-axis) vector, and an up/down vector.
I have used both, and prefer the second method (just my preference, as i find it easier to work with, and manipulate).
Making a ball bounce off the form using the vector method of ball movement.
I suggest setting up a ball type, so you can easily manipulate it's various properties. Here is a basic one for you.
VB Code:
Private Type typBall X as Double Y as Double a as Double b as Double Radius as Integer 'Does not need to be too precise (nor do the others really...) End Type
Of course you could have many others such as....
VB Code:
Private Type typBall Mass As Double 'How Heavy is 1 unit (120 by 120) of this object? Height As Double 'The height of the object Width As Double 'The width of the object X As Double 'X coordinate of the ball Y As Double 'Y coordinate of the ball Speed(1 To 2) As Double 'Speed of the ball as a vector in X and Y (1=x, 2=y) Accel(1 To 2) As Double 'Accelleration of the ball as a vector in X and Y (1=x, 2=y) CoeffRestitution As Double 'General coefficient of restitution (different for each surface - based on contact with the form edges) (0-1) CoeffFriction As Double 'General coefficient of friction (different for each surface - based on contact with the form edges) (0-1) AirResistance As Double 'How much wind effects this object 0=none, 1 = fully State As String 'Used in code, do decide what physics to apply End Type
We'll stick to the simple ones :)
Ok, the x value is the position of the ball relative to the left side of the form, and the y value is relative to the top (0 being at the very top).
A is the veolcity vector for the x axis. So if a = 100 then the ball would move left...
B is the velocity vector for the y axis. So if b = 100 then the ball would move DOWN (as measurements are made from the top of the form).
Enough of the lecture, to get the ball rolling (hehe) put a timer on a form, with a shape (easy to change to a picturebox).
Call the shape shpBall, and put in a timer called Timer1
VB Code:
Option Explicit Private Type typBall x As Double y As Double a As Double b As Double radius As Integer End Type Dim Ball As typBall Private Sub Form_Activate() Ball.x = shpBall.Left Ball.y = shpBall.Top Ball.a = 60 Ball.b = 30 Ball.radius = (shpBall.Height / 2) End Sub Private Sub Timer1_Timer() shpBall.Left = Ball.x + (Ball.radius) shpBall.Top = Ball.y + (Ball.radius) Ball.x = Ball.x + Ball.a Ball.y = Ball.y + Ball.b End Sub
OOOO, the ball moves, but it goes off the edge of the screen. Lets deal with that now.
In the timer1_timer before ball.x = ball.x + ball.a Put
VB Code:
Call FormCollisionDetection
Now, we'll make the collision detection routine.
It basiclly works like this. If the ball was going right (i.e. ball.a was +ve) then when it hits the form's edge we want it to go left (i.e. ball.a is -ve). It is similar for ball.y
If this was collision detection for an object, instead of the edge of the form, we would have to check that the balls path didn't pass over that object, otherwise if the ball was going fast enough it could 'jump' the object. I won't deal with that now though, as we are just dealing with the form's edges (and it doesn't have to be very realistic).
VB Code:
Private Sub FormCollisionDetection() If Ball.x + Ball.radius > Form1.Width Then 'The ball hit the right edge Ball.a = -Abs(Ball.a) End If If Ball.x - Ball.radius < 0 Then 'The ball hit the left edge Ball.a = Abs(Ball.a) End If If Ball.y + Ball.radius > Form1.Height Then 'The ball hit the bottom edge Ball.b = -Abs(Ball.b) End If If Ball.y - Ball.radius < 0 Then 'The ball hit the top edge Ball.b = Abs(Ball.b) End If End Sub
Now run the program and see what happens.
Success, the ball bounces (you can see that i've only checked the location of the ball, not it's path, as the ball goes off the screen sometimes).
Go ahead and have a play with that code. Try this for example, all i did was add 1 line.
VB Code:
Option Explicit Private Type typBall x As Double y As Double a As Double b As Double radius As Integer End Type Dim Ball As typBall Private Sub Form_Activate() Ball.x = shpBall.Left Ball.y = shpBall.Top Ball.a = 60 Ball.b = 30 Ball.radius = (shpBall.Height / 2) End Sub Private Sub Timer1_Timer() shpBall.Left = Ball.x + (Ball.radius) shpBall.Top = Ball.y + (Ball.radius) Call FormCollisionDetection If Ball.b < 120 Then Ball.b = Ball.b + 1 'A crude simulation of gravity Ball.x = Ball.x + Ball.a Ball.y = Ball.y + Ball.b End Sub Private Sub FormCollisionDetection() If Ball.x + Ball.radius > Form1.Width Then 'The ball hit the right edge Ball.a = -Abs(Ball.a) End If If Ball.x - Ball.radius < 0 Then 'The ball hit the left edge Ball.a = Abs(Ball.a) End If If Ball.y + Ball.radius > Form1.Height Then 'The ball hit the bottom edge Ball.b = -Abs(Ball.b) End If If Ball.y - Ball.radius < 0 Then 'The ball hit the top edge Ball.b = Abs(Ball.b) End If End Sub
Next you could try changing this...
...so that the player had to be under the ball for it to bounce up.VB Code:
If Ball.y + Ball.radius > Form1.Height Then 'The ball hit the bottom edge Ball.b = -Abs(Ball.b) End If
Have fun :)
I have seen some games SLH has made with this method and it works very well.
Thanks Ambivalentiowa, i'll pay you later ;)Quote:
Originally posted by Ambivalentiowa
I have seen some games SLH has made with this method and it works very well.
LMAO
use what ppl above me posted, but to check if it is at edge, make it
if ballpositionx + speedx > form1.width then ballpositionx = form1.width: speedx = 0 - speedx
change according to spot... basicly the ball can be going 9999999 and it will never go outside of form.
Alkatran, that method of collision detection is a better way, but i don't know about how you moved the ball...
Look at the attached pic.
With your method, alkatran, the ball would be moved to the red position. While at low speeds this would be un-noticable, but if it was going 9999999 (in your example :) ), then it would be very noticable.
What you should do, is test various percentages of the velocity of the ball, then when you detect a collision, move the ball to ball.x + (ball.a * Percent/100) and ball.y = ball.y + (ball.b * Percent/100).
This, if done correctly, would place the ball in the exact position that it would collide with the form.
NB: This method would have to be used for detection of small objects, such as a line, as otherwise the ball would go straight over it (at a relativly low speed).
http://www.vbforums.com/attachment.php?s=&postid=945698
Also, if you want to be really clever, you could add the remainder of the ball's velocity on to the new ball position (in the correct direction of course). If you did use this method, you would have to check for collision on the new velocity as well and if that collided, then you could have to check again.....
http://www.vbforums.com/attachment.php?s=&postid=945728
again, i've seen this, and it works well.
:)