AppGameKit Classic

AppGameKit Classic

67 ratings
Creating a basic platform game
By thescenecommander
Another basic coding guide using heavily documented code to demonstrate various coding techniques. This one is a little more complicated than previous ones and is aimed at the slightly more advanced user. However, if you've been following my previous guides and read the remarks, you shouldn't have too much difficulty following what's going on.
   
Award
Favorite
Favorited
Unfavorite
Controlling player movement - Description
Hi,

Welcome to another tutorial on game creation using AppGameKit . As I mentioned in the description, this one is aimed at the slightly more advanced user, but beginners should still find it fairly easy to pick up.

You'll need to set up a new project as normal and copy some media into the project media folder.

As before, we'll be using default media from the AppGameKit library. In this case from the SmackIt demo game. background.png and cloud1.png can be found in the main menu folder and the looking1.png can be found in the mole folder.

The images used are for demonstration purposes. The code is designed for square and rectangle shaped sprites as suits a platformer, so some of the collision may seem off as BOX collision is used.

Feel free to replace the media with your own for nice looking results.

The jumping system is very simple and could certain benefit from a liitle maths, but you should get the idea.

As with all of these guides, the intention of the code is to provide working examples from which you can develop your own games.

Crrently all of the platforms are placed randomly, but on running the code you should see something like this.



You'll find the code ready fo cut and pasting below





Controlling player movement - The source code.
// Project: platform
// Created: 2015-02-17

// set window properties
SetWindowTitle( "platform" )
SetWindowSize( 1024, 768, 0 )

// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )

//force sync rate to 60 for best cross platform support.
SetSyncRate(60,0)

// define a type for the platforms
type platformstype
sprite as integer
x as integer
y as integer
endtype

// create a platform array allowing for 30 platforms
dim platform[30] as platformstype

// define a type for the player and assign values for position, jumping and a falling flag.
type playertype
sprite as integer
x as integer
y as integer
jumping as integer
jumptime as integer
falling as integer
contact as integer
endtype

// create a player variable based on the type
global player as playertype

// load in some images and create sprites.
// The media used for this demo can be located in the Smackit demo game provided with AppGameKit.
// Background and cloud1 can be found in the main menu folder
// looking1 can be found in the mole folder.
// As with previous tutorials , copy and paste these images into the media folder for this demo.

LoadImage (1,"background.png")
CreateSprite(1,1)
// As the background image is too small for the demo size, enlarge the sprite to fit.
SetSpriteSize(1,1024,768)
// This sprite won't be doing anything other than look pretty, so make non active.
SetSpriteActive(1,0)

//load default platform
LoadImage(2,"cloud1.png")
CreateSprite(2,2)
// Set a consistant size for the sprite, this makes it easier to detect collisions by limiting overlaps.
SetSpriteSize(2,64,64)
// We will be cloning this sprite so we won't need it to be active or visible.
SetSpriteActive(2,0)
SetSpriteVisible(2,0)

//load mole as player
LoadImage(3,"looking1.png")
//make player sprite
CreateSprite(3,3)
// rescale sprite
SetSpriteSize(3,64,64)
//Set Sprite to box collision
SetSpriteShape(3,2)
SetSpriteDepth(3,9)

//set variables for inital position of player and sprite number. We don't need to set falling and jumping as by default these will be 0
player.x=round(512/64)*64
player.y=round(600/64)*64
player.sprite=3

buildplatforms()

//main loop
do

//display the player
displayplayer()
//check for movement and jumping
controlplayer()

sync()

loop

// We are using a function too display the player as it's often useful for future project development.
Function displayplayer()

SetSpritePosition(player.sprite,player.x,player.y)


EndFunction

Function controlplayer()

// read the keyboard to check for player movement, you can find all of the scancodes for the keys at the link below
// the function also controls forced movement
/http://www.appgamekit.com/documentation/guides/scancodes.htm


// left and right arrow keys for movement and space bar are used as a default.

If GetRawKeyState(32)=1 and player.jumping=0 and player.contact<>0 //if spacebar pressed and player NOT already jumping AND standing on a platform, start jump.
player.jumping=1 //jump straight up)
player.jumptime=1// start a count to see how long the player has been jumping.
endif

//if jumping, check to see if a direction has been added

if player.jumping=1

if GetRawKeyState(37)
player.jumping=2 //jump left
endif

if GetRawKeyState(39)
player.jumping=3 // jump right
endif
// lock out direction changes when jumping.

if player.jumping=1 then player.jumping=4

endif

//move left (decrease screen x position)
if GetRawKeyState(37) and player.jumping=0 and player.falling=0
dec player.x,2
endif

//move right (increase screen x position)
if GetRawKeyState(39) and player.jumping=0 and player.falling=0
inc player.x,2
endif



//if player is falling and they should be on the way down, then move player downwards.

//check to see it the player has hit a platform or is standing on one
standingonplatform=checkcollision()
// if they are stop all falling and jumping
if standingonplatform<>0 and player.jumptime>=64
player.falling=0
player.jumping=0
player.jumptime=0
endif

// if the player is falling, move them down the screen.
if player.falling<>0
inc player.y,2
endif

// if player jumping then move them up

if player.jumping<>0
inc player.jumptime,1
if player.jumptime<64
dec player.y,4
endif

// are they jumping left, if so move left

if player.jumping=2
dec player.x,2
endif

//are they junping right, if so move left

if player.jumping=3
inc player.x,2
endif

endif

//if the player has been jumping for long enough enter free fall.

if player.jumptime>=128
player.jumping=0
player.jumptime=0
endif

// safety code for demo, if player falls off bottom of screen reset positon.
if player.y>800
player.x=round(512/64)*64
player.y=round(600/64)*64
endif


EndFunction

Function checkcollision()

// reset collisons, assume player falling
collision=0
player.falling=1
player.contact=0

// go through platforms and check for collison

for checkplatform=1 to 30
// only return a true collision if the player sprite is standing on top of the platform (check Y position).
if GetSpriteCollision(player.sprite,platform[checkplatform].sprite) and Abs(platform[checkplatform].y-(player.y+round(GetSpriteHeight(player.sprite))))<3
// if true set collision to the platform number.
collision=checkplatform
// if collision found end loop for performance, closing loop by setting checkplatform to a value of 30, which is where the loop ends.
if collision<>0
checkplatform=31
player.falling=0
player.contact=collision
endif
endif

next checkplatform

remstart
// remmed out, but provides debug information.

print("PY="+str(platform[collision].y))
print("Playy="+str(player.y+round(GetSpriteHeight(player.sprite))))
print("Col="+str(collision))
print("falling="+str(player.falling))
print("jumping="+str(player.jumping))
print("jumptime="+str(player.jumptime))
remend


EndFunction collision

Function buildplatforms()

//Create random platforms, most user will want to build an editor for this.

for makeplatforms=1 to 30
// chose a random position. In this demo we're forcing the sprite to a 64x64 position. This is really a matter of preference, but again, aids collision be avoiding overlap.
randomx=round(random(1,950)/64)*64
randomy=round(random(100,700)/64)*64
//set to sprite to be created (remember we'll be cloning them)
platform[makeplatforms].sprite=9+makeplatforms
// If this is the first platform, place it below the player so they have something soft to fall on.
if makeplatforms=1
platform[makeplatforms].x=player.x
platform[makeplatforms].y=player.y+GetSpriteHeight(player.sprite)
//otherwise place it randomly.
else
platform[makeplatforms].x=randomx
platform[makeplatforms].y=randomy
endif

//clonse the sprite and set position and status.
CloneSprite(platform[makeplatforms].sprite,2)
SetSpriteActive(platform[makeplatforms].sprite,1)
SetSpriteVisible(platform[makeplatforms].sprite,1)
SetSpritePosition(platform[makeplatforms].sprite,platform[makeplatforms].x,platform[makeplatforms].y)
SetSpriteShape(platform[makeplatforms].sprite,2)
//end loop
next makeplatforms

EndFunction
Adding simple collectables - Description
Hi,

This next section changes some of the media for other default media and adds the concepts of a single collectable item which moves around. You could of course adapt this code to have many items. Again, this is to demonstrate the principal.

You will need two new pieces of media, again located in your AppGameKit projects folder.

You'll need:

blue.png which can be found in the AGK projects/version 2/sprites/PercentageSystem/media folder.

apple.png can be found in the SnakeSnacker folder in the demo games folder.

As before, both of these will need to be transferred into your platform game media folder.

This demo also introduces the concept of using timers to control life span.

You can cut and paste the code from below, which as normal, is fully documented, but of course, please ask if you've any questions.

If all goes well, you should see something similar to this

.
Adding Simple collectables - the source code part 1
// Project: platform
// Created: 2015-02-17

// set window properties
SetWindowTitle( "platform" )
SetWindowSize( 1024, 768, 0 )

// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )

//force sync rate to 60 for best cross platform support.
SetSyncRate(60,0)

// define a type for the platforms
type platformstype
sprite as integer
x as integer
y as integer
endtype

// create a platform array allowing for 50 platforms
dim platform[50] as platformstype

// define a type for the player and assign values for position, jumping and a falling flag.
type playertype
sprite as integer
x as integer
y as integer
jumping as integer
jumptime as integer
falling as integer
contact as integer
endtype

// create a player variable based on the type
global player as playertype

// load in some images and create sprites.
// The media used for this demo can be located in the Smackit demo game provided with AppGameKit.
// Background can be found in the main menu folder
// looking1 can be found in the mole folder.
//
// blue.png can be found in the AGK projects/version 2/sprites/PercentageSystem/media folder.
//
// apple.png can be found in the SnakeSnacker folder in the demo games folder
//
// As with previous tutorials , copy and paste these images into the media folder for this demo.

LoadImage (1,"background.png")
CreateSprite(1,1)
// As the background image is too small for the demo size, enlarge the sprite to fit.
SetSpriteSize(1,1024,768)
// This sprite won't be doing anything other than look pretty, so make non active.
SetSpriteActive(1,0)

//load default platform
LoadImage(2,"blue.png")
CreateSprite(2,2)
// Set a consistant size for the sprite, this makes it easier to detect collisions by limiting overlaps.
SetSpriteSize(2,64,64)
// We will be cloning this sprite so we won't need it to be active or visible.
SetSpriteActive(2,0)
SetSpriteVisible(2,0)

//load mole as player
LoadImage(3,"looking1.png")
//make player sprite
CreateSprite(3,3)
// rescale sprite
SetSpriteSize(3,56,64)
//Set Sprite to box collision
SetSpriteShape(3,2)
//bring to the front.
SetSpriteDepth(3,8)

//make apple sprite, we'll only be using one collectable at a time in this demo.

Loadimage(4,"apple.png")
CreateSprite(4,4)
SetSpriteSize(4,32,32)
SetSpriteShape(4,2)
//bring right to the front
SetSpriteDepth(4,8)
//hide it because we don't want it seen yet
SetSpriteVisible(4,0)

//setup apple timer, we won't use variables for the postion as we will only have one at a time.
global appletimer as integer:appletimer=0
// We are also going to show the time remaining to collect the apple above the apple, so we'll be using a text object.

//create the object numbered 1,with a 1 as placeholder text
CreateText(1,"1")
//set the text size
SetTextSize(1,24)
// hide it.
SetTextVisible(1,0)
//colour text to make it easier to see. RGB(0,0,0)=true black
SetTextColor(1,0,0,0,255)

//set variables for inital position of player and sprite number. We don't need to set falling and jumping as by default these will be 0
player.x=round(512/64)*64
player.y=round(600/64)*64
player.sprite=3

buildplatforms()



//main loop
do

//display the player
displayplayer()
//check for movement and jumping
controlplayer()

// if timer runs out move apple
if appletimer-GetSeconds()<0
createapple()
endif

//diplay time left
displaytimer()

//check to see if apple collected
collectapple()

//update display

sync()

loop

// We are using a function too display the player as it's often useful for future project development.
Function displayplayer()

SetSpritePosition(player.sprite,player.x,player.y)


EndFunction

Function controlplayer()

// read the keyboard to check for player movement, you can find all of the scancodes for the keys at the link below
// the function also controls forced movement
/http://www.appgamekit.com/documentation/guides/scancodes.htm


// left and right arrow keys for movement and space bar are used as a default.

If GetRawKeyState(32)=1 and player.jumping=0 and player.contact<>0 //if spacebar pressed and player NOT already jumping AND standing on a platform, start jump.
player.jumping=1 //jump straight up)
player.jumptime=1// start a count to see how long the player has been jumping.
endif

//if jumping, check to see if a direction has been added

if player.jumping=1

if GetRawKeyState(37)
player.jumping=2 //jump left
endif

if GetRawKeyState(39)
player.jumping=3 // jump right
endif
// lock out direction changes when jumping.
if player.jumping=1 then player.jumping=4
endif

//move left (decrease screen x position)
if GetRawKeyState(37) and player.jumping=0 and player.falling=0
dec player.x,2
endif

//move right (increase screen x position)
if GetRawKeyState(39) and player.jumping=0 and player.falling=0
inc player.x,2
endif



//if player is falling and they should be on the way down, then move player downwards.

//check to see it the player has hit a platform or is standing on one
standingonplatform=checkcollision()
// if they are stop all falling and jumping
if standingonplatform<>0 and player.jumptime>=64
player.falling=0
player.jumping=0
player.jumptime=0
endif

// if the player is falling, move them down the screen.
if player.falling<>0
inc player.y,2
endif

// if player jumping then move them up

if player.jumping<>0
inc player.jumptime,1
if player.jumptime<64
dec player.y,4
endif

// are they jumping left, if so move left

if player.jumping=2
dec player.x,2
endif

//are they junping right, if so move left

if player.jumping=3
inc player.x,2
endif

endif

//if the player has been jumping for long enough enter free fall.

if player.jumptime>=128
player.jumping=0
player.jumptime=0
endif

// safety code for demo, if player falls off bottom of screen reset positon. - could be used as a player life loss.
if player.y>800
player.x=round(512/64)*64
player.y=round(600/64)*64
endif

EndFunction


//Jump here to see if apple collected.

Function collectapple()

//check collision if hit, collect a new apple, you could create a score here.
if GetSpriteCollision(player.sprite,4)
createapple()
endif

EndFunction



Function checkcollision()

// reset collisons, assume player falling
collision=0
player.falling=1
player.contact=0

// go through platforms and check for collison

for checkplatform=1 to 50
// only return a true collision if the player sprite is standing on top of the platform (check Y position).
if GetSpriteCollision(player.sprite,platform[checkplatform].sprite) and Abs(platform[checkplatform].y-(player.y+round(GetSpriteHeight(player.sprite))))<3
// if true set collision to the platform number.
collision=checkplatform
// if collision found end loop for performance, closing loop by setting checkplatform to a value of 30, which is where the loop ends.
if collision<>0
checkplatform=51
player.falling=0
player.contact=collision
endif
endif

next checkplatform

remstart
// remmed out, but provides debug information.

print("PY="+str(platform[collision].y))
print("Playy="+str(player.y+round(GetSpriteHeight(player.sprite))))
print("Col="+str(collision))
print("falling="+str(player.falling))
print("jumping="+str(player.jumping))
print("jumptime="+str(player.jumptime))
remend


EndFunction collision

Adding simple collectables - the source code - part 2
// cut and paste this code into your project below the code above.

Function createapple()

//choice a random platform to display the apple above, excluding the first one.
choiceplatform=random(2,50)
// position the apple above the platform
SetSpritePosition(4,platform[choiceplatform].x,platform[choiceplatform].y-32)
//make it visible
SetSpriteVisible(4,1)
// set the timer for between 8 and 16 seconds
appletimer=GetSeconds()+(8+random(0,8))
SetTextVisible(1,1)
SetTextPosition(1,platform[choiceplatform].x,platform[choiceplatform].y-64)

endfunction

Function displaytimer()
//convert numeric timer to a string
timeremaining=appletimer-GetSeconds()
a$=str(timeremaining)
SetTextString(1,a$)

EndFunction

Function buildplatforms()

//Create random platforms, most user will want to build an editor for this.

for makeplatforms=1 to 50
// chose a random position. In this demo we're forcing the sprite to a 64x64 position. This is really a matter of preference, but again, aids collision be avoiding overlap.
randomx=round(random(1,950)/64)*64
randomy=round(random(100,700)/64)*64
//set to sprite to be created (remember we'll be cloning them)
platform[makeplatforms].sprite=9+makeplatforms
// If this is the first platform, place it below the player so they have something soft to fall on.
if makeplatforms=1
platform[makeplatforms].x=player.x
platform[makeplatforms].y=player.y+GetSpriteHeight(player.sprite)
//otherwise place it randomly.
else
platform[makeplatforms].x=randomx
platform[makeplatforms].y=randomy
endif

//clonse the sprite and set position and status.
CloneSprite(platform[makeplatforms].sprite,2)
SetSpriteActive(platform[makeplatforms].sprite,1)
SetSpriteVisible(platform[makeplatforms].sprite,1)
SetSpritePosition(platform[makeplatforms].sprite,platform[makeplatforms].x,platform[makeplatforms].y)
SetSpriteShape(platform[makeplatforms].sprite,2)
//end loop
next makeplatforms

EndFunction
Adding effects to platforms (conveyor belts) - Description
The next part of this guide demonstrates how to set up a simple effects system to your platforms.

For this we've added a new element to the TYPE platformtypes called effect, For this demo I've added some conveyor belt type platforms, one left and one right.

The system is designed to be expanded and you should easily be able to add to it to have a whole host of different effects.

For this version, the blocks are simply coloured to reflect the effect, green for right red for left.

As before, I've posted the code below, and it's fully documented, and as always, if you've any questions please ask.

I also would like to recommend that as an aid to learning, users use the free tool ExamDiff to compare various versions of the source code, this will highlight differences and is a great help in not only debugging, but also in understanding the effect that the changes in code have on the game.




Adding effects to platforms (conveyor belts) - the source - part 1
// Project: platform
// Created: 2015-02-17

// set window properties
SetWindowTitle( "platform" )
SetWindowSize( 1024, 768, 0 )

// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )

//force sync rate to 60 for best cross platform support.
SetSyncRate(60,0)

// define a type for the platforms
// added new staticic, effect, so that we can have platforms with different effect.
type platformstype
sprite as integer
x as integer
y as integer
effect as integer
endtype

// create a platform array allowing for 50 platforms
dim platform[50] as platformstype

//We now introduce the idea that several platforms can be in contact with the player at the same time. We'll allow 3 for the moment, but can easily add more.

// for this example, we'll add the idea of conveyor belts. These will be indentified using the effect value of the platform array.
//
// 1 = Normal Platform
// 2 = Conveyor belt left
// 3 = Conveyor belt right

Global numberofeffects=3

dim platformtouched[numberofeffects]

// define a type for the player and assign values for position, jumping and a falling flag.
type playertype
sprite as integer
x as integer
y as integer
jumping as integer
jumptime as integer
falling as integer
contact as integer
endtype

// create a player variable based on the type
global player as playertype

// load in some images and create sprites.
// The media used for this demo can be located in the Smackit demo game provided with AppGameKit.
// Background can be found in the main menu folder
// looking1 can be found in the mole folder.
//
// blue.png can be found in the AGK projects/version 2/sprites/PercentageSystem/media folder.
//
// apple.png can be found in the SnakeSnacker folder in the demo games folder
//
// As with previous tutorials , copy and paste these images into the media folder for this demo.

LoadImage (1,"background.png")
CreateSprite(1,1)
// As the background image is too small for the demo size, enlarge the sprite to fit.
SetSpriteSize(1,1024,768)
// This sprite won't be doing anything other than look pretty, so make non active.
SetSpriteActive(1,0)

//load default platform
LoadImage(2,"blue.png")
CreateSprite(2,2)
// Set a consistant size for the sprite, this makes it easier to detect collisions by limiting overlaps.
SetSpriteSize(2,64,64)
// We will be cloning this sprite so we won't need it to be active or visible.
SetSpriteActive(2,0)
SetSpriteVisible(2,0)

//load mole as player
LoadImage(3,"looking1.png")
//make player sprite
CreateSprite(3,3)
// rescale sprite
SetSpriteSize(3,56,64)
//Set Sprite to box collision
SetSpriteShape(3,2)
//bring to the front.
SetSpriteDepth(3,8)

//make apple sprite, we'll only be using one collectable at a time in this demo.

Loadimage(4,"apple.png")
CreateSprite(4,4)
SetSpriteSize(4,32,32)
SetSpriteShape(4,2)
//bring right to the front
SetSpriteDepth(4,8)
//hide it because we don't want it seen yet
SetSpriteVisible(4,0)

//setup apple timer, we won't use variables for the postion as we will only have one at a time.
global appletimer as integer:appletimer=0
// We are also going to show the time remaining to collect the apple above the apple, so we'll be using a text object.

//create the object numbered 1,with a 1 as placeholder text
CreateText(1,"1")
//set the text size
SetTextSize(1,24)
// hide it.
SetTextVisible(1,0)
//colour text to make it easier to see. RGB(0,0,0)=true black
SetTextColor(1,0,0,0,255)

//set variables for inital position of player and sprite number. We don't need to set falling and jumping as by default these will be 0
player.x=round(512/64)*64
player.y=round(600/64)*64
player.sprite=3

// this is a random placement generator, I'd encourage users to have a go at building thier own level editor.
buildplatforms()


//main loop
do


//check for movement and jumping
controlplayer()

// if timer runs out move apple
if appletimer-GetSeconds()<0
createapple()
endif

//diplay time left
displaytimer()

//check to see if apple collected
collectapple()
//display the player
displayplayer()

remstart
// debug information.
for f=1 to 3
print(platformtouched[f])
next f
remend

//update display

sync()

loop

// We are using a function too display the player as it's often useful for future project development.
Function displayplayer()

SetSpritePosition(player.sprite,player.x,player.y)


EndFunction

Function controlplayer()

// read the keyboard to check for player movement, you can find all of the scancodes for the keys at the link below
// the function also controls forced movement
/http://www.appgamekit.com/documentation/guides/scancodes.htm


// left and right arrow keys for movement and space bar are used as a default.

If GetRawKeyState(32)=1 and player.jumping=0 and player.contact<>0 //if spacebar pressed and player NOT already jumping AND standing on a platform, start jump.
player.jumping=1 //jump straight up)
player.jumptime=1// start a count to see how long the player has been jumping.
endif

//if jumping, check to see if a direction has been added

if player.jumping=1

if GetRawKeyState(37)
player.jumping=2 //jump left
endif

if GetRawKeyState(39)
player.jumping=3 // jump right
endif
// lock out direction changes when jumping.
if player.jumping=1 then player.jumping=4
endif

//move left (decrease screen x position)
if GetRawKeyState(37) and player.jumping=0 and player.falling=0
dec player.x,2
endif

//move right (increase screen x position)
if GetRawKeyState(39) and player.jumping=0 and player.falling=0
inc player.x,2
endif


//if player is falling and they should be on the way down, then move player downwards.

//check to see it the player has hit a platform or is standing on one
checkcollision()
// if they are stop all falling and jumping
if player.contact<>0 and player.jumptime>=64
player.falling=0
player.jumping=0
player.jumptime=0
endif

// if the player is falling, move them down the screen.
if player.falling<>0
inc player.y,2
endif

// if player jumping then move them up

if player.jumping<>0
inc player.jumptime,1
if player.jumptime<64
dec player.y,4
endif

// are they jumping left, if so move left

if player.jumping=2
dec player.x,2
endif

//are they junping right, if so move left

if player.jumping=3
inc player.x,2
endif

endif

//if the player has been jumping for long enough enter free fall.

if player.jumptime>=128
player.jumping=0
player.jumptime=0
endif

// safety code for demo, if player falls off bottom of screen reset positon. - could be used as a player life loss.
if player.y>800
player.x=round(512/64)*64
player.y=round(600/64)*64
endif

//check for special platform effects

checkforspecialplatforms()

EndFunction
Adding effects to platforms (conveyor belts) - the source - part 2

Function checkforspecialplatforms()

//scan every platform to see if it's set.
for testplatforms=1 to numberofeffects
// set the effect to testvalue for checking
if platformtouched[testplatforms] then testvalue=testplatforms
// start a select/case loop
Select testvalue
//1 = normal platform, do nothing
Case 1
Endcase
//2 = Conveyor left, move the player
Case 2
player.x=player.x-1
EndCase
// 3= Conveyor right, move the player
Case 3
player.x=player.x+1
EndCase
//end select loop
EndSelect

next testplatforms

EndFunction


//Jump here to see if apple collected.

Function collectapple()

//check collision if hit, collect a new apple, you could create a score here.
if GetSpriteCollision(player.sprite,4)
createapple()
endif

EndFunction



Function checkcollision()

// reset collisons, assume player falling
collision=0
player.falling=1
player.contact=0

//clear platform effects to ensure a true reading.

for clear=1 to numberofeffects
platformtouched[clear]=0
next clear

// go through platforms and check for collison

for checkplatform=1 to 50
// only return a true collision if the player sprite is standing on top of the platform (check Y position).
if GetSpriteCollision(player.sprite,platform[checkplatform].sprite) and Abs(platform[checkplatform].y-(player.y+round(GetSpriteHeight(player.sprite))))<3
// if true set collision to the platform number.
collision=checkplatform
// if collision found set the approprate value in the platformtouched array.
if collision<>0
player.falling=0
player.contact=1 // changed to indicate that the player in touching something
platformtouched[platform[checkplatform].effect]=collision // set approprate effect flag with number of platform touched (for future expansion).
endif
endif

next checkplatform

remstart
// remmed out, but provides debug information.

print("PY="+str(platform[collision].y))
print("Playy="+str(player.y+round(GetSpriteHeight(player.sprite))))
print("Col="+str(collision))
print("falling="+str(player.falling))
print("jumping="+str(player.jumping))
print("jumptime="+str(player.jumptime))
remend


EndFunction

Function createapple()

//choice a random platform to display the apple above, excluding the first one.
choiceplatform=random(2,50)
// position the apple above the platform
SetSpritePosition(4,platform[choiceplatform].x+16,platform[choiceplatform].y-32)
//make it visible
SetSpriteVisible(4,1)
// set the timer for between 8 and 16 seconds
appletimer=GetSeconds()+(8+random(0,8))
SetTextVisible(1,1)
SetTextPosition(1,platform[choiceplatform].x+16,platform[choiceplatform].y-64)

endfunction

Function displaytimer()
//convert numeric timer to a string
timeremaining=appletimer-GetSeconds()
a$=str(timeremaining)
SetTextString(1,a$)

EndFunction

Function buildplatforms()

//Create random platforms, most user will want to build an editor for this.

for makeplatforms=1 to 50
//set to sprite to be created (remember we'll be cloning them)
platform[makeplatforms].sprite=9+makeplatforms
// chose a random position. In this demo we're forcing the sprite to a 64x64 position. This is really a matter of preference, but again, aids collision be avoiding overlap.

randomx=round(random(1,950)/64)*64
randomy=round(random(100,700)/64)*64


// If this is the first platform, place it below the player so they have something soft to fall on.
if makeplatforms=1
platform[makeplatforms].x=player.x
platform[makeplatforms].y=player.y+GetSpriteHeight(player.sprite)
//otherwise place it randomly.
else
platform[makeplatforms].x=randomx
platform[makeplatforms].y=randomy
endif

//clonse the sprite and set position and status.
CloneSprite(platform[makeplatforms].sprite,2)
SetSpriteActive(platform[makeplatforms].sprite,1)
SetSpriteVisible(platform[makeplatforms].sprite,1)
SetSpritePosition(platform[makeplatforms].sprite,platform[makeplatforms].x,platform[makeplatforms].y)
SetSpriteShape(platform[makeplatforms].sprite,2)
//add new platform effects - for this demo ensure that the first platform is normal, otherwise add a platform effect between 1 and 3
if makeplatforms>1 then platform[makeplatforms].effect=Random(1,3)
//hack1 - make more normal that others, 50% change of reverting back.
if random(1,100)>50
platform[makeplatforms].effect=1
endif
// hack2 to show different in platforms using different colours, in a full game you would idealy use different images.
if platform[makeplatforms].effect=2 then SetSpriteColor(platform[makeplatforms].sprite,127,0,0,255) // conveyor left will be red
if platform[makeplatforms].effect=3 then SetSpriteColor(platform[makeplatforms].sprite,0,255,0,255) // conveyor right will be green
//end loop
next makeplatforms

EndFunction
Adding moving creatures - introduction
Hi,

For the next part of the tutorial, we'll be looking at adding moving creatures and allowing them to kill the player. The creature can actually be thought of as a type of platform that can move. In the case of this demo, up, down, left and right.

We could expand on this to allow moving platforms,and I'll consider adding a guide to that at a later date.

For now, you'll need to add the balloon sprite (item0) to your media folder, we've used it before in previous guides, and it will be representing our creature.

As a reminder you can copy this image from your SteamApps folder : ...\common\App Game Kit 2\Projects\Sprites\SpriteAnim1\media.



This guide also tweaks the arrays used to store the platform information, giving all users the basis of an editor. I've not included any editor code, but the core storage is now there. This also allows your levels to be reset by retaining all of the original data.

As before, I'm including all of the latest code and it is well documented, but please ask if you need any clarification.



Adding moving creatures - the source code - part 1.
// Project: platform
// Created: 2015-02-17

// set window properties
SetWindowTitle( "platform" )
SetWindowSize( 1024, 768, 0 )

// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )

//force sync rate to 60 for best cross platform support.
SetSyncRate(60,0)

// define a type for the platforms
// added new staticic, effect, so that we can have platforms with different effect and includes moving entities such as creatures.
type platformstype
sprite as integer
x as integer
y as integer
effect as integer
iscreature as integer // = 0 no, 1 = yes.
direction as integer // 0 = static, 1 = up, 2 = right, 3 = down, 4 = left.
endtype

// create a platform array// We are changing this approach to store all platforms and creatures in a
// multiple dimensional array, purely for placement. This can also be used later to create an easy to
// use editor. our screen is 1024 pixels wide and 768 pixels high. For ease of calculating the jump we'll restrict
// this to 64x64 blocks. Which is 12 blocks high and 16 blocks across. Making a maximum number of possible platforms 192

dim platformeditor[12,16] as platformstype

//create an array to hold the final information for compatibilty with old system.

dim platform[192] as platformstype

//We now introduce the idea that several platforms can be in contact with the player at the same time. We'll allow 3 for the moment, but can easily add more.

// for this example, we'll add the idea of conveyor belts. These will be indentified using the effect value of the platform array.
//
// 1 = Normal Platform
// 2 = Conveyor belt left
// 3 = Conveyor belt right
// 4 = killer

Global numberofeffects=4

dim platformtouched[numberofeffects]

// define a type for the player and assign values for position, jumping and a falling flag.
type playertype
sprite as integer
x as integer
y as integer
jumping as integer
jumptime as integer
falling as integer
contact as integer
endtype

// create a player variable based on the type
global player as playertype

// load in some images and create sprites.
// The media used for this demo can be located in the Smackit demo game provided with AppGameKit.
// Background can be found in the main menu folder
// looking1 can be found in the mole folder.
//
// blue.png can be found in the AGK projects/version 2/sprites/PercentageSystem/media folder.
//
// apple.png can be found in the SnakeSnacker folder in the demo games folder
//
// As with previous tutorials , copy and paste these images into the media folder for this demo.

LoadImage (1,"background.png")
CreateSprite(1,1)
// As the background image is too small for the demo size, enlarge the sprite to fit.
SetSpriteSize(1,1024,768)
// This sprite won't be doing anything other than look pretty, so make non active.
SetSpriteActive(1,0)

//load default platform
LoadImage(2,"blue.png")
CreateSprite(2,2)
// Set a consistant size for the sprite, this makes it easier to detect collisions by limiting overlaps.
SetSpriteSize(2,64,64)
// We will be cloning this sprite so we won't need it to be active or visible.
SetSpriteActive(2,0)
SetSpriteVisible(2,0)

//load mole as player
LoadImage(3,"looking1.png")
//make player sprite
CreateSprite(3,3)
// rescale sprite
SetSpriteSize(3,56,64)
//Set Sprite to box collision
SetSpriteShape(3,2)
//bring to the front.
SetSpriteDepth(3,8)

//make apple sprite, we'll only be using one collectable at a time in this demo.

Loadimage(4,"apple.png")
CreateSprite(4,4)
SetSpriteSize(4,32,32)
SetSpriteShape(4,2)
//bring right to the front
SetSpriteDepth(4,8)
//hide it because we don't want it seen yet
SetSpriteVisible(4,0)

Loadimage(5,"item0.png")
CreateSprite(5,5)
SetSpriteSize(5,64,64) // scale to fit in 64x64
SetSpriteShape(5,2)
//hide it because we don't want it seen yet
SetSpriteVisible(5,0)

//setup apple timer, we won't use variables for the postion as we will only have one at a time.
global appletimer as integer:appletimer=0
// We are also going to show the time remaining to collect the apple above the apple, so we'll be using a text object.

//create the object numbered 1,with a 1 as placeholder text
CreateText(1,"1")
//set the text size
SetTextSize(1,24)
// hide it.
SetTextVisible(1,0)
//colour text to make it easier to see. RGB(0,0,0)=true black
SetTextColor(1,0,0,0,255)

//set variables for inital position of player and sprite number. We don't need to set falling and jumping as by default these will be 0
player.x=round(512/64)*64
player.y=round(600/64)*64
player.sprite=3

// this is a random placement generator, I'd encourage users to have a go at building thier own level editor.
buildplatforms()
resetplatforms()

Adding moving creatures - the source code - part 2
//main loop
do

//check for movement and jumping
controlplayer()

// if timer runs out move apple
if appletimer-GetSeconds()<0
createapple()
endif

//diplay time left
displaytimer()

//check to see if apple collected
collectapple()
//display the player
displayplayer()

remstart
// debug information.
for f=1 to 3
print(platformtouched[f])
next f
remend

//update display

sync()

loop

// We are using a function to display the player as it's often useful for future project development.
Function displayplayer()

SetSpritePosition(player.sprite,player.x,player.y)


EndFunction

Function controlplayer()

// read the keyboard to check for player movement, you can find all of the scancodes for the keys at the link below
// the function also controls forced movement
/http://www.appgamekit.com/documentation/guides/scancodes.htm


// left and right arrow keys for movement and space bar are used as a default.

If GetRawKeyState(32)=1 and player.jumping=0 and player.contact<>0 //if spacebar pressed and player NOT already jumping AND standing on a platform, start jump.
player.jumping=1 //jump straight up)
player.jumptime=1// start a count to see how long the player has been jumping.
endif

//if jumping, check to see if a direction has been added

if player.jumping=1

if GetRawKeyState(37)
player.jumping=2 //jump left
endif

if GetRawKeyState(39)
player.jumping=3 // jump right
endif
// lock out direction changes when jumping.
if player.jumping=1 then player.jumping=4
endif

//move left (decrease screen x position)
if GetRawKeyState(37) and player.jumping=0 and player.falling=0
dec player.x,2
endif

//move right (increase screen x position)
if GetRawKeyState(39) and player.jumping=0 and player.falling=0
inc player.x,2
endif


//if player is falling and they should be on the way down, then move player downwards.

//check to see it the player has hit a platform or is standing on one
checkcollision()
// if they are stop all falling and jumping
if player.contact<>0 and player.jumptime>=64
player.falling=0
player.jumping=0
player.jumptime=0
endif

// if the player is falling, move them down the screen.
if player.falling<>0
inc player.y,2
endif

// if player jumping then move them up

if player.jumping<>0
inc player.jumptime,1
if player.jumptime<64
dec player.y,4
endif

// are they jumping left, if so move left

if player.jumping=2
dec player.x,2
endif

//are they junping right, if so move left

if player.jumping=3
inc player.x,2
endif

endif

//if the player has been jumping for long enough enter free fall.

if player.jumptime>=128
player.jumping=0
player.jumptime=0
endif

// safety code for demo, if player falls off bottom of screen reset positon. - could be used as a player life loss.
if player.y>800
player.x=round(512/64)*64
player.y=round(600/64)*64
endif

//check for special platform effects

checkforspecialplatforms()

EndFunction
Adding moving creatures - the source code - part 3.
Function checkforspecialplatforms()

//scan every platform to see if it's set.
for testplatforms=1 to numberofeffects
// set the effect to testvalue for checking
if platformtouched[testplatforms]
testvalue=testplatforms
// start a select/case loop
Select testvalue
//1 = normal platform, do nothing
Case 1
Endcase
//2 = Conveyor left, move the player
Case 2
player.x=player.x-1
EndCase
// 3= Conveyor right, move the player
Case 3
player.x=player.x+1
EndCase
// 4 = Killer
Case 4
// for now simple reset player position.
player.x=round(512/64)*64
player.y=round(600/64)*64
EndCase
//end select loop
EndSelect
endif

next testplatforms

EndFunction


//Jump here to see if apple collected.

Function collectapple()

//check collision if hit, collect a new apple, you could create a score here.
if GetSpriteCollision(player.sprite,4)
createapple()
endif

EndFunction



Function checkcollision()

// reset collisons, assume player falling
collision=0
player.falling=1
player.contact=0

//clear platform effects to ensure a true reading.

for clear=1 to numberofeffects
platformtouched[clear]=0
next clear

// go through platforms and check for collison

for checkplatform=1 to 192
// only check if object has an effect AND isn't a killer - effect 4. (killers need full collision)
if platform[checkplatform].effect<>0 and platform[checkplatform].effect<>4
// only return a true collision if the player sprite is standing on top of the platform (check Y position).
if GetSpriteCollision(player.sprite,platform[checkplatform].sprite) and Abs(platform[checkplatform].y-(player.y+round(GetSpriteHeight(player.sprite))))<3
// if true set collision to the platform number.
collision=checkplatform
// if collision found set the approprate value in the platformtouched array.
if collision<>0
player.falling=0
player.contact=1 // changed to indicate that the player in touching something
platformtouched[platform[checkplatform].effect]=collision // set approprate effect flag with number of platform touched (for future expansion).
endif
endif
//end if no effect
endif

if platform[checkplatform].direction<>0 // is it a moving object?
//jump to function to move this object and check to see if it's hits an object to change direction.
movingplatform(checkplatform)
endif

if platform[checkplatform].effect=4 // is the platform a killer
if GetSpriteCollision(player.sprite,platform[checkplatform].sprite) // check for full collision. (excludes check for only when on top.).
// reset player start position for now. (You would want a death scene here).
player.x=round(512/64)*64
player.y=round(600/64)*64
// reset falling and jumping.
player.falling=0
player.jumping=0
endif
endif

next checkplatform

// remmed out, but provides debug information.
remstart
print("PY="+str(platform[collision].y))
print("Playy="+str(player.y+round(GetSpriteHeight(player.sprite))))
print("Col="+str(collision))
print("falling="+str(player.falling))
print("jumping="+str(player.jumping))
print("jumptime="+str(player.jumptime))
remend

EndFunction

Function createapple()

//choice a random platform to display the apple above, excluding the first one.
do
choiceplatform=random(2,192)
// don't allow placement on platforms with no effect or ones that are moving.
if platform[choiceplatform].effect<>0 and platform[choiceplatform].direction=0 then exit
loop
// position the apple above the platform
SetSpritePosition(4,platform[choiceplatform].x+16,platform[choiceplatform].y-32)
//make it visible
SetSpriteVisible(4,1)
// set the timer for between 8 and 16 seconds
appletimer=GetSeconds()+(8+random(0,8))
SetTextVisible(1,1)
SetTextPosition(1,platform[choiceplatform].x+16,platform[choiceplatform].y-64)

endfunction

Function displaytimer()
//convert numeric timer to a string
timeremaining=appletimer-GetSeconds()
a$=str(timeremaining)
SetTextString(1,a$)


EndFunction

Function movingplatform(platnum)

// Calculate new position
// define original direction of moving sprite for future reference
origin=platform[platnum].direction

Select origin
Case 1 // up
platform[platnum].y=platform[platnum].y-2
EndCase

Case 2 // right
platform[platnum].x=platform[platnum].x+2
EndCase
Case 3 // down
platform[platnum].y=platform[platnum].y+2
EndCase

Case 4 // left
platform[platnum].x=platform[platnum].x-2
EndCase

EndSelect

// reprosition sprite to new location.

SetSpritePosition(platform[platnum].sprite,platform[platnum].x,platform[platnum].y)

//check for hitting other sprite and reverse direction
For bouncing=1 to 192
// only if it has an effect and not the same sprite
if platform[bouncing].effect<>0 and bouncing<>platnum
// have the sprites collided

if GetSpriteCollision(platform[platnum].sprite,platform[bouncing].sprite)
// if so change direction

if origin=1 // up change to down
platform[platnum].direction=3
endif

if origin=2 // right change to left
platform[platnum].direction=4
endif

if origin=3 // down change to up
platform[platnum].direction=1
endif

if origin=4 // left change to right
platform[platnum].direction=2
endif
// Force end of loop as collision confirmed.
bouncing=192
endif
endif
next bouncing

EndFunction
Adding moving creatures - the source code - part 4.
// set or reset platforms to original position.

function resetplatforms()

// temp variable to assign from editor to working game array (the one we can change).
nextone=1
// search multi dimensional editor array
for down=1 to 12
for across=1 to 16
platform[nextone].x=platformeditor[down,across].x
platform[nextone].y=platformeditor[down,across].y
platform[nextone].sprite=platformeditor[down,across].sprite
platform[nextone].effect=platformeditor[down,across].effect
platform[nextone].iscreature=platformeditor[down,across].iscreature
platform[nextone].direction=platformeditor[down,across].direction
//increase number of times loop has been run so we can assign values to the correct array
inc nextone,1
next across// finish across loop
next down// finish down loop
endfunction


//// Warning - the build platform is very hacked in. The system is designed to be used with an editor, this is for demo purposes only

Function buildplatforms()

//Create random platforms, most user will want to build an editor for this. - this should give some clues.
// create a temporaty variable to show where to count passes
nextone=1

for makeplatformsdown=1 to 11 // platforms down only to 11 as platforms start one down for demo purposes
for makeplatformsacross=1 to 16 // platforms across.

//set to sprite to be created (remember we'll be cloning them)
platformeditor[makeplatformsdown,makeplatformsacross].sprite=9+nextone // 9+ number of passes to ensure easch sprite has a new number.

//place platform

platformeditor[makeplatformsdown,makeplatformsacross].x=(makeplatformsacross-1)*64// -1 to allow placement at very edge of screen
platformeditor[makeplatformsdown,makeplatformsacross].y=makeplatformsdown*64


//add new platform effects - between 1 and 3
platformeditor[makeplatformsdown,makeplatformsacross].effect=Random(1,3)
usesprite=2 // assume platform (only one image being used).
colmode=2// hack platform collision mode.
//hack1 - 10% change of platform being a creature

if random(1,100)>90
platformeditor[makeplatformsdown,makeplatformsacross].iscreature=1 // yes it's a creature
platformeditor[makeplatformsdown,makeplatformsacross].effect=4 // set effect to 4, contact will kill
platformeditor[makeplatformsdown,makeplatformsacross].direction=random(1,4) // assign random movement
usesprite=5
colmode=3// force pixel/poly collison
endif
//clone the sprite and set position and status.
CloneSprite(platformeditor[makeplatformsdown,makeplatformsacross].sprite,usesprite)
SetSpriteActive(platformeditor[makeplatformsdown,makeplatformsacross].sprite,1)
SetSpriteVisible(platformeditor[makeplatformsdown,makeplatformsacross].sprite,1)
SetSpritePosition(platformeditor[makeplatformsdown,makeplatformsacross].sprite,platformeditor[makeplatformsdown,makeplatformsacross].x,platformeditor[makeplatformsdown,makeplatformsacross].y)
SetSpriteShape(platformeditor[makeplatformsdown,makeplatformsacross].sprite,colmode)


if random(1,100)>30
//hack2 - make more normal that others, 70% change of no platform.
platformeditor[makeplatformsdown,makeplatformsacross].effect=0
platformeditor[makeplatformsdown,makeplatformsacross].direction=0
// remove from checking and visability for performance and clarity
SetSpriteActive(platformeditor[makeplatformsdown,makeplatformsacross].sprite,0)
SetSpriteVisible(platformeditor[makeplatformsdown,makeplatformsacross].sprite,0)
SetSpriteShape(platformeditor[makeplatformsdown,makeplatformsacross].sprite,0)
endif
// hack3 to show different in platforms using different colours, in a full game you would idealy use different images.
if platformeditor[makeplatformsdown,makeplatformsacross].effect=2 then SetSpriteColor(platformeditor[makeplatformsdown,makeplatformsacross].sprite,127,0,0,255) // conveyor left will be red
if platformeditor[makeplatformsdown,makeplatformsacross].effect=3 then SetSpriteColor(platformeditor[makeplatformsdown,makeplatformsacross].sprite,0,255,0,255) // conveyor right will be green

//increase number of times loop has been run
inc nextone,1
next makeplatformsacross // finish across loop
//increase number of times loop has been run
inc nextone,1
next makeplatformsdown // finsish down loop

EndFunction

17 Comments
🍂🌿🍁🌱🍂⛰️🌋 Oct 4, 2020 @ 9:24pm 
this look easy
Arstein Oct 4, 2020 @ 2:50am 
Basic? OMG. This is so hard for me. Yes, i will be sitting on my ass all my life. But i want to believe, what this is a joke. Sorry for my english
1MantisPhoenix Jan 15, 2018 @ 4:18pm 
I played this game so long ago that i want to remake - now - as I have never been able to see it or remember the name, sadly;
BUT The concept is- you need to get as high as possible - you start at the bottom, how do you make the level go vertically up and then you infintely have it going till you miss the platform/?
GemGirl Feb 9, 2017 @ 6:56am 
Alright, I'll try to limit the speed the player falls so the collision won't fail.
thescenecommander  [author] Feb 9, 2017 @ 6:23am 
A multiplier would work well. Be aware, that in the demo above, the collision is pixel based, and if the player is moving too quickly the collision will fail.
GemGirl Feb 9, 2017 @ 4:41am 
How would I add increasing falling speed based on the amount of time passed(with a max falling speed limit)? Should I use the timer and put the multiplier based on milliseconds passed? (ex. while jumptime is less than 64, and while the timer goes from 0 to 1 seconds, multiply inc player.y to current time+1)? So, if 0.5 seconds passed, the specific increase amount of player.y would be 1.5 times the specified inc player.y number.
GemGirl Feb 9, 2017 @ 3:11am 
@thescenecommander

Ah I see, that sounds like a better method!
thescenecommander  [author] Feb 9, 2017 @ 3:07am 
@slimessmileslime

Yes, that method also works well, for performance, actually only moving the sprites percieved position will speed things up a lot. By this I mean, store the sprite position in an array. Adjust the array values but only reposition the sprite if those values are on screen. In this case less is most deffinately more.
GemGirl Feb 9, 2017 @ 2:17am 
Maybe having the background and other sprites move while the player is walking in place(To make it look like the player is moving) may be another idea to make a sidescroller.
Dah Sweatah Shreddah Feb 8, 2017 @ 6:36am 
awesome! thanks for getting back ti me