So, I found this little flash game called
Last Square Standing and thought that is was a brilliant game to try to remake with AGK.
So I did. It's my first attempt at actually finishing a project in AppGameKit so there is probably bugs and performance issues in it. But it was fun to work on and pretty fun to play.
I'm posting the source code here instead of the compiled version, this way people can learn from it or perhaps give me feedback in case I've done something extraordinary dumb.
REM Set up display
SetDisplayAspect( 4.0/3.0 ) REM Set display aspect to use percent system.
SetClearColor(100, 149, 237) REM Set background to a pleasing blue color.
REM Set up controls
SetJoystickScreenPosition(8, 90, 10) REM If no joystick present WASD will be used.
REM Setup texts for menus
CreateText(1, "Last Square Standing") REM The title of the game.
SetTextPosition(1, 25, 20)
SetTextSize(1, 5) REM Title should be larger that other text.
SetTextColor(1, 255, 255, 0, 255)
CreateText(2, "Avoid any and all obstacles to make your square last as long as possible. You control your square with the WASD-keys on the keyboard.")
SetTextSize(2, 2.5)
SetTextPosition(2, 25, 30)
SetTextMaxWidth(2, 55)
CreateText(3, "Press space to start your game")
SetTextPosition(3, 27, 50)
SetTextSize(3, 3)
CreateText(4, "Game over")
SetTextPosition(4, 40, 30)
SetTextSize(4, 4)
SetTextVisible(4, 0) REM Hide game over text until game is actually over.
REM Load the images.
playerImage = LoadImage("YellowSquare.png") REM The yellow square that represents the player.
enemyImage = LoadImage("OrangeCircle.png") REM The orange circle that represents the enemy.
REM Create and position the player sprite
playerSprite = 1 REM Set player sprite to 1 because I can't figure out how the global keyword works.
CreateSprite(1, playerImage) REM Create the sprite that the player will control.
SetSpriteSize(playerSprite, 2.5, -1) REM Set the size of the sprite.
SetSpritePosition(playerSprite, 50, 50) REM Set player to center of screen.
playerWidth# = GetSpriteWidth(playerSprite) REM Player dimensions will be used for hit detection.
playerHeight# = GetSpriteHeight(playerSprite) REM For performance reasons will only be taken once.
SetSpriteVisible(playerSprite, 0) REM Hide the player sprite untill the game actually starts.
REM Set up the enemies array.
REM Each enemy needs to have a sprite and a direction.
REM This information will be stored in this in a handy "object".
Type Enemy REM The enemy object.
Sprite REM The sprite for the current instance of the enemy.
DirectionX# REM The direction the enemy will travel while on screen.
DirectionY#
EndType
Dim enemies[100] As Enemy REM Stores the enemies that will be created during game play.
numberOfEnemies = 0 REM How many enemies has been created so far.
REM Total number of enemies. Increase this for more difficult game.
#Constant MAX_NUMBER_OF_ENEMIES 30
REM Misc variables for gameplay.
second = 0 REM Used to calculate when a new enemy will be spawned.
gamestate = 0 REM The state of the game, 0 is the first menu, 1 is game is currently playing, 2 is game over.
Repeat
Select gamestate
Case 0:
If GetButtonState(1) = 1 REM Player pressed the button, time to start the game.
SetTextVisible(1, 0) REM Hide all the text.
SetTextVisible(2, 0)
SetTextVisible(3, 0)
SetSpriteVisible(playerSprite, 1) REM Show the player sprite
Inc gamestate REM Set gamestate to 1, playing.
EndIf
EndCase
Case 1:
REM Moving the player.
JoystickX# = GetJoystickX() REM Get the x-input.
JoystickY# = GetJoystickY() REM Get the y-input
playerX# = GetSpriteX(playerSprite) REM Get players current x-position.
playerY# = GetSpriteY(playerSprite) REM Get pleyers current y-position
REM Move the player
SetSpritePosition(playerSprite, playerX# + (joystickX# / 2.0), playerY# + (joystickY# / 2.0)) REM move the player based of joystick input.
REM Check if player hits a wall
playerX# = GetSpriteX(playerSprite) REM Get players x-position after movement.
playerY# = GetSpriteY(playerSprite) REM Get pleyers y-position after movement.
If playerX# < 0 Then Inc gamestate REM Player hit a wall, increment gamestate to 2, game over.
If playerX# > 100 - playerWidth# Then Inc gamestate
If playerY# < 0 Then Inc gamestate
If playerY# > 100 - playerHeight# Then Inc gamestate
REM move the enemies
For i= 1 To numberOfEnemies
SX# = GetSpriteX(enemies[i].Sprite)
SY# = GetSpriteY(enemies[i].Sprite)
SetSpritePosition(enemies[i].Sprite, SX# + enemies[i].DirectionX#, SY# + enemies[i].DirectionY#) REM Move the enemy based on it's direction.
If SX# < 0 Or SX# > 100 Or SY# < 0 Or SY# > 100 Then ResetEnemy(i) REM Enemy moved off screen. Give it new position and direction.
REM Collision detection for enemies and player.
If GetSpriteCollision(enemies[i].Sprite, playerSprite) = 1 Then Inc gamestate REM Enemy collided with the player. Increment gamestate to 2, game over.
Next i
REM Spawning enemies
If numberOfEnemies < MAX_NUMBER_OF_ENEMIES
currentSecond = GetSeconds()
If currentSecond - second > 2 REM Every other second, spawn new enemy
Inc numberOfEnemies REM Increment number of enemies
GoSub SetupNewEmemy REM Give enemy a position and direction.
second = currentSecond REM store the current second.
EndIf
EndIf
EndCase
Case 2:
If numberOfEnemies > 0 REM If enemies has been created, delete them.
For i = 1 To numberOfEnemies
DeleteSprite(enemies[i].Sprite) REM Delete the enemy.
Next i
EndIf
REM Reset game.
numberOfEnemies = 0 REM Reset the number of enemies.
SetSpriteVisible(playerSprite, 0) REM Hide the player sprite
SetSpritePosition(playerSprite, 50, 50) REM Reset the player sprite position
REM Show text for menu.
SetTextVisible(1, 1)
SetTextVisible(3, 1)
SetTextVisible(4, 1)
If GetButtonState(1) = 1 REM Player starts a new game.
SetTextVisible(1, 0)
SetTextVisible(2, 0)
SetTextVisible(3, 0)
SetTextVisible(4, 0)
SetSpriteVisible(playerSprite, 1) REM Show player sprite again.
Dec gamestate REM Decrement gamestate to 1, game playing.
EndIf
EndCase
EndSelect
Sync()
Until GetRawKeyPressed(27) = 1
SetupNewEmemy:
newEnemy As Enemy REM Create a new enemy.
newEnemy.Sprite = CreateSprite(enemyImage) REM Create a new sprite for this enemy.
SetSpriteSize(newEnemy.Sprite, 2.5, -1) REM Set the size of the sprite.
SetSpriteShape(newEnemy.Sprite, 1) REM Enemy is a circle after all, this may impact collision detection. Honestly I don't know.
SetSpriteGroup(newEnemy.Sprite, 2) REM Eenemies belong in their own sprite group. This might be important.
enemies[numberOfEnemies] = newEnemy REM Append the enemy to the enemies array.
ResetEnemy(numberOfEnemies) REM Give the enemy a starting position and a direction.
return
Function ResetEnemy(i)
REM position sprite along screen edge. Randomize the edge.
screenEdge = Random(1, 4)
Select screenEdge
Case 1: REM Top
EX# = Random(1, 99)
EY# = 0.1
EndCase
Case 2: REM Right
EX# = 98.5
EY# = Random(1, 99)
EndCase
Case 3: REM Bottom
EX# = Random(1, 99)
EY# = 98.5
EndCase
Case 4: REM Left
EX# = 0.1
EY# = Random(1, 99)
EndCase
EndSelect
SetSpritePosition(enemies[i].Sprite, EX#, EY#) REM The enemys starting position.
PX# = GetSpriteX(1) REM Find the position of the player.
PY# = GetSpriteY(1)
REM These lines figures out the direction of the player in relation to the enemy.
DX# = PX# - EX#
DY# = PY# - EY#
D# = Sqrt(DX# * DX# + DY# * DY#) * 4.0 REM The multiplier helps control the speed of the enemy. Adjust this for more difficult game.
enemies[i].DirectionX# = DX# / D#
enemies[i].DirectionY# = DY# / D#
EndFunction
REM Remove all the resouces used.
DeleteSprite(playerSprite)
For i = 1 To numberOfEnemies
DeleteSprite(enemies[i].Sprite)
Next i
Undim enemies[100]
DeleteImage(playerImage)
DeleteImage(enemyImage)
DeleteText(1)
DeleteText(2)
DeleteText(3)
DeleteText(4)