Breakout physics

Blitz3D Forums/Blitz3D Beginners Area/Breakout physics

Figment(Posted 2003) [#1]
I'm working on a breakout style game in blitz but I have one major problem. I have no clue as to how I should go about coding the ball physics, or more accurately how to even make the ball bounce around the screen >.<. I'm not really worried about the colisions code or anything like that just the ball physics code. I've looked it up on google and wasn't able to find very much in the way of what I am looking for, which is really an explanation of how it works rather then just code although example code would be great. Thanks in advance for any help.

Figment


Ross C(Posted 2003) [#2]
well, basically if you want a bouce, just invert the driection. say if the ball was travelling up and left and hit a block above the ball, then invert the y speed. i think the most difficult thing would be to determine which side of the block it hit, but you could simply compare the x and y co-ords of both.


Ross C(Posted 2003) [#3]
in fact, just trying to put together code for it. it don't seem so easy now. you'll probably have to check collisions with the top bottom left and right of the ball


Shambler(Posted 2003) [#4]
I remember doing this years ago in AMOS! =)

Say for example the ball is moving up and right, it could hit in 2 different ways..

1) Hit the left hand side of a block in which case you need to invert the X direction to make it go left

2) Hit the bottom of a block in which case you need to invert the Y direction to make it go down

Instead of moving the ball to the next position then checking for collisions I did this, this was for a 2D game..

Move the ball X coord only
check for collisions and invert X direction if hit
Move the ball Y coord only
check for collisions and invert Y direction if hit

this way I was able to tell if the ball had hit the side or top/bottom of a block.

Of course, if you are making this game in 3D you could just check the collision normal to work out which face of the block the ball hits.


Ross C(Posted 2003) [#5]
yeah, finally cracked it. i wish i had read shambler's post tho, but here it is. oh it's for 2d btw!

Graphics 800,600
SetBuffer BackBuffer()


blockimg=CreateImage(32,32)
SetBuffer ImageBuffer(blockimg)
Rect 0,0,32,32
MidHandle blockimg


ball=CreateImage(20,20)
SetBuffer ImageBuffer(ball)
Oval 0,0,20,20
MidHandle ball


bx=300
by=360
bxdir=-4
bydir=-4

Type block
	Field image
	Field x,y
	Field life
End Type

For loop=1 To 10
	b.block=New block
	b\image=blockimg
	b\x=Rnd(40,600)
	b\y=Rnd(50,500)
	b\life=2
	MidHandle b\image
Next


SetBuffer BackBuffer()

While Not KeyHit(1)
	Cls






	Gosub update_ball

	DrawImage ball,bx,by

	Flip
Wend
End

.update_ball
	bx=bx+bxdir
	by=by+bydir
	If bx<10 Or bx>700 Then
		bx=bx-bxdir
		bxdir=bxdir*-1
	End If
	If by<20 Or by>590 Then
		by=by-bydir
		bydir=bydir*-1
	End If
	
	For b.block=Each block
		DrawImage b\image,b\x,b\y
		If ImagesCollide(ball,bx,by,0,b\image,b\x,b\y,0) Then
					
					If b\y=>by And b\x=>bx Then
	
						If b\y-by>b\x-bx And bydir>0 Then
							bydir=bydir*-1
						Else
							bxdir=bxdir*-1
						End If
					ElseIf b\y=>by And b\x<=bx Then
						If b\y-by>bx-b\x And bydir>0 Then
							bydir=bydir*-1
						Else
							bxdir=bxdir*-1
						End If
					ElseIf b\y<=by And b\x>=bx
						If by-b\y>b\x-bx And bydir<0 Then
							bydir=bydir*-1
						Else
							bxdir=bxdir*-1
						End If
					ElseIf b\y<=by And b\x<=bx
						If by-b\y>bx-b\x And bydir<0 Then
							bydir=bydir*-1
						Else
							bxdir=bxdir*-1
						End If
					Else
						bxdir=bxdir*-1
						bydir=bydir*-1
					End If
		b\life=b\life-1
		If b\life=0 Then Delete b.block
		End If

	Next
Return



Ross C(Posted 2003) [#6]
ok, here's an updated version. you can specify in the loop at the beginning how many block you want and how many times you want it to get hit before it disappears. sorry for not commented it. i'm in a wee bit of a rush :D


Figment(Posted 2003) [#7]
Thank alot, all of this really helps. Time to get my code on.


WolRon(Posted 2003) [#8]
I tried your (joker) code, but unfortunately, it doesn't change the velocity or angle of the ball depending on where it hit the square (like if the square was the paddle). Games like BreakOut do that. Of course, that's a whole other hurdle...


Shambler(Posted 2003) [#9]
Changing ball direction based on where it hits the paddle is simply a matter of comparing the difference in X coordinates between the ball and paddle positions.

Pseudo code:


If Ball hits Paddle
;Reverse ball Y direction
BallYDirection=-BallYDirection
;Work out where it hit /2 copes with changing paddle/ball sizes
Diff=(Paddle.x+Paddlewidth/2)-(Ball.x+Ballwidth/2)
;Change ball direction
BallXSpeed=Diff/10 ( sensitivity value )




Ross C(Posted 2003) [#10]
oh rite, i didn't put that in because i don't remember it being like that. i thought that only happenned to the paddle. mind you, long time since i've played it


Figment(Posted 2003) [#11]
Okay I tried this in 3d...I get a memory access violation...
Graphics3D 640,480,16,1
font=LoadFont("Arial",32,True)
SetFont font
SetBuffer BackBuffer()
blurtex=CreateTexture(0,0,0)
camera=CreateCamera()
CameraClsMode camera,0,1
sprite=CreateSprite(camera)
MoveEntity sprite,0,0,640
ScaleSprite sprite,640,640
EntityOrder sprite,-1
;EntityTexture sprite,blurtex
EntityAlpha sprite,0.75
EntityBlend sprite,3

Const CUBE_COL=1
Const SPHERE_COL=2


;create ball
Global ball=CreateSphere(12)
ScaleEntity ball,3,3,3
EntityColor ball,100,100,255
EntityShininess ball,.2
Global balldirection = 0

;create paddle
Global p1=CreateCube()
ScaleEntity p1,8,2,2
EntityColor p1,50,60,20

;setup Collisions table
EntityType ball,SPHERE_COL
EntityType p1, CUBE_COL
Collisions ball,p1,2,2

ground=CreateSphere(32)
EntityColor ground,0,0,0

EntityType p1,2

While Not KeyHit(1)

If count=3
		CameraViewport camera,0,0,50,50
		RenderWorld
		CopyRect 0,0,256,256,0,0,BackBuffer(),TextureBuffer(blurtex)	
		CameraViewport camera,0,0,GraphicsWidth(),GraphicsHeight()
		count=0
	EndIf
count=count+1
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	PositionEntity camera,0,100,1
	RotateEntity camera,80,0,0
	If x1#<-180 Then x1#=-180
	If x1#>180 Then x1#=180
	PositionEntity camera,0,0,200
	RotateEntity camera,178,0,0
	PositionEntity p1,x1#,122,0
	

MoveEntity  ball,.5,.5,0

If EntityCollided(ball,p1) Then
AlignToVector ball, CollisionNX (p1, 1), CollisionNY (p1, 1),CollisionNZ(p1,1), 3
EndIf
	


	

	UpdateWorld
	RenderWorld
	Color 0,0,0

Flip
	x1#=x1#-MouseXSpeed()
Wend
End

aghhhhhh....


Ross C(Posted 2003) [#12]
it's the collisions command which is giving the error

when you use the collisions commands the first two parameters are the entitytype numbers not the entity names.

so it should be
collisions SPHERE_COL,CUBE_COL,2,2



Gnasher(Posted 2003) [#13]
hi , did it work with Jokers, small fix .. im curious how it looks when it works , i just started to code in bliz again :D

cheers!

/gnasher