Last night I sat down and coded this simple canon shooting game so I thought I'd share.
Destroy all three targets in this simple 2D canon shooting game, featuring a procedurally generated destructible landscape
No media is required, just copy and paste the below code into the editor (V2.14b Tier 1, might work in V1 with a bit of tinkering).
remstart
Simple Canon Shooting Game by 29 Games 27 Aug 2015
AGK V2.14b Tier 1
Destroy all three targets in this simple 2D canon shooting game, featuring procedurally generated destructible landscape
Controls:
Left and right arrow keys to set elavation of canon
Up and down arrow keys to set power
Enter to shoot
Hud (top left of screen):
Yellow squares show the number of shots the player has left
Green squares show the current power
remend
// initial set up
gosub _declare_variables
_f_screen_setup()
_f_create_media()
do
// initiate the game
_f_generate_level()
// play game loop
repeat
select game_state
case 0
_f_manage_game_state()
_f_canon_controls()
_f_manage_canon_ball()
_f_manage_targets()
_f_manage_hud()
endcase
case 1
_f_game_over()
endcase
endselect
sync()
until game_state = 2
loop
_declare_variables:
type _landscape_type
spr as integer
y as integer
endtype
dim landscape[32] as _landscape_type
type _canon_type
spr_barrel as integer
spr_body as integer
angle as integer
power as integer
state as integer
shots_remaining as integer
endtype
global canon as _canon_type
type _canon_ball_type
spr as integer
xp# as float
yp# as float
xv# as float
yv# as float
scale# as float
hit as integer
endtype
global ball as _canon_ball_type
type _target_type
spr as integer
location as integer
life as integer
xp# as float
yp# as float
yv# as float
endtype
dim target[3] as _target_type
// hud
dim shots_spr[12]
dim power_spr[10]
// other variables
global game_state as integer
global gravity# as float
return
function _f_screen_setup()
SetWindowSize(1024,768,0)
SetVirtualResolution(1024,768)
endfunction
function _f_create_media()
//landscape
for i = 1 to 32
landscape[i].spr = createSprite(0)
SetSpriteSize(landscape[i].spr,32,700)
SetSpritePosition(landscape[i].spr,(i-1)*32,68)
next i
// targets
for i = 1 to 3
target[i].spr = CreateSprite(0)
SetSpriteSize(target[i].spr,24,24)
SetSpriteOffset(target[i].spr,12,24)
SetSpriteColor(target[i].spr,100,255,255,255)
next i
// canon
canon.spr_barrel = CreateSprite(0)
SetSpriteSize(canon.spr_barrel,12,36)
SetSpriteOffset(canon.spr_barrel,6,36)
canon.spr_body = CreateSprite(0)
SetSpriteSize(canon.spr_body,24,24)
SetSpriteOffset(canon.spr_body,12,24)
// canon ball
ball.spr = CreateSprite(0)
SetSpriteSize(ball.spr,12,12)
SetSpriteColor(ball.spr,255,255,0,255)
// hud number of shots
for i = 1 to 12
shots_spr[i] = CreateSprite(0)
SetSpriteSize(shots_spr[i],10,10)
SetSpritePosition(shots_spr[i],5+i*12,5)
next i
// hud power
for i = 1 to 10
power_spr[i] = CreateSprite(0)
SetSpriteSize(power_spr[i],10,10)
SetSpritePosition(power_spr[i],5+i*12,20)
next i
// create game over text
CreateText(1,"")
SetTextSize(1,40)
SetTextAlignment(1,1)
SetTextPosition(1,512,360)
CreateText(2,"PRESS SPACE BAR TO REPLAY")
SetTextSize(2,30)
SetTextAlignment(2,1)
SetTextPosition(2,512,444)
endfunction
function _f_generate_level()
// create the landscape
// starting height
landscape[1].y = random(30,49)*10
// there are 32 sprites making up the landscape, split into eight groups of four
n = 0
for i = 1 to 8
// calculate y change increment
repeat
delta_y = (random(0,6)-3)*40
until delta_y <> 0
for j = 1 to 4
// landscape sprite id
inc n
// calculate new y for all sprite beyond the first two
if n > 2
landscape[n].y = landscape[n-1].y + delta_y
else
// the first two landscape sprites will be the same height
if n > 1
landscape[n].y = landscape[n-1].y
endif
endif
// restrict the y between limits and alter delta_y to bring landscape away from screen edge
if landscape[n].y <= 190
landscape[n].y = 190
delta_y = 20
endif
if landscape[n].y >= 700
landscape[n].y = 700
delta_y = -20
endif
// position landscape sprite
SetSpriteY(landscape[n].spr,landscape[n].y)
// colour the landscape sprite a shade of purple
col = random(0,5)*5+100
SetSpriteColor(landscape[n].spr,col,0,col,255)
next j
next i
// ++++++++++++++++++++++++
// set and position position the targets
n = 0
for i = 1 to 3
// set life and velocity
target[i].life = 1
target[i].yv# = 0.0
// position the target on the landscape and set it visible
n = n + (random(i,6+i))
target[i].location = 32-n
target[i].xp# = (target[i].location)*32-16
target[i].yp# = landscape[target[i].location].y
SetSpritePositionByOffset(target[i].spr,target[i].xp#,target[i].yp#)
SetSpriteVisible(target[i].spr,1)
next i
// ++++++++++++++++++++++++
// set value for gravity
gravity# = 0.05
// position the canon and set initial values
SetSpritePositionByOffset(canon.spr_barrel,16,landscape[1].y-12)
SetSpritePositionByOffset(canon.spr_body,16,landscape[1].y)
canon.angle = 45
canon.power = 5
canon.state = 0
canon.shots_remaining = 12
// hide game over text
SetTextVisible(1,0)
SetTextVisible(2,0)
// set game state to play the game
game_state = 0
endfunction
function _f_manage_game_state()
// check to see if all targets are destroyed
total_life = 0
for i = 1 to 3
total_life = total_life + target[i].life
next i
// check to see if the player has won or lost
if total_life = 0
// if all targets are destroyed then the player has won
if canon.state = 1
game_state = 1
SetTextString(1,"!!! YOU DESTROYED ALL THE TARGETS !!!")
SetTextVisible(1,1)
SetTextVisible(2,1)
endif
else
// check to see if the player has run out of shots and if they have they have failed
if canon.shots_remaining = 0 and canon.state = 1
game_state = 1
SetTextString(1,"FAILED")
SetTextVisible(1,1)
SetTextVisible(2,1)
endif
endif
endfunction
function _f_canon_controls()
// use left and right arrow keys to change angle of canon
delta_angle = GetRawKeyState(39) - GetRawKeyState(37)
canon.angle = canon.angle + delta_angle
// restrict canon's angle
if canon.angle < 4
canon.angle = 4
endif
if canon.angle > 89
canon.angle = 89
endif
// set angle of barrel sprite
SetSpriteAngle(canon.spr_barrel,canon.angle)
// use up and down arrows to change power
delta_power = GetRawKeyPressed(38) - GetRawKeyPressed(40)
canon.power = canon.power + delta_power
// restrict canon power to between 1 and 10
if canon.power < 1
canon.power = 1
endif
if canon.power > 10
canon.power = 10
endif
// press enter to shoot
if GetRawKeyPressed(13) = 1
if canon.state = 1
canon.state = 2
dec canon.shots_remaining
if canon.shots_remaining <= 0
canon.shots_remaining = 0
endif
endif
endif
// change colour of canon depending on it's state
if canon.state = 1
SetSpriteColor(canon.spr_barrel,0,255,0,255)
SetSpriteColor(canon.spr_body,0,255,0,255)
else
SetSpriteColor(canon.spr_barrel,255,0,0,255)
SetSpriteColor(canon.spr_body,255,0,0,255)
endif
endfunction
function _f_manage_canon_ball()
select canon.state
case 0
ball.scale# = 1.0
SetSpriteScaleByOffset(ball.spr,ball.scale#,ball.scale#)
SetSpriteVisible(ball.spr,0)
canon.state = 1
endcase
case 1
// the canon is ready to be fired but the ball is not doing anything
endcase
case 2
// position the canon ball att he end of the barrel
ball.xp# = GetSpriteXByOffset(canon.spr_barrel)+36*sin(canon.angle)
ball.yp# = GetSpriteYByOffset(canon.spr_barrel)-36*cos(canon.angle)
// calculate the canon's initial velocities
ball.xv# = canon.power*sin(canon.angle)
ball.yv# = canon.power*cos(canon.angle)*-1
// show and position the canon ball
SetSpriteVisible(ball.spr,1)
SetSpritePositionByOffset(ball.spr,ball.xp#,ball.yp#)
// set next state
canon.state = 3
endcase
case 3
// calculate canon ball x position
ball.xp# = ball.xp# + ball.xv#
// apply gravity to the ball y velocity then calculate the new y position
ball.yv# = ball.yv# + gravity#
ball.yp# = ball.yp# + ball.yv#
SetSpritePositionByOffset(ball.spr,ball.xp#,ball.yp#)
// determine if the canon ball has hit a target (will also affect the landscape below the target
for i = 1 to 3
if target[i].life = 1
if GetSpriteCollision(ball.spr,target[i].spr) = 1
canon.state = 4
// kill the target
target[i].life = 0
SetSpriteVisible(target[i].spr,0)
// deal with the landscape below the target
ball.hit = target[i].location
ball.yp# = landscape[ball.hit].y
endif
endif
next i
// determine if canon ball has hit landscape
for i = 1 to 32
if GetSpriteCollision(ball.spr,landscape[i].spr) = 1
canon.state = 4
ball.hit = i
endif
next i
// spin the canon ball
SetSpriteAngle(ball.spr,GetSpriteAngle(ball.spr)-4)
// if ball goes off far end of the screen then reset canon
if ball.xp# > 1050
canon.state = 0
endif
endcase
case 4
// make the ball explode
ball.scale# = ball.scale#*1.25
if ball.scale# > 5
canon.state = 0
endif
// spin the canon ball
SetSpriteAngle(ball.spr,GetSpriteAngle(ball.spr)-16)
SetSpriteScaleByOffset(ball.spr,ball.scale#,ball.scale#)
// check to see if target is caught in explosion
for i = 1 to 3
if target[i].life = 1
if GetSpriteCollision(ball.spr,target[i].spr) = 1
// kill the target
target[i].life = 0
SetSpriteVisible(target[i].spr,0)
endif
endif
next i
// destroy landscape (but not the first two sprites)
if ball.hit > 2
landscape[ball.hit].y = ball.yp# + 6*ball.scale#
if landscape[ball.hit].y > 760
landscape[ball.hit].y = 760
endif
SetSpriteY(landscape[ball.hit].spr,landscape[ball.hit].y)
endif
endcase
endselect
endfunction
function _f_manage_targets()
for i = 1 to 3
if target[i].life = 1
// check to see of the landscape is lower than the the target's y position
if target[i].yp# < landscape[target[i].location].y
// apply gravity to the target's y velocity and calculate the new y position of the target
target[i].yv# = target[i].yv# + gravity#
target[i].yp# = target[i].yp# + target[i].yv#
// if the target has landed on the landscape then set the target's y position to the y position of the landscape
if target[i].yp# >= landscape[target[i].location].y
target[i].yp# = landscape[target[i].location].y
endif
SetSpritePositionByOffset(target[i].spr,target[i].xp#,target[i].yp#)
else
// if target is on the landscape then set the target's y velocity to zero
target[i].yv# = 0.0
endif
endif
next i
endfunction
function _f_manage_hud()
// shots fired hud
for i = 1 to 12
SetSpriteColor(shots_spr[i],50,50,50,255)
next i
for i = 1 to canon.shots_remaining
SetSpriteColor(shots_spr[i],255,255,0,255)
next i
// power hud
for i = 1 to 10
SetSpriteColor(power_spr[i],50,50,50,255)
next i
for i = 1 to canon.power
SetSpriteColor(power_spr[i],0,255,0,255)
next i
endfunction
function _f_game_over()
if GetRawKeyPressed(32) = 1
game_state = 2
endif
endfunction
Controls:
- Left and right arrow keys to set elavation of canon
- Up and down arrow keys to set power
- Enter to shoot
Hud (top left of screen):
- Yellow squares show the number of shots the player has left
- Green squares show the current power