2d ball bouncing

Blitz3D Forums/Blitz3D Beginners Area/2d ball bouncing

How can i bounce balls in 2d, if someone could put this inside a function or something, and give me an explanation for how this works, I'd appreciate it. (been searching the forums, can't find anything that quite cuts it)

Have you tried looking throught the sample games?
I'd try the code from "Kong" in Game Programming for teens.
I think this is a collision thing.
I'd be more detailed but I don't have time, sorry.

err...what???

 
BallX=BallX+BallMoveX
If BallX > 100 Then BallMoveX=BallMoveX*-1



Off the top of my head, BallMoveX is how much the ball moves. Just opposite it when it hits a boundary.
Do the same thing for the Y vaules and you have a bounce effect.

I've already done something like that, except that only works for 4-directional bouncing, it won't bounce of diagnal surfaces.

Graphics 640,480,0,2
SetBuffer BackBuffer()

; set up a type to hold xy coordinates
Type vector2
	Field x#
	Field y#
End Type

; set up a Type For Each ball
Type Ball
	Field pos.vector2
	Field vel.vector2
	Field size
End Type

gravity# = .75

; create 20 balls 
For loop = 1 To 20
	b.ball = New ball
	b\pos = New vector2
	b\vel = New vector2

	;assign random position and velocity
	b\pos\x = Rnd (640)
	b\pos\y = Rnd (480)
	b\vel\x = Rnd (-5.0,5.0)
	b\vel\y = Rnd (-5.0,5.0)
Next


While Not KeyHit(1) ; start main loop

	Line 0,460,640,460 ; draw floor

	For b.ball = Each ball
		Oval b\pos\x, b\pos\y,10,10
		b\pos\x = b\pos\x + b\vel\x ; add velocity to Ball X position
		b\vel\y = b\vel\y + gravity	; Add gravity to ball Y velocity
		b\pos\y = b\pos\y + b\vel\y	; Add velocity to ball Y position

		; check for screen bounds and reverse direction if outside
		If b\pos\x > 640
			b\pos\x = 640
			b\vel\x = -b\vel\x
		EndIf 
		If b\pos\x < 0
			b\pos\x = 0
			b\vel\x = -b\vel\x
		EndIf 
		If b\pos\y > 450
			b\pos\y = 450
			b\vel\y = -b\vel\y
		EndIf 
		If b\pos\y < 0
			b\pos\y = 0
			b\vel\y = -b\vel\y
		EndIf 
	Next

	Flip
	Cls
Wend ; end main loop

End ; end program



Oops,... just saw your last post,... didn't know you were looking for angles. I don't have time to make that work tonight. Edit,... did a bit more on it anyways

How are you drawing your angles? You will need to find the angle of the line, and how it intersects the velocity line of the ball. Then you change the velocity to the new value. Same concept as above, but instead of detecting the screen edge you are detecting the angled lines.

Edit: ok, I grabbed some code from the archives for the line collision. It is missing some of the collisions because the collision response is only changing the Y velocity. You will need to determine the proper angle to give the correct x and y velocities.


Graphics 640,480,0,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global intersectX%, intersectY%

; set up a type to hold xy coordinates
Type vector2
	Field x#
	Field y#
End Type

; set up a Type For Each ball
Type Ball
	Field pos.vector2
	Field vel.vector2
	Field size
End Type

gravity# = .25

; create 20 balls 
For loop = 1 To 20
	b.ball = New ball
	b\pos = New vector2
	b\vel = New vector2

	;assign random position and velocity
	b\pos\x = Rnd (640)
	b\pos\y = Rnd (480)
	b\vel\x = Rnd (-5.0,5.0)
	b\vel\y = Rnd (-5.0,5.0)
Next

Type Line
	Field p1.vector2 	;start point
	Field p2.vector2	;end point
End Type

For loop = 1 To 5
	l.Line = New Line
	l\p1 = New vector2
	l\p2 = New vector2

	l\p1\x = Rnd (640)
	l\p1\y = Rnd (480)
	l\p2\x = l\p1\x + 200
	l\p2\y = l\p1\y + Rnd (-50,50)
Next 


While Not KeyHit(1) ; start main loop

	Line 0,460,640,460 ; draw floor

	For l.Line = Each Line ; draw the lines
		Line l\p1\x,l\p1\y, l\p2\x,l\p2\y
	Next
	
	For b.ball = Each ball
		Oval b\pos\x, b\pos\y,10,10
		b\pos\x = b\pos\x + b\vel\x ; add velocity to Ball X position
		b\vel\y = b\vel\y + gravity	; Add gravity to ball Y velocity
		b\pos\y = b\pos\y + b\vel\y	; Add velocity to ball Y position

		; check for screen bounds and reverse direction if outside
		If b\pos\x > 640
			b\pos\x = 640
			b\vel\x = -b\vel\x
		EndIf 
		If b\pos\x < 0
			b\pos\x = 0
			b\vel\x = -b\vel\x
		EndIf 
		If b\pos\y > 450
			b\pos\y = 450
			b\vel\y = -b\vel\y
		EndIf 
		If b\pos\y < 0
			b\pos\y = 0
			b\vel\y = -b\vel\y
		EndIf 

		For l.Line = Each Line
			If linesintersect ( b\pos\x, b\pos\y, b\pos\x + b\vel\x ,  b\pos\y + b\vel\y , l\p1\x,l\p1\y ,l\p2\x,l\p2\y  )
				b\pos\x = intersectX
				b\pos\y = intersectY - 10
				b\vel\y = -b\vel\y
			EndIf
		Next

	Next

	Flip
	Cls
Wend ; end main loop

End ; end program




;Source: <a href="http://Local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/" target="_blank">http://Local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/</a>
;Intersection point of two lines (from code archives Andy_A)
;(2 dimensions)
Function linesIntersect(x1%,y1%, x2%,y2%, x3%,y3%, x4%,y4%)

	numeratorA#  = (x4-x3)*(y1-y3)-(y4-y3)*(x1-x3)
	numeratorB#  = (x2-x1)*(y1-y3)-(y2-y1)*(x1-x3)
	denominator# = (y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)

	If denominator = 0.0 Then
;		Text(10,20,"No intersection")
;		If numeratorA = 0.0 And numeratorB = 0.0 And denominator = 0.0 Then
;			Text(10,40,"Lines are coincident")
;		Else
;			Text(10,40,"Lines are parallel")
;		End If
		Return False
	Else
		Ua# = numeratorA/denominator
		Ub# = numeratorB/denominator
		range1% = Ua >= 0.0 And Ua <= 1.0
		range2% = Ub >= 0.0 And Ub <= 1.0
		If range1 And range2 Then
			intersectX% = Floor(x1 + Ua*(x2-x1)+.5)
			intersectY% = Floor(y1 + Ua*(y2-y1)+.5)
			Return True
		Else
;			Text(10,20,"No intersection")
			Return False
		End If
    End If
End Function



See my revised code near the bottom. This does correct reflection in 2d. You could adapt it to work with Pongo's code above.

http://www.blitzbasic.com/Community/posts.php?topic=65410#730520