Posted: 11th Aug 2011 19:33
@Nomad Soul,
This is not that hard, and certainly nothing close to C++. Granted I have nearly 30 years of programming experience, but the AppGameKit script is really not hard at all. Worlds Apart Online with it's 27,000 lines of DBPro code, now that's hard.

If you've already been programming with DBPro and made some good progress, then this will be just as easy. It's actually easier because there are fewer commands, and you're dealing with nothing but sprites. If your ultimate goal is to publish an iPhone game, this is the best route for a novice programmer.

Overall the program is 1,604 lines, but the real meat of the game loop is only about 500 lines. The rest is all setup, an option screen, a high score screen, an instructions screen, and some networking. This is truly a very small program.

@All,
For those interested, here is the latest version that's been updated to be more cross-platform compatible for input, and updated for changes in syntax during the beta. I dropped the second virtual joystick, and replaced it with 2 virtual buttons. I also changed all of the mouse click functions because there was a better, more cross-platform way to detect a mouse click or a touch event with the same command.

Then I added code to detect the platform it was running on. If you're running it on Windows, Mac, or MeeGo it wont display the virtual controls and you can use the keyboard controls.

It makes a big difference when you can test on something with a touch screen. The game takes on an entirely different feel, even though the gameplay is exactly the same. It could just be the difference in screen size, but it's wild either way.

I've tested this on Windows, Mac, and an iPod Touch (4th gen).

+ Code Snippet
rem
rem Asteroid Blast
rem Written by : Kevin Summers
rem Copyright 2011 KISTech Studios
rem

SetPrintSize(18)
SetOrientationAllowed(1, 0, 0, 0)

rem Set Globals
global sw as integer
global sh as integer
global Stick1 as integer
global Button1 as integer
global Button2 as integer
global KeyPress as integer
global dim t[20] as integer
global optSound as integer
global optSoundVol as integer
global optMusic as integer
global optMusicVol as integer
global optInitials$ as string

rem Set the working resolution
sw = 320 : sh = 480
SetVirtualResolution(sw, sh)

rem Variables for the virtual input
Stick1 = 1
Button1 = 1
Button2 = 2
d$ = GetDeviceName()
if d$ = "windows" or d$ = "mac" or d$ = "meego"
	KeyBoard = 1
else
	KeyBoard = 0
endif

rem Player Options
optSound = 1
optSoundVol = 70
optMusic = 1
optMusicVol = 70
optInitials$ = "AAA"

if GetFileExists("Options.txt") = 1
	f = OpenToRead("Options.txt")
	if FileEOF(f) = 0
		optSound = ReadInteger(f)
		optSoundVol = ReadInteger(f)
		optMusic = ReadInteger(f)
		optMusicVol = ReadInteger(f)
	endif
	CloseFile(f)
else
	f = OpenToWrite("Options.txt", 0)
	WriteInteger(f, optSound)
	WriteInteger(f, optSoundVol)
	WriteInteger(f, optMusic)
	WriteInteger(f, optMusicVol)
	CloseFile(f)
endif

rem Load our generic all purpose image
LoadImage(1, "White.jpg", 0)
CreateSprite(1, 1)
SetSpriteSize(1, sw, sh)
SetSpriteColor(1, 0, 0, 0, 255)
SetSpritePosition(1, 0, 0)
SetSpriteDepth(1, 9)

rem Logo Splash Screen
LoadImage(2, "Logo.png", 0)
CreateSprite(2, 2)
SetSpriteSize(2, sw, sw)
SetSpritePosition(2, 0, 80)
t# = timer()
a = 255
do
	a = a - 2
	if a < 0 then a = 0
	SetSpriteColor(1, 0, 0, 0, a)
	if timer() - t# > 2.0 then t# = 0.0
	sync()
	if t# = 0.0 then exit
loop
t# = timer()
do
	if timer() - t# > 2.0 then t# = 0.0
	sync()
	if t# = 0.0 then exit
loop
t# = timer()
do
	a = a + 4
	if a > 255 then a = 255
	SetSpriteColor(1, 0, 0, 0, a)
	if timer() - t# > 1.5 then t# = 0.0
	sync()
	if t# = 0.0 then exit
loop
DeleteSprite(2)
DeleteImage(2)

rem Let them know we're loading assets
tLoading = CreateText("Loading..")
SetTextSize(tLoading, 18)
SetTextPosition(tLoading, sw/2-(GetTextTotalWidth(tLoading)/2), sh/2-10)
sync()
SetSpritePosition(1, -320, 0)

rem Main menu logo and buttons
ABLogo = LoadImage("ABLogo.png", 0)
ABSpr = CreateSprite(ABLogo)
SetSpritePosition(ABSpr, -300, -300)
PlayImg = LoadImage("Btn_Play.png", 0)
PlaySpr = CreateSprite(PlayImg)
SetSpriteShape(PlaySpr, 3)
SetSpritePosition(PlaySpr, -300, -300)
HiScoreImg = LoadImage("Btn_HighScore.png", 0)
HiScoreSpr = CreateSprite(HiScoreImg)
SetSpriteShape(HiScoreSpr, 3)
SetSpritePosition(HiScoreSpr, -300, -300)
HiScoreImg2 = LoadImage("HighScores.png", 0)
HiScoreSpr2 = CreateSprite(HiScoreImg2)
SetSpritePosition(HiScoreSpr2, -300, -300)
ExitImg = LoadImage("Btn_Exit.png", 0)
ExitSpr = CreateSprite(ExitImg)
SetSpriteShape(ExitSpr, 3)
SetSpritePosition(ExitSpr, -300, -300)
OptionsImg = LoadImage("Btn_Options.png", 0)
OptionsSpr = CreateSprite(OptionsImg)
SetSpriteShape(OptionsSpr, 3)
SetSpritePosition(OptionsSpr, -300, -300)
InstructImg = LoadImage("Btn_Instruct.png", 0)
InstructSpr = CreateSprite(InstructImg)
SetSpriteShape(InstructSpr, 3)
SetSpritePosition(InstructSpr, -300, -300)
BackImg = LoadImage("Btn_Back.png", 0)
BackSpr = CreateSprite(BackImg)
SetSpriteShape(BackSpr, 3)
SetSpritePosition(BackSpr, -300, -300)

rem Set the physics boundaries (0 = off 1 = on)
SetPhysicsWallTop(0)
SetPhysicsWallBottom(0)
SetPhysicsWallLeft(0)
SetPhysicsWallRight(0)

rem Load Music
BGMusic = LoadMusic("Mus_BGMusic.mp3")

rem Load Sound Effects
SndExplode = LoadSound("Snd_Explode.wav")
SndLaser = LoadSound("Snd_Laser.wav")
SndBomb = LoadSound("Snd_Bleep.wav")
SndShield = LoadSound("Snd_ShieldPhase.wav")
SndBombLaunch = LoadSound("Snd_Warning.wav")
SndTriShot = LoadSound("Snd_Hydrolic.wav")

rem Load Background
type nebula_data
	img as integer
	spr as integer
endtype
dim Nebulas[5] as nebula_data
for x = 1 to 4
	Nebulas[x].img = LoadImage("Nebula"+str(x)+".png", 0)
	Nebulas[x].spr = CreateSprite(Nebulas[x].img)
	SetSpritePosition(Nebulas[x].spr, -800, -600)
	SetSpriteDepth(Nebulas[x].spr, 5000)
next x
Nebula = Random(1, 4)

rem Load Ship
global Ship as integer
global ShipF as integer
global ShipL as integer
global ShipR as integer
ShipImg = LoadImage("Ship.png", 0)
ShipF = CreateSprite(ShipImg)
SetSpriteScale(ShipF, 0.5, 0.5)
SetSpriteOffset(ShipF, 32, 32)
SetSpritePositionByOffset(ShipF, -100, -100)
SetSpriteShape(ShipF, 3)
ShipLImg = LoadImage("ShipL.png", 0)
ShipL = CreateSprite(ShipLImg)
SetSpriteScale(ShipL, 0.5, 0.5)
SetSpriteOffset(ShipL, 32, 32)
SetSpritePositionByOffset(ShipL, -100, -100)
SetSpriteShape(ShipL, 3)
ShipRImg = LoadImage("ShipR.png", 0)
ShipR = CreateSprite(ShipRImg)
SetSpriteScale(ShipR, 0.5, 0.5)
SetSpriteOffset(ShipR, 32, 32)
SetSpritePositionByOffset(ShipR, -100, -100)
SetSpriteShape(ShipR, 3)

rem Setup Particles for Explosions
Shrapnel = LoadImage("shrapnel3.png", 0)
Explode = CreateParticles(-500, -500)
ExplodeX = -500
ExplodeY = -500
ExpFreq = 100
ExpLife = 1.0
ExpMax = 20
fire = 0

rem Load Powerups
PUShieldImg = LoadImage("PU_Shield.png", 0)
PUShield = CreateSprite(PUShieldImg)
SetSpriteScale(PUShield, 0.25, 0.25)
SetSpriteOffset(PUShield, 16, 16)
SetSpritePositionByOffset(PUShield, -100, -100)
SetSpriteShape(PUShield, 1)
ShieldImg = LoadImage("Shield.png", 0)
Shield = CreateSprite(ShieldImg)
SetSpriteOffset(Shield, 64, 64)
SetSpritePositionByOffset(Shield, -100, -100)
SetSpriteShape(Shield, 1)
PUShieldActive = 0
ShieldActive = 0
ShieldTime = 0
ShieldHits = 0
PUTriShotImg = LoadImage("PU_Trishot.png", 0)
PUTriShot = CreateSprite(PUTriShotImg)
SetSpriteScale(PUTriShot, 0.25, 0.25)
SetSpriteOffset(PUTriShot, 16, 16)
SetSpritePositionByOffset(PUTriShot, -100, -100)
SetSpriteShape(PUTriShot, 1)
PUTriShotActive = 0
TriShotActive = 0
TriShotTime = 0
iTriShot = CreateSprite(Shrapnel)
SetSpriteOffset(iTriShot, 16, 16)
SetSpriteColor(iTriShot, 64, 255, 64, 255)
SetSpritePosition(iTriShot, -100, -100)
PUBombImg = LoadImage("PU_Bomb.png", 0)
PUBomb = CreateSprite(PUBombImg)
SetSpriteScale(PUBomb, 0.25, 0.25)
SetSpriteOffset(PUBomb, 16, 16)
SetSpritePositionByOffset(PUBomb, -100, -100)
SetSpriteShape(PUBomb, 1)
BombImg = LoadImage("Bomb.png", 0)
Bomb = CreateSprite(BombImg)
SetSpriteOffset(Bomb, 32, 32)
SetSpritePositionByOffset(Bomb, -100, -100)
SetSpriteShape(Bomb, 3)
PUBombActive = 0
BombActive = 0
BombTime = 0
iBomb = CreateSprite(BombImg)
SetSpriteScale(iBomb, 0.5, 0.5)
SetSpriteOffset(iBomb, 16, 16)
SetSpritePositionByOffset(iBomb, -100, -100)

rem Blast radius sprite for the bomb used for collision detection
rem against the asteroids when the bomb goes off.
BlastRadiusImg = LoadImage("BlastRadius.png", 0)
BlastRadius = CreateSprite(BlastRadiusImg)
SetSpriteScale(BlastRadius, 3.0, 3.0)
SetSpriteOffset(BlastRadius, 192, 192)
SetSpriteShape(BlastRadius, 1)
SetSpritePositionByOffset(BlastRadius, -300, -300)
SetSpriteVisible(BlastRadius, 0)

rem Load Asteroids
AsteroidCount = 60
type asteroid_data
	spr as integer
	act as integer
	hits as integer
endtype
dim AsteroidImg[8] as integer
dim Asteroids[AsteroidCount] as asteroid_data
for x = 1 to 8
	AsteroidImg[x] = LoadImage("Rock"+str(x)+".png", 0)
next x

rem Set the size of the asteroids, then place them off the top of
rem the screen to allow gravity to pull them down onto the screen.
i = 0
for x = 1 to AsteroidCount
	i = i + 1
	if i = 9 then i = 1
	Asteroids[x].spr = CreateSprite(AsteroidImg[i])
	a# = Random(2, 5) / 10.0
	SetSpriteScale(Asteroids[x].spr, a#, a#)
	SetSpriteAngle(Asteroids[x].spr, Random(0, 359))
	w = GetImageWidth(AsteroidImg[i]) * a#
	SetSpriteOffset(Asteroids[x].spr, w/2, w/2)
	SetSpritePositionByOffset(Asteroids[x].spr, Random(w/2, sw-(w/2)), -(Random(60, 300)))
	SetSpriteShape(Asteroids[x].spr, 3)
	SetSpritePhysicsOn(Asteroids[x].spr, 2)
next x

rem Laser / Photon setup
type laser_data
	spr as integer
	act as integer
endtype
LaserCount = 50
dim Laser[LaserCount] as laser_data
w = GetImageWidth(Shrapnel) / 2
for x = 1 to LaserCount
	Laser[x].spr = CreateSprite(Shrapnel)
	SetSpriteColor(Laser[x].spr, 64, 64, 255, 255)
	SetSpriteOffSet(Laser[x].spr, w, w)
	SetSpritePositionByOffset(Laser[x].spr, -50, -50)
	SetSpriteShape(Laser[x].spr, 1)
next x

asteroidTime# = timer()

global Lives as integer = 3
global Score as integer = 0
global Level as integer = 1

rem Setup all of the text objects
global tDebug as integer
tDebug = CreateText(" ")
SetTextSize(tDebug, 18)
SetTextPosition(tDebug, 10, 230)
global tScore as integer
tScore = CreateText("Score : "+str(Score))
SetTextSize(tScore, 16)
SetTextPosition(tScore, 0, -30)
global tLives as integer
tLives = CreateText("Lives : "+str(Lives))
SetTextSize(tLives, 16)
SetTextPosition(tLives, 0, -30)
global tLevel as integer
tLevel = CreateText("Level : "+str(Level))
SetTextSize(tLevel, 22)
SetTextPosition(tLevel, 0, -30)
SetTextColor(tLevel, 255, 255, 0, 255)
global tGameOver as integer
tGameOver = CreateText("GAME OVER")
SetTextSize(tGameOver, 28)
SetTextPosition(tGameOver, 0, -50)
SetTextColor(tGameOver, 255, 64, 92, 255)
global tGetHiScore as integer
tGetHiScore = CreateText("Downloading High Scores..")
SetTextSize(tGetHiScore, 18)
SetTextPosition(tGetHiScore, 0, -50)
SetTextColor(tGetHiScore, 200, 200, 200, 255)
global tNetworkError1 as integer
global tNetworkError2 as integer
tNetworkError1 = CreateText("Server unavailable.")
tNetworkError2 = Createtext("Try again later.")
SetTextSize(tNetworkError1, 18)
SetTextSize(tNetworkError2, 18)
SetTextPosition(tNetworkError1, 0, -50)
SetTextPosition(tNetworkError2, 0, -50)
SetTextColor(tNetworkError1, 200, 200, 200, 255)
SetTextColor(tNetworkError2, 200, 200, 200, 255)
global tCountdown as integer
tCountdown = CreateText("3")
SetTextSize(tCountdown, 28)
SetTextPosition(tCountdown, 0, -50)
SetTextColor(tCountdown, 255, 255, 0, 255)
global tRoundTime as integer
tRoundTime = CreateText("60")
SetTextSize(tRoundTime, 16)
SetTextPosition(tRoundTime, 0, -50)
SetTextColor(tRoundTime, 255, 255, 255, 255)

rem Setup High Score text objects
type hiscore_data
	txt as integer
	sc as integer
endtype
dim HiScores[10] as hiscore_data
global HiScoreHeader as integer
HiScoreHeader = CreateText("Name          Score")
SetTextSize(HiScoreHeader, 22)
SetTextPosition(HiScoreHeader, 0, -50)
SetTextColor(HiScoreHeader, 255, 255, 128, 255)
f = 0
if GetFileExists("Scores.txt") = 1
	f = OpenToRead("Scores.txt")
endif
for x = 1 to 10
	if f = 0
		HiScores[x].txt = CreateText("AAA .......... 1000")
		HiScores[x].sc = 1000
	else
		n$ = ReadString(f) + " "
		HiScores[x].sc = ReadInteger(f)
		tTemp = CreateText(str(HiScores[x].sc))
		fx = GetTextLength(tTemp)
		DeleteText(tTemp)
		for y = 1 to 13 - fx
			n$ = n$ + "."
		next y
		n$ = n$ + " " + str(HiScores[x].sc)
		HiScores[x].txt = CreateText(n$)
	endif
	SetTextSize(HiScores[x].txt, 22)
	SetTextPosition(HiScores[x].txt, 0, -50)
	SetTextColor(HiScores[x].txt, 255, 255, 128, 255)
next x
if f > 0 then CloseFile(f)
SetTextPosition(tLoading, 0, -50)
fade = 0

rem Download the current high scores from the server
gosub GetHighScores



rem Main Loop
Main:
	do
		gosub StartScreen
		if Branch = 1
			Branch = 0
			gosub HiScoreScreen
		endif
		if Branch = 2
			Branch = 0
			gosub OptionsScreen
		endif
		if Branch = 3
			Branch = 0
			gosub Instructions
		endif
		if Branch = 4
			Branch = 0
			gosub GamePlay
		endif
		if Branch = 5 then exit
	loop

	end


rem Start Screen (MAIN MENU)
StartScreen:
	if GetMusicPlaying() = 1
		StopMusic()
	endif
	if optMusic = 1
		PlayMusic(BGMusic, optMusicVol, 1, 0)
	endif
	Branch = 0
	SetSpritePosition(Nebulas[Nebula].spr, 0, 0)
	SetSpritePosition(ABSpr, 32, 0)
	SetSpriteDepth(ABSpr, 2)
	SetSpritePosition(HiScoreSpr, 92, 130)
	SetSpriteDepth(HiScoreSpr, 2)
	SetSpritePosition(OptionsSpr, 92, 190)
	SetSpriteDepth(OptionsSpr, 2)
	SetSpritePosition(InstructSpr, 92, 250)
	SetSpriteDepth(InstructSpr, 2)
	SetSpritePosition(PlaySpr, 92, 310)
	SetSpriteDepth(PlaySpr, 2)
	SetSpritePosition(ExitSpr, 92, 370)
	SetSpriteDepth(ExitSpr, 2)
	SetPhysicsGravity(0.0, 0.0)
	SetTextPosition(tScore, 0, -30)
	SetTextPosition(tLives, 0, -30)

	rem Make sure there's no asteroids drifting through the menu
	for x = 1 to AsteroidCount
		Asteroids[x].act = 0
		SetSpritePhysicsAngularVelocity(Asteroids[x].spr, 0.0)
		SetSpritePhysicsVelocity(Asteroids[x].spr, 0.0, 0.0)
		SetSpritePhysicsOff(Asteroids[x].spr)
		SetSpritePositionByOffset(Asteroids[x].spr, Random(64, sw-64), -64)
	next x

	do
		tx = GetPointerX()
		ty = GetPointerY()
		ti = GetPointerState()

		if tx > GetSpriteX(HiScoreSpr) and tx < GetSpriteX(HiScoreSpr)+GetSpriteWidth(HiScoreSpr)
			if ty > GetSpriteY(HiScoreSpr) and ty < GetSpriteY(HiScoreSpr)+GetSpriteHeight(HiScoreSpr)
				if ti > 0
					Branch = 1
					exit
				endif
			endif
		endif

		if tx > GetSpriteX(OptionsSpr) and tx < GetSpriteX(OptionsSpr)+GetSpriteWidth(OptionsSpr)
			if ty > GetSpriteY(OptionsSpr) and ty < GetSpriteY(OptionsSpr)+GetSpriteHeight(OptionsSpr)
				if ti > 0
					Branch = 2
					exit
				endif
			endif
		endif

		if tx > GetSpriteX(InstructSpr) and tx < GetSpriteX(InstructSpr)+GetSpriteWidth(InstructSpr)
			if ty > GetSpriteY(InstructSpr) and ty < GetSpriteY(InstructSpr)+GetSpriteHeight(InstructSpr)
				if ti > 0
					Branch = 3
					exit
				endif
			endif
		endif

		if tx > GetSpriteX(PlaySpr) and tx < GetSpriteX(PlaySpr)+GetSpriteWidth(PlaySpr)
			if ty > GetSpriteY(PlaySpr) and ty < GetSpriteY(PlaySpr)+GetSpriteHeight(PlaySpr)
				if ti > 0
					SetPhysicsGravity(0.0, 10.0)
					Restart = 1
					Branch = 4
					exit
				endif
			endif
		endif

		if tx > GetSpriteX(ExitSpr) and tx < GetSpriteX(ExitSpr)+GetSpriteWidth(ExitSpr)
			if ty > GetSpriteY(ExitSpr) and ty < GetSpriteY(ExitSpr)+GetSpriteHeight(ExitSpr)
				if ti > 0
					Branch = 5
					exit
				endif
			endif
		endif

		sync()
	loop

	while GetPointerState() = 1
		sync()
	endwhile
	rem Move everything off screen
	SetSpritePosition(ABSpr, -300, -300)
	SetSpritePosition(PlaySpr, -300, -300)
	SetSpritePosition(HiScoreSpr, -300, -300)
	SetSpritePosition(OptionsSpr, -300, -300)
	SetSpritePosition(InstructSpr, -300, -300)
	SetSpritePosition(ExitSpr, -300, -300)

return


rem Main Game Loop
GamePlay:

	Level = 1
	Score = 0
	Lives = 3
	Active = 0
	RoundTime = 0
	dead = 1

	do
		
		if KeyBoard = 0
			if GetRawKeyState(37) = 1 or GetRawKeyState(39) = 1
				KeyBoard = 1
				DeleteVirtualJoystick(Stick1)
				DeleteVirtualButton(Button1)
				DeleteVirtualButton(Button2)
			endif
		endif
			
		if dead = 1
			if KeyBoard = 0
				DeleteVirtualJoystick(Stick1)
				DeleteVirtualButton(Button1)
				DeleteVirtualButton(Button2)
			endif
			gosub Intermission
		endif

		t# = timer()

		RT = 60 - (t# - RoundTime)

		if RT =< 0
			SetTextPosition(tRoundTime, 0, -50)
			RT = 0
			Active = 0
			if Score => 0
				Level = Level + 1
			endif
			SetSpritePhysicsOff(Ship)
			SetSpritePosition(Ship, -100, -100)
			if KeyBoard = 0
				DeleteVirtualJoystick(Stick1)
				DeleteVirtualButton(Button1)
				DeleteVirtualButton(Button2)
			endif
			gosub Intermission
		endif

		if RT < 10
			SetTextString(tRoundTime, "0"+str(RT))
		else
			SetTextString(tRoundTime, str(RT))
		endif

		SetTextString(tScore, "Score : "+str(Score))

		rem Move Powerups
		if PUShieldActive = 1
			SetSpritePositionByOffset(PUShield, GetSpriteXByOffset(PUShield), GetSpriteYByOffset(PUShield)+1)
			if GetSpriteCollision(Ship, PUShield) = 1
				SetSpritePositionByOffset(PUShield, -100, -100)
				if optSound = 1
					PlaySound(SndShield, optSoundVol, 0, 0)
				endif
				PUShieldActive = 0
				ShieldActive = 1
				ShieldTime = t#
				ShieldHits = 0
			endif
			if GetSpriteYByOffset(PUShield) > 500
				ShieldDrop = t# + Random(0, 20)
				SetSpritePositionByOffset(PUShield, -100, -100)
				PUShieldActive = 0
			endif
		endif
		if PUTriShotActive = 1
			SetSpritePositionByOffset(PUTriShot, GetSpriteXByOffset(PUTriShot), GetSpriteYByOffset(PUTriShot)+1)
			if GetSpriteCollision(Ship, PUTriShot) = 1
				SetSpritePositionByOffset(PUTriShot, -100, -100)
				if optSound = 1
					PlaySound(SndTriShot, optSoundVol, 0, 0)
				endif
				PUTriShotActive = 0
				SetSpritePosition(iTriShot, sw/2-32, sh-32)
				TriShotActive = 1
				TriShotTime = t#
			endif
			if GetSpriteYByOffset(PUTriShot) > 500
				SetSpritePositionByOffset(PUTriShot, -100, -100)
				PUTriShotActive = 0
			endif
		endif
		if PUBombActive = 1
			SetSpritePositionByOffset(PUBomb, GetSpriteXByOffset(PUBomb), GetSpriteYByOffset(PUBomb)+1)
			if GetSpriteCollision(Ship, PUBomb) = 1
				SetSpritePositionByOffset(PUBomb, -100, -100)
				if optSound = 1
					PlaySound(SndBomb, optSoundVol, 0, 0)
				endif
				PUBombActive = 0
				BombActive = 1
				SetSpritePosition(iBomb, sw/2, sh-32)
				BombTime = 0
			endif
			if GetSpriteYByOffset(PUBomb) > 500
				SetSpritePositionByOffset(PUBomb, -100, -100)
				PUBombActive = 0
			endif
		endif

		rem Shield Active
		if ShieldActive = 1
			SetSpritePositionByOffset(Shield, GetSpriteXByOffset(Ship), GetSpriteYByOffset(Ship))
			if t# - ShieldTime > 20
				ShieldActive = 0
				SetSpritePositionByOffset(Shield, -100, -100)
			endif
		endif

		rem TriShot Active
		if TriShotActive = 1
			if t# - TriShotTime > 10
				TriShotActive = 0
				TRiShotTime = 0
				SetSpritePosition(iTriShot, -100, -100)
			endif
		endif

		rem Fired Bomb is Active
		if BombActive = 1
			if BombTime > 0
				SetSpritePositionByOffset(Bomb, GetSpriteXByOffset(Bomb), GetSpriteYByOffset(Bomb)-1)
				if GetSpriteYByOffset(Bomb) < 200 then SetSpritePositionByOffset(Bomb, GetSpriteXByOffset(Bomb), 200)
				if t# - Bombtime > 5
					SetSpritePositionByOffset(BlastRadius, GetSpriteXByOffset(Bomb), GetSpriteYByOffset(Bomb))
					ExplodeX = GetSpriteXByOffset(Bomb)
					ExplodeY = GetSpriteYByOffset(Bomb)
					ExpFreq = 300
					ExpLife = 2.0
					ExpMax = 300
					if optSound = 1
						PlaySound(SndExplode, optSoundVol, 0, 0)
					endif
					Fire = 1
					gosub Explosions
					for x = 1 to AsteroidCount
						if GetSpriteCollision(Asteroids[x].spr, BlastRadius) = 1
							Score = Score + 10
							Asteroids[x].act = 0
							SetSpritePhysicsOff(Asteroids[x].spr)
							SetSpritePositionByOffset(Asteroids[x].spr, sw/2, -100)
						endif
					next x
					SetSpritePositionByOffset(BlastRadius, -300, -300)
					SetSpritePositionByOffset(Bomb, -100, -100)
					BombTime = 0
					BombActive = 0
					SetSpritePosition(iBomb, -100, -100)
				endif
			endif
		endif

		rem Check if the Photon has gone past the allowed game area
		rem and remove it to make it available for reuse
		for fx = 1 to LaserCount
			if GetSpriteY(Laser[fx].spr) < 16
				SetSpritePhysicsOff(Laser[fx].spr)
				SetSpritePosition(Laser[fx].spr, 0, -100)
				Laser[fx].act = 0
			endif
		next fx

		for fx = 1 to AsteroidCount
			if Asteroids[fx].act = 1
				rem Check if the asteroid made it past the player
				if GetSpriteY(Asteroids[fx].spr) > 500
					if Active = 1 then Score = Score - 50
					Asteroids[fx].act = 0
					SetSpritePhysicsOff(Asteroids[fx].spr)
					SetSpritePositionByOffset(Asteroids[fx].spr, sw/2, -100)
				endif
				rem Check if the asteroid drifted off the left or right edge of the screen
				X = GetSpriteX(Asteroids[fx].spr)
				if X < -30 or X > 340
					Asteroids[fx].act = 0
					SetSpritePhysicsOff(Asteroids[fx].spr)
					SetSpritePositionByOffset(Asteroids[fx].spr, sw/2, -100)
				endif
				rem Check if an asteroid hit the shield
				if GetSpriteCollision(Asteroids[fx].spr, Shield) = 1
					ExplodeX = GetSpriteXByOffset(Asteroids[fx].spr)
					ExplodeY = GetSpriteYByOffset(Asteroids[fx].spr)
					ExpLife = 3.0
					ExpFreq = 100
					ExpMax = 100
					if optSound = 1
						PlaySound(SndExplode, optSoundVol, 0, 0)
					endif
					Score = Score + 10
					ShieldHits = ShieldHits + 1
					SetSpritePhysicsOff(Asteroids[fx].spr)
					SetSpritePositionByOffset(Asteroids[fx].spr, sw/2, -100)
					if ShieldHits => 3
						ShieldTime = 0
						ShieldActive = 0
						SetSpritePositionByOffset(Shield, -100, -100)
					endif
					Fire = 1
					gosub Explosions
				endif
				rem Check if an asteroid hit the ship
				if GetPhysicsCollision(Asteroids[fx].spr, Ship) = 1
					ExplodeX = GetPhysicsCollisionWorldX()
					ExplodeY = GetPhysicsCollisionWorldY()
					ExpFreq = 100
					ExpLife = 1.0
					ExpMax = 30
					if optSound = 1
						PlaySound(SndExplode, optSoundVol, 0, 0)
					endif
					dead = 1
					Active = 0
					Score = Score - 100
					Lives = Lives - 1
					SetTextString(tLives, "Lives : "+str(Lives))
					fire = 1
					gosub Explosions
					SetSpritePhysicsOff(Ship)
					SetSpritePositionByOffset(Ship, -200, -200)
					exit
				endif
			endif
		next fx

		rem Release asteroids at the proper interval
		if t# - asteroidTime# > asteroidFreq# and Active = 1
			for x = 1 to AsteroidCount
				if Asteroids[x].act = 0
					SetSpritePositionByOffset(Asteroids[x].spr, Random(20, sw-20), -50)
					SetSpritePhysicsOn(Asteroids[x].spr, 2)
					SetSpritePhysicsVelocity(Asteroids[x].spr, 0.0, 0.0)
					SetSpritePhysicsAngularVelocity(Asteroids[x].spr, 0.0)
					if GetSpriteWidth(Asteroids[x].spr) < 48
						Asteroids[x].hits = 1
					else
						Asteroids[x].hits = 0
					endif
					Asteroids[x].act = 1
					exit
				endif
			next x
			asteroidTime# = t#
		endif

		rem Check for Photons hitting Asteroids
		for fx = 1 to LaserCount
			if Laser[fx].act = 1
				if GetSpriteY(Laser[fx].spr) > 16
					for ax = 1 to AsteroidCount
						if Asteroids[ax].act = 1
							if GetPhysicsCollision(Laser[fx].spr, Asteroids[ax].spr) = 1
								Asteroids[ax].hits = Asteroids[ax].hits + 1
								if Asteroids[ax].hits < 2
									ExpFreq = 50
									ExpLife = 0.75
									ExpMax = 20
								else
									ExpFreq = 80
									ExpLife = 1.0
									ExpMax = 20
								endif
								ExplodeX = GetPhysicsCollisionWorldX()
								ExplodeY = GetPhysicsCollisionWorldY()
								if optSound = 1
									PlaySound(SndExplode, optSoundVol, 0, 0)
								endif
								fire = 1
								gosub Explosions
								rem Decide if a Powerup will be dropped by a large asteroid being destroyed
								if GetSpriteWidth(Asteroids[ax].spr) => 48 and Asteroids[ax].hits = 2
									a = Random(0, 50)
									if (a = 0 or a = 5 or a = 10 or a = 15 or a = 20 or a = 25 or a = 30 or a = 35 or a = 40 or a = 45 or a = 50) and Level > 1
										if Level = 2 then PU = 1
										if Level = 3 then PU = 2
										if Level > 3 then PU = 3
										PU = Random(1, PU)
										spx = GetSpriteXbyOffset(Asteroids[ax].spr)
										spy = GetSpriteYbyOffset(Asteroids[ax].spr)
										if PU = 1 and PUShieldActive = 0 and PUTriShotActive = 0 and PUBombActive = 0 and ShieldActive = 0
											SetSpritePositionByOffset(PUShield, spx, spy)
											PUShieldActive = 1
										endif
										if PU = 2 and PUTriShotActive = 0 and PUShieldActive = 0 and PUBombActive = 0 and TriShotActive = 0
											SetSpritePositionByOffset(PUTriShot, spx, spy)
											PUTriShotActive = 1
										endif
										if PU = 3 and PUBombActive = 0 and PUTriShotActive = 0 and PUShieldActive = 0 and BombActive = 0
											SetSpritePositionByOffset(PUBomb, spx, spy)
											PUBombActive = 1
										endif
									endif
								endif
								rem Give points for destroying an Asteroid
								if Asteroids[ax].hits = 2
									SetSpritePhysicsOff(Asteroids[ax].spr)
									Asteroids[ax].act = 0
									SetSpritePositionByOffset(Asteroids[ax].spr, Random(20, 300), -(Random(60, 300)))
									Score = Score + 10
								endif
								SetSpritePhysicsOff(Laser[fx].spr)
								Laser[fx].act = 0
								SetSpritePositionByOffset(Laser[fx].spr, -50, -50)
							endif
						endif
					next ax
				else
					rem Reset the Photon for reuse
					SetSpritePhysicsDelete(Laser[fx].spr)
					SetSpritePhysicsOn(Laser[fx].spr, 3)
					SetSpritePhysicsVelocity(Laser[fx].spr, 0.0, -25.0)
				endif
			endif
		next fx

		rem Ship Movement
		sx = GetSpriteXByOffset(Ship)
		sy = sh-100
		SetSpriteAngle(Ship, 0.0)
		SetSpritePhysicsAngularVelocity(Ship, 0.0)

		if KeyBoard = 0
			JX = GetVirtualJoystickX(Stick1)
			B1 = GetVirtualButtonState(Button1)
			B2 = GetVirtualButtonState(Button2)
		endif

		rem Move Left
		if (GetRawKeystate(37) = 1 or JX < 0) and Active = 1
			if sx > 30
				if Ship <> ShipL
					SetSpritePhysicsOff(Ship)
					SetSpritePositionByOffSet(Ship, -200, -200)
					Ship = ShipL
					SetSpritePhysicsOn(Ship, 2)
					SetSpritePositionByOffSet(Ship, sx, sy)
				endif
				ShipVX = -10
				SetSpritePhysicsVelocity(Ship, ShipVX, 0.0)
			else
				if Ship <> ShipF
					SetSpritePhysicsOff(Ship)
					SetSpritePositionByOffset(Ship, -200, -200)
					Ship = ShipF
					SetSpritePhysicsOn(Ship, 2)
					SetSpritePositionByOffset(Ship, sx, sy)
				endif
				ShipVX = 0
				SetSpritePhysicsVelocity(Ship, ShipVX, 0.0)
			endif
		endif

		rem Move Right
		if (GetRawKeystate(39) = 1 or JX > 0) and Active = 1
			if sx < 290
				if Ship <> ShipR
					SetSpritePhysicsOff(Ship)
					SetSpritePositionByOffSet(Ship, -200, -200)
					Ship = ShipR
					SetSpritePhysicsOn(Ship, 2)
					SetSpritePositionByOffset(Ship, sx, sy)
				endif
				ShipVX = 10
				SetSpritePhysicsVelocity(Ship, ShipVX, 0.0)
			else
				if Ship <> ShipF
					SetSpritePhysicsOff(Ship)
					SetSpritePositionByOffset(Ship, -200, -200)
					Ship = ShipF
					SetSpritePhysicsOn(Ship, 2)
					SetSpritePositionByOffset(Ship, sx, sy)
				endif
				ShipVX = 0
				SetSpritePhysicsVelocity(Ship, ShipVX, 0.0)
			endif
		endif

		rem Reset after turning
		if GetRawKeystate(37) = 0 and GetRawKeystate(39) = 0 and JX = 0
			if Ship <> ShipF
				SetSpritePhysicsOff(Ship)
				SetSpritePositionByOffset(Ship, -200, -200)
				Ship = ShipF
				SetSpritePhysicsOn(Ship, 2)
				SetSpritePositionByOffset(Ship, sx, sy)
			endif
			ShipVX = 0
			SetSpritePhysicsVelocity(Ship, ShipVX, 0.0)
		endif

		rem Fire Photons
		if t# - firetime# > 0.325 then firetime# = 0.0

		if (GetRawKeyState(32) = 1 or B2 = 1) and firetime# = 0.0 and Active = 1
			nl = 1
			if TriShotActive = 1 then nl = 3
			al = 0
			for fx = 1 to LaserCount
				if Laser[fx].act = 0
					al = al + 1
					if al = 1 then SetSpritePositionByOffset(Laser[fx].spr, sx, sy-72)
					if al = 2 then SetSpritePositionByOffset(Laser[fx].spr, sx+32, sy-72)
					if al = 3 then SetSpritePositionByOffset(Laser[fx].spr, sx-32, sy-72)
					SetSpritePhysicsDelete(Laser[fx].spr)
					SetSpritePhysicsOn(Laser[fx].spr, 2)
					if nl = 1
						SetSpritePhysicsVelocity(Laser[fx].spr, ShipVX/2, -25.0)
					else
						if al = 1 then SetSpritePhysicsVelocity(Laser[fx].spr, 0.0, -25.0)
						if al = 2 then SetSpritePhysicsVelocity(Laser[fx].spr, 5.0, -25.0)
						if al = 3 then SetSpritePhysicsVelocity(Laser[fx].spr, -5.0, -25.0)
					endif
					Laser[fx].act = 1
					if nl = 3
						SetSpriteColor(Laser[fx].spr, 64, 255, 64, 255)
					else
						SetSpriteColor(Laser[fx].spr, 64, 64, 255, 255)
					endif
					if al = nl
						al = 0
						if optSound = 1
							PlaySound(SndLaser, optSoundVol, 0, 0)
						endif
						exit
					endif
				endif
			next fx
			firetime# = t#
		endif

		rem Release the bomb if you've captured the Powerup
		if (GetRawKeystate(38) = 1 or B1 = 1) and BombActive = 1 and BombTime = 0
			SetSpritePositionByOffset(Bomb, GetSpriteXByOffset(Ship), GetSpriteYByOffset(Ship)-16)
			BombTime = t#
		endif

		rem Escape to exit if you have a keyboard
		tx = GetPointerX()
		ty = GetPointerY()
		ti = GetPointerState()
		if GetRawKeystate(27) = 1 or (tx > sw/2 - 100 and tx < sw/2 + 100 and ty > sh/2 - 100 and ty < sh/2 + 100 and ti > 0)
			while GetRawKeyState(27) = 1
				sync()
			endwhile
			while GetPointerState() = 1
				sync()
			endwhile
			exit
		endif

		rem Exit the Game Loop if you are out of lives and you die
		if Lives = 0 and Dead = 1
			Active = 0
			exit
		endif

		Sync ( )

	loop

	rem Remove the virtual controls before leaving the Game Loop
	if KeyBoard = 0
		DeleteVirtualJoystick(Stick1)
		DeleteVirtualButton(Button1)
		DeleteVirtualButton(Button2)
	endif

	rem Clean up the Photons
	for x = 1 to LaserCount
		Laser[x].act = 0
		SetSpritePhysicsOff(Laser[x].spr)
		SetSpritePosition(Laser[x].spr, sw/2, sh+50)
	next x

	rem Clean up the Asteroids
	for x = 1 to AsteroidCount
		Asteroids[x].act = 0
		SetSpritePhysicsOff(Asteroids[x].spr)
		SetSpritePosition(Asteroids[x].spr, sw/2, -100)
	next x

	rem Move Text Objects off screen
	SetTextPosition(tLevel, 0, -50)
	SetTextPosition(tRoundTime, 0, -50)
	SetTextPosition(tCountdown, 0, -50)

	rem Move the ship off screen
	SetSpritePhysicsOff(Ship)
	SetSpritePositionByOffset(Ship, -100, -100)

	rem Check if the player got a High Score
	for x = 1 to 10
		if Score > HiScores[x].sc then exit
	next x
	if x < 11
		gosub EnterInitials
		gosub SendHiScore
	endif

	rem Move the Powerup icons off screen
	SetSpritePosition(iBomb, -100, -100)
	SetSpritePosition(iTriShot, -100, -100)

	rem Game Over screen
	if Lives = 0 and Dead = 1
		SetSpritePositionByOffset(PUShield, sw/2, -100)
		SetSpritePositionByOffset(PUTriShot, sw/2, -100)
		SetSpritePositionByOffset(PUBomb, sw/2, -100)
		PUShieldActive = 0
		PUTriShotActive = 0
		PUBombActive = 0
		SetSpritePosition(ABLogo, 32, 0)
		SetTextPosition(tGameOver, sw/2-(GetTextTotalWidth(tGameOver)/2.0), 230)
		t# = timer()
		do
			if timer() - t# > 4.0 then exit
			sync()
		loop
		SetSpritePosition(ABLogo, -300, -300)
		SetTextPosition(tGameOver, 0, -50)
	endif

	if x < 11 then goto HiScoreScreen

	Branch = 0

return


rem Intermission Screen
Intermission:
	SetTextPosition(tRoundTime, 0, -50)
	SetSpritePosition(iBomb, -100, -100)
	SetSpritePosition(iTriShot, -100, -100)
	SetTextString(tScore, "Score : "+str(Score))
	SetTextString(tLevel, "Level : "+str(Level))
	SetTextPosition(tLevel, sw/2-(GetTextTotalWidth(tLevel)/2.0), sh/2-30)
	for x = 1 to AsteroidCount
		Asteroids[x].act = 0
		SetSpritePositionByOffset(Asteroids[x].spr, Random(20, sw-20), -50)
		SetSpritePhysicsOff(Asteroids[x].spr)
	next x
	for x = 1 to LaserCount
		Laser[x].act = 0
		SetSpritePositionByOffset(Laser[x].spr, -100, sh+50)
	next x

	SetSpritePosition(PUShield, sw/2, -100)
	SetSpritePosition(Shield, -300, -300)
	PUShieldActive = 0
	SetSpritePosition(PUTriShot, sw/2, -100)
	PUTriShotActive = 0
	SetSpritePosition(PUBomb, sw/2, -100)
	SetSpritePosition(Bomb, -150, -150)
	PUBombActive = 0
	SetSpritePosition(Nebulas[Nebula].spr, -800, -600)
	Nebula = Random(1, 4)
	SetSpritePosition(Nebulas[Nebula].spr, 0, 0)
	dead = 0
	CountdownTime = timer()
	SetTextPosition(tCountdown, sw/2-10, sh/2-10)

	do
		t# = timer()
		CT = 5 - (t# - CountdownTime)
		if CT = 0
			SetTextPosition(tLevel, 0, -50)
			SetTextString(tCountDown, "GO!")
			SetTextPosition(tCountdown, sw/2-32, sh/2-10)
		else
			SetTextString(tCountdown, str(CT))
		endif
		if t# - CountdownTime > 5
			RoundTime = t#
			CountdownTime = 0
			asteroidTime# = t#
			SetTextPosition(tRoundTime, sw/2-10, 0)
			SetTextPosition(tCountdown, 0, -50)
			Active = 1
			ShieldActive = 0
			ShieldHits = 0
			ShieldTime = 0
			PUShieldDrop = t# + Random(10, 30)
			TriShotActive = 0
			TriShotTime = 0
			PUTriShotDrop = t# + Random(10, 30)
			BombActive = 0
			BombTime = 0
			PUBombDrop = t# + Random(10, 30)
			asteroidFreq# = 0.81 - (Level * 0.01)
			Ship = ShipF
			SetSpritePositionByOffset(Ship, sw/2, sh-100)
			SetSpritePhysicsOn(Ship, 2)
			SetTextPosition(tScore, 0, 0)
			SetTextPosition(tLives, sw-GetTextTotalWidth(tLives), 0)
			if KeyBoard = 0
				AddVirtualJoystick(Stick1, 50, sh-50, 50)
				AddVirtualButton(Button1, sw-100, sh-50, 50)
				SetVirtualButtonColor(Button1, 255, 255, 0)
				AddVirtualButton(Button2, sw-50, sh-50, 50)
				SetVirtualButtonColor(Button2, 255, 0, 0)
			endif
			exit
		endif

		sync()

	loop

return


rem Explosions
Explosions:
	if fire = 1
		SetParticlesPosition(Explode, ExplodeX, ExplodeY)
		ResetParticleCount(Explode)
		SetParticlesFrequency(Explode, ExpFreq)
		SetParticlesLife(Explode, ExpLife)
		SetParticlesSize(Explode, 32)
		SetParticlesStartZone(Explode, -10, 0, 10, 0)
		SetParticlesImage(Explode, Shrapnel)
		SetParticlesDirection(Explode, 10, 10)
		SetParticlesAngle(Explode, 360)
		SetParticlesVelocityRange(Explode, 5.0, 20.0)
		SetParticlesMax(Explode, ExpMax)
		AddParticlesColorKeyFrame(Explode, 0.0, 0, 0, 0, 0)
		AddParticlesColorKeyFrame(Explode, (ExpLife * 0.25), 255, 255, 0, 255)
		AddParticlesColorKeyFrame(Explode, (ExpLife * 0.75), 255, 64, 64, 0)
		fire = 0
	endif
return


rem Enter Initials
EnterInitials:
	t1 = CreateText("YOU HAVE A HIGH SCORE!!")
	SetTextSize(t1, 18)
	SetTextPosition(t1, sw/2-(GetTextTotalWidth(t1)/2), 30)
	t2 = CreateText("Enter Your Initials")
	SetTextSize(t2, 18)
	SetTextPosition(t2, sw/2-(GetTextTotalWidth(t2)/2), 50)

	StartTextInput()
	Text$ = ""
	do
		if GetTextInputCompleted() = 1
			if GetTextInputCancelled() = 0
				Text$ = GetTextInput()
				if len(Text$) < 4
					optInitials$ = Text$
				endif
			endif
			exit
		endif
		sync()
	loop

	DeleteText(t1)
	DeleteText(t2)
return


rem High Score Screen
HiScoreScreen:
	gosub GetHighScores
	SetSpritePosition(HiScoreSpr2, 32, 30)
	SetTextPosition(HiScoreHeader, sw/2-(GetTextTotalWidth(HiScoreHeader)/2), 100)
	for x = 1 to 10
		SetTextPosition(HiScores[x].txt, sw/2-(GetTextTotalWidth(HiScores[x].txt)/2), 100+(x * 24))
	next x
	SetSpritePosition(BackSpr, 92, 410)

	do
		tx = GetPointerX()
		ty = GetPointerY()
		ti = GetPointerState()

		if tx > GetSpriteX(BackSpr) and tx < GetSpriteX(BackSpr)+GetSpriteWidth(BackSpr)
			if ty > GetSpriteY(BackSpr) and ty < GetSpriteY(BackSpr)+GetSpriteHeight(BackSpr)
				if ti > 0
					SetSpritePosition(HiScoreSpr2, -300, -300)
					SetSpritePosition(BackSpr, -300, -300)
					SetTextPosition(HiScoreHeader, 0, -50)
					for x = 1 to 10
						SetTextPosition(HiScores[x].txt, 0, -50)
					next x
					while GetPointerState() = 1
						sync()
					endwhile
					exit
				endif
			endif
		endif

		sync()
	loop

return


rem Options Screen
OptionsScreen:
	OptionsImg = LoadImage("Options.png", 0)
	Options = CreateSprite(OptionsImg)
	SetSpriteScale(Options, 1.5, 1.5)
	MusicImg = LoadImage("Music.png", 0)
	Music = CreateSprite(MusicImg)
	SoundImg = LoadImage("Sound.png", 0)
	Sound = CreateSprite(SoundImg)

	SetSpritePosition(Options, 64, 8)
	SetSpritePosition(Music, 92, 110)
	SetSpritePosition(Sound, 92, 210)

	HoverImg = LoadImage("Btn_Hover.png", 0)
	Hover = CreateSprite(HoverImg)
	SetSpriteDepth(Hover, 5)
	MusicSelect = CreateSprite(HoverImg)
	SetSpriteScale(MusicSelect, 2, 1)
	SetSpriteDepth(MusicSelect, 5)
	SetSpriteColor(MusicSelect, 64, 64, 64, 128)
	SoundSelect = CreateSprite(HoverImg)
	SetSpriteScale(SoundSelect, 2, 1)
	SetSpriteDepth(SoundSelect, 5)
	SetSpriteColor(SoundSelect, 64, 64, 64, 128)

	OnImg = LoadImage("Btn_ON.png", 0)
	On1 = CreateSprite(OnImg)
	SetSpriteDepth(On1, 4)
	SetSpriteShape(On1, 3)
	On2 = CreateSprite(OnImg)
	SetSpriteDepth(On2, 4)
	SetSpriteShape(On2, 3)
	OffImg = LoadImage("Btn_OFF.png", 0)
	Off1 = CreateSprite(OffImg)
	SetSpriteDepth(Off1, 4)
	SetSpriteShape(Off1, 3)
	Off2 = CreateSprite(OffImg)
	SetSpriteDepth(Off2, 4)
	SetSpriteShape(Off2, 3)

	SetSpritePosition(On1, sw/2-100, 164)
	SetSpritePosition(Off1, sw/2+48, 164)
	SetSpritePosition(On2, sw/2-100, 264)
	SetSpritePosition(Off2, sw/2+48, 264)

	SetSpritePosition(BackSpr, 92, 410)

	Entry = 1

	do
		if optMusic = 1
			SetSpritePosition(MusicSelect, GetSpriteX(On1), GetSpriteY(On1))
		else
			SetSpritePosition(MusicSelect, GetSpriteX(Off1), GetSpriteY(Off1))
		endif
		if optSound = 1
			SetSpritePosition(SoundSelect, GetSpriteX(On2), GetSpriteY(On2))
		else
			SetSpritePosition(SoundSelect, GetSpriteX(Off2), GetSpriteY(Off2))
		endif
		tx = GetPointerX()
		ty = GetPointerY()
		ti = GetPointerState()
		SetSpritePosition(Hover, -40, -40)
		SetSpriteScale(Hover, 1, 1)

		if tx > GetSpriteX(On1) and tx < GetSpriteX(On1)+GetSpriteWidth(On1)
			if ty > GetSpriteY(On1) and ty < GetSpriteY(On1)+GetSpriteHeight(On1)
				SetSpriteScale(Hover, 2, 1)
				SetSpritePosition(Hover, GetSpriteX(On1), GetSpriteY(On1))
				if ti > 0
					optMusic = 1
				endif
			endif
		endif

		if tx > GetSpriteX(On2) and tx < GetSpriteX(On2)+GetSpriteWidth(On2)
			if ty > GetSpriteY(On2) and ty < GetSpriteY(On2)+GetSpriteHeight(On2)
				SetSpriteScale(Hover, 2, 1)
				SetSpritePosition(Hover, GetSpriteX(On2), GetSpriteY(On2))
				if ti > 0
					optSound = 1
				endif
			endif
		endif

		if tx > GetSpriteX(Off1) and tx < GetSpriteX(Off1)+GetSpriteWidth(Off1)
			if ty > GetSpriteY(Off1) and ty < GetSpriteY(Off1)+GetSpriteHeight(Off1)
				SetSpriteScale(Hover, 2, 1)
				SetSpritePosition(Hover, GetSpriteX(Off1), GetSpriteY(Off1))
				if ti > 0
					optMusic = 0
				endif
			endif
		endif

		if tx > GetSpriteX(Off2) and tx < GetSpriteX(Off2)+GetSpriteWidth(Off2)
			if ty > GetSpriteY(Off2) and ty < GetSpriteY(Off2)+GetSpriteHeight(Off2)
				SetSpriteScale(Hover, 2, 1)
				SetSpritePosition(Hover, GetSpriteX(Off2), GetSpriteY(Off2))
				if ti > 0
					optSound = 0
				endif
			endif
		endif

		if tx > GetSpriteX(BackSpr) and tx < GetSpriteX(BackSpr)+GetSpriteWidth(BackSpr)
			if ty > GetSpriteY(BackSpr) and ty < GetSpriteY(BackSpr)+GetSpriteHeight(BackSpr)
				if ti > 0
					DeleteSprite(On1)
					DeleteSprite(On2)
					DeleteImage(OnImg)
					DeleteSprite(Off1)
					DeleteSprite(Off2)
					DeleteImage(OffImg)
					DeleteSprite(MusicSelect)
					DeleteSprite(SoundSelect)
					DeleteSprite(Hover)
					DeleteImage(HoverImg)
					DeleteSprite(Options)
					DeleteImage(OptionsImg)
					DeleteSprite(Music)
					DeleteImage(MusicImg)
					DeleteSprite(Sound)
					DeleteImage(SoundImg)
					SetSpritePosition(BackSpr, -300, -300)
					f = OpenToWrite("Options.txt", 0)
					WriteInteger(f, optSound)
					WriteInteger(f, optSoundVol)
					WriteInteger(f, optMusic)
					WriteInteger(f, optMusicVol)
					CloseFile(f)
					while GetPointerState() = 1
						sync()
					endwhile
					exit
				endif
			endif
		endif

		sync()
	loop
return


rem Get High Scores from the Server
GetHighScores:
	if fade = 1
		SetSpritePosition(1, 0, 0)
		SetSpriteColor(1, 0, 0, 0, 0)
		a = 0
		t# = timer()
		do
			a = a + 3
			if a => 255 then a = 255
			SetSpriteColor(1, 0, 0, 0, a)
			if timer() - t# > 1.5 then exit
			sync()
		loop
	endif
	SetTextPosition(tGetHiScore, sw/2-(GetTextTotalWidth(tGetHiScore)/2), sh/2-10)

	c$ = "Client"+str(Random())
	iNetID = JoinNetwork("50.43.112.52", 4100, c$)
	t# = timer()
	do
		if iNetID > 0
			c = GetNetworkNumClients(iNetID)
			if c > 1 then exit
		endif
		if timer() - t# > 4.0 then exit
		sync()
	loop

	if isNetworkActive(iNetID) = 0
		SetTextPosition(tGetHiScore, 0, -50)
		SetTextPosition(tNetworkError1, sw/2-(GetTextTotalWidth(tNetworkError1)/2), sh/2-20)
		SetTextPosition(tNetworkError2, sw/2-(GetTextTotalWidth(tNetworkError2)/2), sh/2)
		t# = timer()
		do
			if timer() - t# > 4.0 then exit
			sync()
		loop
	else
		sid = GetNetworkServerID(iNetID)
		t# = timer()
		do
			msg = GetNetworkMessage(iNetID)
			if msg > 0
				id = GetNetworkMessageFromClient(msg)
				if id = sid
					f = OpenToWrite("Scores.txt")
					f# = GetNetworkMessageFloat(msg)
					if f# = 1.0
						for x = 1 to 10
							n$ = GetNetworkMessageString(msg)
							WriteString(f, n$)
							HiScores[x].sc = GetNetworkMessageInteger(msg)
							WriteInteger(f, HiScores[x].sc)
							tTemp = CreateText(str(HiScores[x].sc))
							fx = GetTextLength(tTemp)
							DeleteText(tTemp)
							fx = fx - (3 - len(n$))
							n$ = n$ + " "
							for y = 1 to 13 - fx
								n$ = n$ + "."
							next y
							n$ = n$ + " " + str(HiScores[x].sc)
							SetTextString(HiScores[x].txt, n$)
						next x
					endif
					CloseFile(f)
					DeleteNetworkMessage(msg)
					exit
				endif
			endif

			if timer() - t# > 5.0 then exit

			sync()
		loop
	endif

	if isNetworkActive(iNetID) = 1 then CloseNetwork(iNetID)
	SetTextPosition(tGetHiScore, 0, -50)
	SetTextPosition(tNetworkError1, 0, -50)
	SetTextPosition(tNetworkError2, 0, -50)
	if fade = 1
		t# = timer()
		a = 255
		do
			a = a - 3
			if a < 0 then a = 0
			SetSpriteColor(1, 0, 0, 0, a)
			if timer() - t# > 1.5 then exit
			sync()
		loop
	endif
	SetSpritePosition(1, -sw, 0)
return


SendHiScore:
	iNetID = JoinNetwork("50.43.112.52", 4100, "Client"+str(Random()))
	t# = timer()
	do
		if isNetworkActive(iNetID) = 1
			if Score > 0
				sid = GetNetworkServerID(iNetID)
				msg = CreateNetworkMessage()
				AddNetworkMessageFloat(msg, 1.1)
				AddNetworkMessageString(msg, optInitials$)
				AddNetworkMessageInteger(msg, Score)
				SendNetworkMessage(iNetID, sid, msg)
				DeleteNetworkMessage(msg)
				Score = 0
			endif
			if timer() - t# > 2.0
				exit
			endif
		endif
		if timer() - t# > 4.0 then exit
		sync()
	loop

	if isNetworkActive(iNetID) = 1
		CloseNetwork(iNetID)
	endif
return


rem Instructions Screen
Instructions:
	SetSpritePosition(BackSpr, 92, 420)
	t[1] = CreateText("Instructions")
	t[2] = CreateText("Left/Right Arrows or Joystick")
	t[3] = CreateText("moves the ship")

	t[4] = CreateText("SPACE or Red Button Fires")

	t[5] = CreateText("Up Arrow or Yellow Button")
	t[6] = Createtext("launches bomb when available")

	t[7] = Createtext("Larger Asteroids must be")
	t[8] = Createtext("shot twice and may drop")
	t[9] = Createtext("Powerups")

	t[10] = Createtext("Shields last for 20 seconds")
	t[11] = Createtext("but can only take 3 hits")

	t[12] = CreateText("You must have a positive")
	t[13] = CreateText("score at the end of a level")
	t[14] = CreateText("to advance to the next level.")

	t[15] = CreateText("Touch/Click the center of the")
	t[16] = CreateText("screen to return to the menu.")

	SetTextSize(t[1], 18)
	for x = 2 to 16
		SetTextSize(t[x], 16)
	next x

	SetTextPosition(t[1], sw/2-(GetTextTotalWidth(t[1])/2), 20)
	SetTextPosition(t[2], 10, 60)
	SetTextPosition(t[3], 10, 80)

	SetTextPosition(t[4], 10, 110)

	SetTextPosition(t[5], 10, 140)
	SetTextPosition(t[6], 10, 160)

	SetTextPosition(t[7], 10, 190)
	SetTextPosition(t[8], 10, 210)
	SetTextPosition(t[9], 10, 230)

	SetTextPosition(t[10], 10, 260)
	SetTextPosition(t[11], 10, 280)

	SetTextPosition(t[12], 10, 310)
	SetTextPosition(t[13], 10, 330)
	SetTextPosition(t[14], 10, 350)

	SetTextPosition(t[15], 10, 380)
	SetTextPosition(t[16], 10, 400)

	do
		tx = GetPointerX()
		ty = GetPointerY()
		ti = GetPointerState()
		if tx > GetSpriteX(BackSpr) and tx < GetSpriteX(BackSpr)+GetSpriteWidth(BackSpr)
			if ty > GetSpriteY(BackSpr) and ty < GetSpriteY(BackSpr)+GetSpriteHeight(BackSpr)
				if ti > 0
					SetSpritePosition(BackSpr, -300, -300)
					while GetPointerState() = 1
						sync()
					endwhile
					exit
				endif
			endif
		endif

		sync()

	loop

	for x = 1 to 16
		DeleteText(t[x])
	next x
return
Posted: 11th Aug 2011 20:51
I can understand your concerns Nomad soul, there does seem a lot of variables and such needed to be set up for such a simple game demo. However everyone has there own style of programming. I wouldn't let this code put you off because it looks complicated. Remember, KIStech is new to AppGameKit and this is his first proper demo. So his code is possibly longer than really needed. You tend to learn shortcuts as you develop with a language.

I have only glanced over the code, but I don't see anything mega difficult in there in itself, it is just the amount of code that can overwhelm a little. I would say if you can duplicate what KIStech did in DB, you can do it in AGK.

The main gripe so far from reading around is the lack of image and bitmap manipulation commands. I use both a lot currently in DB. Using sprites only, and not being able to paste them does put me off a little. Even the lack of dot and line commands annoys me, and in all honesty I rarely use them in any finished project. However I do sometimes use them to get a general idea of the screen layout before making the relevant sprites or planes. This is a relatively small gripe though in the main.

One question I would ask though is the speed of the game. Did you have any issues with it? For me I would have had to increase the rate of movement by at least 2x for it to be anything like playable and fun. It may be you didn't pay any regard to that and just did a demo. It could be due to the avi capture. I do worry about a phones ability to throw this stuff around compared to say, a quad core PC and a reasonably fast video card.

Obviously this is the PC version we have seen, as you stated the beta version you used was windows only. Compared to DB pro, how fast does AppGameKit seem?
Posted: 11th Aug 2011 21:21
Are you referring to the side-to-side movement of the ship? It seems slow, but it adds to the difficulty of the game. If you have 2 asteroids on either side of the screen you have to choose which one you'll go after, because if you don't have the shield to extend your reach you probably aren't going to make it across to get the other one in time.

I played around with the speed of things quite a lot, and have played the game more times than I can count. It's fairly well optimized for the objective of the game.

As you progress in level, the rate at which the asteroids fall increases slightly.

For overall app speed, it runs just as well on my iPod Touch 4th gen as it does on the PC running a 3GHz Core2Duo and nVidia 9800GT. However this is a very simple game with less than 200 sprites loaded. More complex games will of course impact performance on slower devices.
Posted: 11th Aug 2011 21:56
I refer to the overall speed really. I used to play a lot of shooters such as R-type, Nemesis, Thunderforce, Parodius, Fantasy Zone etc. The difficulty on your demo here looks somewhat easier in comparison. Like I said it depends on what you were going for. It sounds as if you got it how you wanted, I would have made it a little more fast and furious, because that is what I expect from a shooter.

Good to know you have similar performance on both test systems, I take it you had an update since you mentioned windows only in prior posts. I was wondering mainly regarding speed as in DB compared to AppGameKit on a PC. Does AppGameKit seem similar, better or worse? Have you done any speed comparisons in both? It would be interesting to hear how they compare on a like for like basis.
Posted: 11th Aug 2011 23:29
AGK runs about the same as DBP apps on a PC.
I haven't really run into any performance issues from AppGameKit yet.