'Gimme Friction Baby' for the small screen

Miscellaneous Forums/Blitz Showcase/'Gimme Friction Baby' for the small screen

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Today I was just thinking about trying to write a game for my phone.. in Java probably.

Anyway.. I was trying to think what to write and I remembered a browser game called 'Gimme Friction Baby' where the controls where just 1 button.
So.. tonight I thought I'd try to write a prototype in blitzMax.. and here is my results.

The code isnt pretty.. it was after all written in about 5 hours and written on the fly.

its runs in a 240x320 window.. to match my phone.

Just thought I'd share.



and here is a windows exe GimmeFrictionBabyMobile.zip

Added : Spent another hour or so adding improvements. Spheres now contain a number indicating how many hits remaining before it disapears.
firing sphere size increased ( maily so the numbers would fit inside it ).
SuperStrict
' Program     : Gimme Friction Baby Mobile ( prototype )
' Author      : QuietBloke
' Date        : 21st March 2008
' Description : This is a clone of the winner of a "Casual Gampley Design Competition"
' Please visit www.jayisgames.com and check out the competitions to see the original games.
' "Gimme Friction Baby" was written by Wouter Visser of The Netherlands
' The idea for this prototype is to see if I could recreate the game for the small screen
' so it can fit onto a mobile phone.

Type TGameTemplate
	Field quit:Int
	
	Method Start() Abstract
	Method Update() Abstract
	Method Draw() Abstract
	Method Pause() Abstract
	Method Finish() Abstract

	Method DoQuit()
		quit = True
	End Method
End Type

Type TVector
	Field x:Float
	Field y:Float
	
	Method Rotate(angle:Float)
		Local tempX:Int
		Local tempY:Int
		tempX = x
		tempY = y
		x = Cos(angle) * tempX - Sin(angle) * tempY
		y = Sin(angle) * tempX + Cos(angle) * tempY
	End Method
	
	Method GetMagnitude:Float()
		Return Sqr(x*x + y*y )
	End Method
	
	Method SetMagnitude(newMagnitude:Float)
		Normalise()
		x :* newMagnitude
		y :* newMagnitude
	End Method
	
	Method Normalise()
		Local magnitude:Float
		magnitude = GetMagnitude()
		x :/ magnitude
		y :/ magnitude
	End Method
	
	Method DotProduct:Float(v:TVector)
		Return x*v.x + y*v.y
	End Method
	
	Method ScalarMultiply(scalar:Float)
		x :* scalar
		y :* scalar
	End Method
End Type

Type TPolyRects
	Field rects:TList
	Field pos:TVector
	Field angle:Float
	Field scale:Float
		
	Method New()
		rects = CreateList()
		pos = New TVector
		scale = 1
	End Method
	
	Method AddRect(pointArray:Float[])
		Local rect:TPolyRect = New TPolyRect
		
		rect.pos = pos
		rect.pointArray = pointArray
		rect.scale = scale
		rect.angle = angle
		
		ListAddLast(rects,rect)
	End Method
	
	Method Update()
		Local rect:TPolyRect
		
		For rect = EachIn rects
			rect.angle = angle
			rect.scale = scale
			rect.pos = pos
		Next
	End Method
	
	Method Draw()
		Local rect:TPolyRect
		
		For rect = EachIn rects
			rect.Draw()
		Next
	End Method
End Type

Type TPolyRect
	Field pos:TVector
	Field angle:Float
	Field pointArray:Float[8]
	Field scale:Float
	
	Method New()
		pos = New TVector
		scale = 1
	End Method
	
	Method Update()
	End Method
	
	Method Draw()
		SetOrigin pos.x,pos.y
		SetRotation angle
		SetScale scale,scale
		DrawPoly(pointArray)
		SetOrigin 0,0
		SetRotation 0
		SetScale 1,1
	End Method
End Type

Type TPoly3 Extends TPolyRects
	Method New()
		Local pointArray:Float[8]
		
		pointArray[0] = -5
		pointArray[1] = -5

		pointArray[2] = 5
		pointArray[3] = -5

		pointArray[4] = 5
		pointArray[5] = -3

		pointArray[6] = -5
		pointArray[7] = -3
		
		Addrect(pointArray)

		pointArray = New Float[8]
		
		pointArray[0] = 3
		pointArray[1] = -5

		pointArray[2] = 5
		pointArray[3] = -5

		pointArray[4] = 5
		pointArray[5] = 5

		pointArray[6] = 3
		pointArray[7] = 5

		Addrect(pointArray)

		pointArray = New Float[8]

		pointArray[0] = -3
		pointArray[1] = -1

		pointArray[2] = 5
		pointArray[3] = -1

		pointArray[4] = 5
		pointArray[5] = 1

		pointArray[6] = -3
		pointArray[7] = 1
		
		Addrect(pointArray)

		pointArray = New Float[8]
		pointArray[0] = -5
		pointArray[1] = 3

		pointArray[2] = 5
		pointArray[3] = 3

		pointArray[4] = 5
		pointArray[5] = 5

		pointArray[6] = -5
		pointArray[7] = 5
		
		Addrect(pointArray)

	End Method
End Type

Type TPoly2 Extends TPolyRects
	Method New()
		Local pointArray:Float[8]
		
		pointArray[0] = -5
		pointArray[1] = -5

		pointArray[2] = 5
		pointArray[3] = -5

		pointArray[4] = 5
		pointArray[5] = -3

		pointArray[6] = -5
		pointArray[7] = -3
		
		Addrect(pointArray)

		pointArray = New Float[8]
		
		pointArray[0] = 3
		pointArray[1] = -5

		pointArray[2] = 5
		pointArray[3] = -5

		pointArray[4] = 5
		pointArray[5] = 1

		pointArray[6] = 3
		pointArray[7] = 1

		Addrect(pointArray)

		pointArray = New Float[8]
		
		pointArray[0] = -5
		pointArray[1] = -1

		pointArray[2] = 5
		pointArray[3] = -1

		pointArray[4] = 5
		pointArray[5] = 1

		pointArray[6] = -5
		pointArray[7] = 1

		Addrect(pointArray)
		
		pointArray = New Float[8]
		
		pointArray[0] = -5
		pointArray[1] = -1

		pointArray[2] = -3
		pointArray[3] = -1

		pointArray[4] = -3
		pointArray[5] = 5

		pointArray[6] = -5
		pointArray[7] = 5

		Addrect(pointArray)

		pointArray = New Float[8]

		pointArray[0] = -5
		pointArray[1] = 3

		pointArray[2] = 5
		pointArray[3] = 3

		pointArray[4] = 5
		pointArray[5] = 5

		pointArray[6] = -5
		pointArray[7] = 5
		
		Addrect(pointArray)


	End Method
End Type

Type TPoly1 Extends TPolyRects
	Method New()
		Local pointArray:Float[8]
		
		pointArray[0] = -1
		pointArray[1] = -5

		pointArray[2] = 1
		pointArray[3] = -5

		pointArray[4] = 1
		pointArray[5] = 5

		pointArray[6] = -1
		pointArray[7] = 5
		
		Addrect(pointArray)
	End Method
End Type

Type TTurret Extends TPolyRects
	Field direction:Float

	Method New()
		Local pointArray:Float[8]
		pos.x = 120
		pos.y = 320-40

		pointarray[0] = 0
		pointarray[1] = -8

		pointarray[2] = 35
		pointarray[3] = -8

		pointarray[4] = 35
		pointarray[5] = 8

		pointarray[6] = 0
		pointarray[7] = 8
		
		AddRect(pointArray)

		pos.x = 120
		pos.y = 320-40		
		
		angle = 340
		
		direction = -1
		Super.Update()
	End Method

	Method Update()
		angle :+ direction
		If angle >= 340 Then
			angle = 340
			direction :* -1
		End If
		If angle < 200 Then
			angle = 200
			direction :* -1
		End If
		
		Super.Update()
	End Method
End Type

Type TSphere
	Global spheres:TList = CreateList()
	Global outOfBounds:Int
	Global score:Int

	Field lifePoly:TPolyRects
		
	Field pos:TVector
	Field velocity:TVector
	Field radius:Int
	Field expanding:Int
	Field life:Int
	Field colour:Int
	
	Method New()
		pos = New TVector
		velocity = New TVector
		ListAddLast(spheres,Self)
		radius = 8
		life = 3
		colour = 255
	End Method
	
	Method SetVelocity(magnitude:Float,angle:Float)
		velocity.x = magnitude
		velocity.y = 0
		velocity.Rotate(angle)
	End Method

	Method Hit()
		life :- 1
		If life > 0 Then
			Local angle:Float = lifePoly.angle
			Select life
				Case 1
					lifePoly = New TPoly1
				Case 2
					lifePoly = New TPoly2
			End Select
			lifePoly.pos = pos		
			lifePoly.scale = radius/8.0
			lifePoly.angle = angle
			lifePoly.Update()
		Else
			score :+ 1
		End If
		
	End Method
	
	Function Reset()
		score = 0
		spheres = CreateList()
		outOfBounds = False
	End Function
	
	Method IsStopped:Int()
		If velocity.GetMagnitude() = 0 And expanding = False
			Return True
		Else
			Return False
		End If
	End Method
	
	Method Draw()
		SetColor colour,colour,colour
		DrawOval pos.x-radius, pos.y-radius, radius*2, radius*2
		
		If lifePoly <> Null Then
			SetColor 0,0,0
			lifePoly.Draw()
			SetColor 255,255,255
		End If
	End Method
	
	Method Update()
		' if we are expanding then increase the size if we can
		If expanding Then
			Local hit:Int = False
			'will expansion collide with a wall
			If pos.x -radius -1 < 0 Then
				hit = True
			End If
			If pos.x + radius + 1 > 239 Then
				hit = True
			End If
			If pos.y - radius - 1 < 0 Then
				hit = True
			End If
			If pos.y + radius > 239 Then
				hit = True
			End If
			' see if expanding will collide with another sphere
			Local sphere:TSphere
			
			For sphere = EachIn spheres
				If sphere <> Self And sphere.life > 0 Then
					' find distance from centers of spheres
					Local distance:Float = Sqr((pos.x-sphere.pos.x)*(pos.x-sphere.pos.x) + (pos.y-sphere.pos.y)*(pos.y-sphere.pos.y))
					Local mindistance:Float = radius + sphere.radius
					If distance <= minDistance Then
						hit = True
					End If
				End If
			Next			
			If hit Then
				expanding = False
			Else
				radius :+ 1
				lifePoly.scale = radius/8.0
				lifePoly.Update()
			End If
		Else
			' if we are moving then we must do collision detection
			If velocity.GetMagnitude() <> 0 Then
				' see if we stop the ball
				If velocity.GetMagnitude() <= .04 Then
					SetVelocity(0,0)
					pos.x = Int(pos.x)
					pos.y = Int(pos.y)
					' Expand the ball until it cannot expand anymore
					expanding = True
					lifePoly = New TPoly3
					lifePoly.pos = pos	
					lifepoly.angle = Rand(-35,35)
				Else
					' see if we need to bounce off a wall
					If pos.x - radius  < 0 Then
						velocity.x :* -1
						pos.x = radius 
					End If
					If pos.x + radius > 239 Then
						velocity.x :* -1
						pos.x = 239 - radius
					End If
					If pos.y - radius < 0 Then
						velocity.y :* -1
						pos.y = radius
					End If
					' see if we need to bounce off another sphere
					Local sphere:TSphere
					For sphere = EachIn spheres
						If sphere <> Self And sphere.life > 0 Then
							' find distance from centers of spheres
							Local distance:Float = Sqr((pos.x+-sphere.pos.x)*(pos.x-sphere.pos.x) + (pos.y-sphere.pos.y)*(pos.y-sphere.pos.y))
							Local mindistance:Float = radius + sphere.radius
							If distance <= minDistance Then
								' first shift our sphere back until we are not overlapping the other sphere
								Local m:TVector = New TVector
								m.x = sphere.pos.x - pos.x
								m.y = sphere.pos.y - pos.y
								m.Normalise()
								m.ScalarMultiply(minDistance-distance)
								pos.x :- m.x
								pos.y :- m.y
								
								' find the collision normal 
								Local collisionNormal:TVector = New TVector
								collisionNormal.x = pos.x - sphere.pos.x
								collisionNormal.y = pos.y - sphere.pos.y
								collisionNormal.Normalise()
								
								Local j:Float
								j = (-2 * (velocity.DotProduct(collisionNormal)) / collisionNormal.DotProduct(collisionNormal))
								
								collisionNormal.x :* j
								collisionNormal.y :* j
								velocity.x :+ collisionNormal.x
								velocity.y :+ collisionNormal.y 
								
								sphere.Hit()
							End If 
						End If
					Next

					pos.x :+ velocity.x
					pos.y :+ velocity.y
			
					If velocity.y >= 0 And pos.y + radius > 239 Then
						outOfBounds = True
					End If
					velocity.SetMagnitude(velocity.GetMagnitude()-.04)
				End If
			End If
		End If
	End Method
	
	Function CreateSphere:TSphere(posX:Float, posY:Float, speed:Float, angle:Float)
		Local sphere:TSphere
		
		sphere = New TSphere
		sphere.pos.x = posX
		sphere.pos.y = posY
		sphere.SetVelocity(speed,angle)
		
		Return sphere
	End Function
	
	Function UpdateAll()
		Local sphere:TSphere
		
		For sphere = EachIn spheres
			If sphere.life < 1 And sphere.colour <= 0 Then
				ListRemove(spheres,sphere)
			Else
				If sphere.life < 1 Then
					sphere.colour :- 16
				Else
					sphere.Update()
				End If
			End If
		Next
	End Function
	
	Function DrawAll()
		Local sphere:TSphere
		
		For sphere = EachIn spheres
			sphere.Draw()
		Next
	End Function
End Type

Type TGame Extends TGameTemplate
	Field turret:TTurret
	Field movingSphere:TSphere
	Field gameStage:Int
	Field colour:Int
	Field colourShift:Int
	
	Method New()
		colourShift = -5
		colour = 255
		
	End Method
	
	Method Start()
		Graphics 240,320,0,30
		
		'create the turret
		turret = New TTurret		
	End Method
	
	Method Update()
		If KeyHit(KEY_Escape) Then
			DoQuit()
		End If
		
		If gameStage = 1 Then
			If KeyHit(KEY_Space) Then
				If movingSphere = Null Then
					FireSphere()
				Else
					If movingSphere.IsStopped() Then
						FireSphere()
					End If
				End If
			End If
			
			turret.Update()
			TSphere.UpdateAll()
			
			If TSphere.outOfBounds Then
				gameStage = 0
				colour = 255
				colourShift = -5
			End If
		Else
			If gameStage = 0 Then
				colour :+ colourShift
				If colour <= 5 Or colour >= 255 Then
					colourShift :* -1
				End If
				If KeyHit(Key_SPACE) Then
					TSphere.Reset()
					movingSphere = Null
					turret = New TTurret
					gameStage = 1
				End If
			End If
		End If
	End Method

	Method FireSphere()
		Local startOffset:TVector
		startOffset = New TVector
		startOffset.x = 30
		startOffset.y = 0
		startOffset.Rotate(turret.angle)

		movingSphere = TSphere.CreateSphere(120+startOffset.x,320-40+startOffset.y,5,turret.angle)
	End Method
	
	Method Draw()
		' draw a dotted line marking the bottom of the play area
		Local x:Int
		
		SetColor 255,255,255
		For x = 0 To 240 Step 10
			DrawLine x,240,x+5,240
		Next
		
		'draw the ground
		DrawRect 0,320-20,240,320
		
		' draw the turret base
		DrawRect 120-20,320-40,40,40
		DrawOval 120-20,320-60,40,40

		' draw the turret
		turret.Draw()

		TSphere.DrawAll()
		
		SetColor 0,0,0
		DrawText "Score : " + TSphere.score,80,320-18
		
		SetColor colour,colour,colour
		If gameStage = 0 Then
			DrawText "Press 'SPACE'",70,100
			DrawText "to begin",80,120
		End If
	End Method
	
	Method Pause()
	End Method
	
	Method Finish()
	End Method
End Type

Global game:TGame = New TGame

Global finished:Int

game.Start()
While Not game.quit
	game.Update()
	Cls
	game.Draw()
	Flip
Wend

game.Finish()

End


Forgot to mention : the only key you need to play is the space key. Press Escape to quit the game.

The aim of the game is a little hard to explain.
You fire a ball. When it stops moving it will expand until it reaches a wall or another ball.
When you hit a stationary ball 3 times it will be removed from the play area and you will score 1 point.
The game ends when a ball falls down below the dotted line.