Help mark/correct/optimize/simplify my code

Blitz3D Forums/Blitz3D Beginners Area/Help mark/correct/optimize/simplify my code

RXArt(Posted 2004) [#1]
hi again everyone. I hope I've not become too annoying. Thanks to some of your help, I've completed my first game in Blitz :: Pong!! I've tried to code in the most straight forward and simple structure (KISS). But I believe my code can be further optimized and simplify. I hope that you can please help "mark" my code, and perhaps give me some tips on improving it.

I know I should have used more functions, but it was pretty impossible to do so, because somehow, I can't get my type variables to work in a function. Anyway, here's the code:

AppTitle "-= My Pong =-"
Global screenx	= 640
Global screeny	= 480
Global upkey 	= 200
Global leftkey 	= 203
Global rightkey   = 205
Global downkey 	= 208
Global batspd	= 6

Global MyScore	= 0
Global OpScore    = 0

SeedRnd MilliSecs()

Graphics screenx,screeny,16,2

;Entity type
Type entityinfo
	Field x
	Field y
	Field width
	Field height
	Field speedx#
	Field speedy#
	Field directionx
	Field directiony
End Type

;Create Mybat instance
Mybat.entityinfo 	= New entityinfo
Mybat\x 			= 320
Mybat\y 			= screeny - 30
Mybat\width			= 80
Mybat\height		= 15

;Create Opbat instance
Opbat.entityinfo 	      = New entityinfo
Opbat\x 			= 320
Opbat\y 			= 30
Opbat\width			= 80
Opbat\height		= 15

;Create Ball instance
Ball.entityinfo 	            = New entityinfo
Ball\x				= 320
Ball\y				= 240
Ball\width			      = 15
Ball\height		      	= 15
Ball\speedx#	      	= Rnd(10)
Ball\speedy#		      = 6 ;Rnd(10)
Ball\directionx		      = 1
Ball\directiony		      = 1

;Create bat and ball image
gfxBat 	= CreateImage(Mybat\width,Mybat\height)
gfxBall	= CreateImage(ball\width,ball\height)

;Draw bat and ball image
SetBuffer ImageBuffer(gfxBat)
	Rect 0,0,mybat\width,mybat\height,1

SetBuffer ImageBuffer(gfxBall)
	Oval 0,0,ball\width,ball\height,1

gfxOpBat = CopyImage(gfxBat)

;Center the images
MidHandle gfxBat
MidHandle gfxOpBat
MidHandle gfxBall

;Switch back to back buffer
SetBuffer BackBuffer()

;Game loops starts here
;================================
While Not KeyHit(1)
;================================

	;Clear screen
	Cls

	;Show the score
	Text 2,screeny-15, "Your Score       : " + MyScore
	Text 2,0,          "Computer's Score : " + OpScore
	AppTitle "-= My Pong =-     You : " + MyScore + "         Comp : " + OpScore

	;Draw my bat onto screen
	DrawImage gfxbat,mybat\x,mybat\y
	DrawImage gfxOpBat,Opbat\x,Opbat\y	

	;Calculate ball location.
	;Keep ball in screen
	If ball\x <(ball\width)/2+5 Or ball\x > screenx-(ball\width)/2-5 Then 
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf
	If ball\y <(ball\height)/2 Then
		MyScore = MyScore + 1		;I Scored!!
		ball\y = 240				;Reset ball to center-y
		ball\speedx# = Rnd(2)		;ball move straighter
		Delay 500
	ElseIf ball\y > screeny-(ball\height)/2 Then 
		OpScore = OpScore + 1		;Opponent Scored!!
		ball\y = 240				;Reset ball to center-y
		ball\speedx# = Rnd(2)		;ball move straighter
		Delay 500	
	EndIf
	
	ball\x = (ball\x + ball\speedx#)
	ball\y = (ball\y + ball\speedy#)
	
	;Draw Ball to screen
	DrawImage gfxball,ball\x,ball\y 

	;Collision with my or opponent's bat
	If ImagesCollide (gfxBat,Mybat\x,Mybat\y,0,gfxBall,Ball\x,Ball\y,0) Then
		ball\speedx# = Rnd(10)
		ball\speedy# = ball\speedy# * - ball\directiony
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf
	
	If ImagesCollide (gfxOpBat,Opbat\x,Opbat\y,0,gfxBall,Ball\x,Ball\y,0) Then
		ball\speedx# = Rnd(10)
		ball\speedy# = ball\speedy# * - ball\directiony
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf

	
	;Simple Opponent AI Movement
	If ball\x < OpBat\x Then 
		OpBat\x = MoveBatLeft(OpBat\x, OpBat\width)
	EndIf
	If ball\x > OpBat\x Then 
		OpBat\x = MoveBatRight(OpBat\x, OpBat\width)
	EndIf
	
	;My Bat Movement
	If leftkey()=1 Then 
		Mybat\x = movebatleft(Mybat\x, Mybat\width)
	EndIf
	
	If rightkey()=1 Then 
		Mybat\x = movebatright(Mybat\x, Mybat\width)
	EndIf
	Flip	
Wend

;Free images
FreeImage gfxBat
FreeImage gfxOpBat
FreeImage gfxBall
Cls
WaitKey()
End

;Function to move the bat left
Function MoveBatLeft(batx, batwidth)
	Local old_x = batx
	If batx > (batwidth/2) Then	
		batx = batx - batspd
		Return batx
	Else
		Return old_x
	EndIf
End Function

;Function to move the bat right
Function MoveBatRight(batx, batwidth)
	Local old_x = batx
	If batx < screenx-(batwidth/2) Then
		batx = batx + batspd
		Return batx
	Else
		Return old_x
	EndIf
End Function

;Key functions
;Leftkey
Function LeftKey()
	If KeyDown(leftkey) = 1 Then 
		Return 1
	Else
		Return 0
	EndIf
End Function

;rightkey
Function RightKey()
	If KeyDown(rightkey) = 1 Then 
		Return 1
	Else
		Return 0
	EndIf
End Function

;Upkey
Function UpKey()
	If KeyDown(upkey) = 1 Then 
		Return 1
	Else
		Return 0
	EndIf
End Function

;Downkey
Function DownKey()
	If KeyDown(Downkey) = 1 Then 
		Return 1
	Else
		Return 0
	EndIf
End Function


Cheers, and thanks again!


Curtastic(Posted 2004) [#2]
take apptitle out of the loop


Ross C(Posted 2004) [#3]
Hey man. The reason you types aren't working in function ( it got me too ;) ) is because they aren't declared as global. The actual pointer needs to be declared global. So:

Mybat.entityinfo 	= New entityinfo


Turns into:

Global Mybat.entityinfo 	= New entityinfo


Try that :)


RXArt(Posted 2004) [#4]
Geez, thanks Ross! I've actually resorted to using gosub and labels inorder to make my codes simpler to read. But I'll definitely give your suggestion a go. :)

And Coorae, I guess I'll leave the apptitle in for a while longer (It kinda reminds me of Game Maker), but will definitely take it out if there are enough ppl to whack me straight in the head for leaving it in. :)

cheers!! I'm currently trying to work on a snake game. Man, there's so much for me to catch up!!


WolRon(Posted 2004) [#5]
Remove these lines:
Cls
WaitKey()
They are pointless.

Remove your leftkey(), rightkey(), etc. functions. They serve no real purpose. Just change:
	If leftkey()=1 Then 
to
	If KeyDown(leftkey) Then 



RXArt(Posted 2004) [#6]
Thanks for the info Wolron. Here's what I came up with:

AppTitle "-= My Pong =-"

Const Lft = 1
Const Rgt = 2

Global screenx	= 640
Global screeny	= 480
Global upkey 	= 200
Global leftkey 	= 203
Global rightkey = 205
Global downkey 	= 208
Global batspd	= 6

Global MyScore	= 0
Global OpScore  = 0

SeedRnd MilliSecs()

Graphics screenx,screeny,16,2

;Entity type
Type entityinfo
	Field x
	Field y
	Field width
	Field height
	Field speedx#
	Field speedy#
	Field directionx
	Field directiony
End Type

;Create Mybat instance
Mybat.entityinfo 	= New entityinfo
Mybat\x 			= 320
Mybat\y 			= screeny - 30
Mybat\width			= 80
Mybat\height		= 15

;Create Opbat instance
Opbat.entityinfo 	= New entityinfo
Opbat\x 			= 320
Opbat\y 			= 30
Opbat\width			= 80
Opbat\height		= 15

;Create Ball instance
Ball.entityinfo 	= New entityinfo
Ball\x				= 320
Ball\y				= 240
Ball\width			= 15
Ball\height			= 15
Ball\speedx#		= Rnd(3)
Ball\speedy#		= 6 ;Rnd(10)
Ball\directionx		= 1
Ball\directiony		= 1

;Create bat and ball image
gfxBat 	= CreateImage(Mybat\width,Mybat\height)
gfxBall	= CreateImage(ball\width,ball\height)

;Draw bat and ball image
SetBuffer ImageBuffer(gfxBat)
	Rect 0,0,mybat\width,mybat\height,1

SetBuffer ImageBuffer(gfxBall)
	Oval 0,0,ball\width,ball\height,1

gfxOpBat = CopyImage(gfxBat)

;Center the images
MidHandle gfxBat
MidHandle gfxOpBat
MidHandle gfxBall

;Switch back to back buffer
SetBuffer BackBuffer()

;Game loops starts here
;================================
While Not KeyHit(1)
;================================

	;Clear screen
	Cls
	Gosub ShowScore
	Gosub UpdateSprite
	Gosub Ball
	Gosub BallCollision
	Gosub MoveBat
	Gosub AIBat
	Flip	
Wend

;Free images
FreeImage gfxBat
FreeImage gfxOpBat
FreeImage gfxBall
End

;Ball Collision and reflection
.BallCollision
If ImagesCollide (gfxBat,Mybat\x,Mybat\y,0,gfxBall,Ball\x,Ball\y,0) Then
		ball\speedx# = Rnd(10)
		ball\speedy# = ball\speedy# * - ball\directiony
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf
	
	If ImagesCollide (gfxOpBat,Opbat\x,Opbat\y,0,gfxBall,Ball\x,Ball\y,0) Then
		ball\speedx# = Rnd(10)
		ball\speedy# = ball\speedy# * - ball\directiony
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf
Return

;Ball Movement and Scoring
.Ball
If ball\x <(ball\width)/2+5 Or ball\x > screenx-(ball\width)/2-5 Then 
		ball\speedx# = ball\speedx# * - ball\directionx
	EndIf
	If ball\y <(ball\height)/2 Then
		MyScore = MyScore + 1		;I Scored!!
		ball\y = 240				;Reset ball to center-y
		ball\speedx# = Rnd(2)		;ball move straighter
		Delay 500
	ElseIf ball\y > screeny-(ball\height)/2 Then 
		OpScore = OpScore + 1		;Opponent Scored!!
		ball\y = 240				;Reset ball to center-y
		ball\speedx# = Rnd(2)		;ball move straighter
		Delay 500	
	EndIf
	
	ball\x = (ball\x + ball\speedx#)
	ball\y = (ball\y + ball\speedy#)
Return

;Draw images to screen
.UpdateSprite
	DrawImage gfxbat,mybat\x,mybat\y
	DrawImage gfxOpBat,Opbat\x,Opbat\y	
	DrawImage gfxball,ball\x,ball\y 
Return

;Simple Opponent AI Movement
.AIBat
	If ball\x < OpBat\x Then 
		OpBat\x = MoveBat(lft,OpBat\x, OpBat\width)
	EndIf
	If ball\x > OpBat\x Then 
		OpBat\x = MoveBat(rgt,OpBat\x, OpBat\width)
	EndIf

Return

;My Bat Movement
.MoveBat
	If KeyDown(leftkey) Then 
		Mybat\x = movebat(lft,Mybat\x, Mybat\width)
	EndIf
	
	If KeyDown(rightkey) Then 
		Mybat\x = movebat(rgt,Mybat\x, Mybat\width)
	EndIf
Return

;Show the score
.ShowScore
	Text 2,screeny-15, "Your Score       : " + MyScore
	Text 2,0,          "Computer's Score : " + OpScore
	AppTitle "-= My Pong =-     You  :  " + MyScore + "         Comp  :  " + OpScore
Return

;Function to move the bat left
Function MoveBat(direction, batx, batwidth)
	Local old_x = batx
	If direction = Lft
		If batx > (batwidth/2) Then	
			batx = batx - batspd
			Return batx
		Else
			Return old_x
		EndIf
	ElseIf direction = Rgt
		If batx < screenx-(batwidth/2) Then
			batx = batx + batspd
			Return batx
		Else
			Return old_x
		EndIf
	Else
		Return old_x
	EndIf
End Function



I've combined the movebatleft and movebatright functions into one, and took away those leftkey and rightkey thingy.

;)


darklordz(Posted 2004) [#7]
There is also a bug that gets the ball stuck on the right side of teh screengoing up an ddown.. I guess it's the math. Very good pong AI tough :P

*BrAG* >



download

My first 2D Project (Skinnable/Multiplayer > Pong) It turned out ehrmm not to well but some seem to like it. I totaly think since ur a beginner u did GREAT!!


RXArt(Posted 2004) [#8]
darklordz: thanks for the comments!! Pong seems like an easy one, since it involves inverting the x and y speed of the ball. I'd have love to make the ai guess the location where the ball will hit, and I'm working on that right now. But my next big thingy is the snake clone, that I'm having some trouble with. I'm not using fancy 2d art at the moment, because I'm still trying to get familiar with the blitz language. cheers


Bot Builder(Posted 2004) [#9]
the globals at the top(well, down to batspd) should be constants. So it would be:
[code]
Const screenx = 640
Const screeny = 480
Const upkey = 200
Const leftkey = 203
Const rightkey = 205
Const downkey = 208
Const batspd = 6
[/code