It’s time to put the final touches to our game, namely animating the player sprite. Previously I’ve shown you how to do this for the enemies, and also how to create the enemies as objects, so we’re combining those for this task.
Part 10: Player Animation
As before, we need to draw some frames of animation to use. I’ve created some additional frames in sprite slots 2, 3 and 4 to carry on from 1.
Again, it’s pretty simple but is just for illustration.
Now, we need to create the player as an object. We could have a function to house this, make_player() like we have make_enemy(), but we only need to create one player so that’s overkill. Instead, we’ll create it in one go in the _init() function, replacing the x and y we had there before:
-- create player object
player = {}
player.x = 64
player.y = 64
player.sprite = 1
player.frame = 0
player.framemax = 3
player.ticks = 0
player.ticksmax = 4
player.draw = function(this)
this.ticks += 1
if this.ticks == this.ticksmax then
if this.frame == this.framemax then
this.frame = 0
else
this.frame += 1
end
this.ticks = 0
end
spr(this.sprite+this.frame, this.x, this.y)
end
You’ll notice I’ve put a player.draw function in there, which works just like the enemy draw function from last time.
Now we need to replace all references to x and y in the code, with player.x and player.y. You’ll find some in the button press check code (e.g. if btn(0) and x > 0 then…), in the collision check routine (if checkcol(x,y,en.x,en.y)) and in the en.move function (if x < this.x then…).
if btn(0) and player.x > 0 then player.x -= 1 end if btn(1) and player.x < 120 then player.x += 1 end if btn(2) and player.y > 0 then player.y -= 1 end if btn(3) and player.y < 120 then player.y += 1 end
if checkcol(player.x,player.y,en.x,en.y) then stop() end
en.move = function(this) if player.x < this.x then this.x -= this.d end if player.x > this.x then this.x += this.d end if player.y < this.y then this.y -= this.d end if player.y > this.y then this.y += this.d end end
Finally, we need to replace the code in _draw() that drew the player sprite. It was spr(1,x,y), but now we just call:
player:draw()
Save, deep breath, run!
And that’s it. We have a complete, working game with enemies, movement, collisions and animation. Sure, we don’t have any sound, a title screen, lives or a game over sequence, but the game logic is there and you can see it’s a place to build from.
Here’s the final code. Skip past it to play the actual game!
function _init()
-- create player object
player = {}
player.x = 64
player.y = 64
player.sprite = 1
player.frame = 0
player.framemax = 3
player.ticks = 0
player.ticksmax = 4
player.draw = function(this)
this.ticks += 1
if this.ticks == this.ticksmax then
if this.frame == this.framemax then
this.frame = 0
else
this.frame += 1
end
this.ticks = 0
end
spr(this.sprite+this.frame, this.x, this.y)
end
ticks = 0
tickstrigger = 200
dinc = 0.05
-- score
score = 0
-- initialise enemies table
enemies = {}
-- make first enemy
make_enemy(17,120,120,0.05,3,0,5)
end
function _update()
-- check for collision
foreach(enemies, function(en)
if checkcol(player.x,player.y,en.x,en.y) then
stop()
end
end)
--[[ check button presses and screen edge
btn(0) is left
btn(1) is right
btn(2) is up
btn(3) is down
]]
if btn(0) and player.x > 0 then
player.x -= 1
end
if btn(1) and player.x < 120 then
player.x += 1
end
if btn(2) and player.y > 0 then
player.y -= 1
end
if btn(3) and player.y < 120 then
player.y += 1
end
-- move enemies
foreach(enemies, function(en) en:move() end)
-- increment score
score += 1
-- if ticks are triggered, make enemy faster
ticks += 1
if ticks > tickstrigger then
foreach(enemies, function(en) en.d += dinc end)
ticks = 0
make_enemy(17,rnd(128),rnd(128),0.05,3,0,4)
end
end
function _draw()
cls(2) -- clear the screen to mauve
print(score,100,0,7) -- print score
player:draw() -- draw player
-- draw all enemies
foreach(enemies, function(en) en:draw() end)
end
function checkcol(ax,ay,bx,by)
if bx+8>ax and bx<ax+8 and by+8>ay and by<ay+8 then
return true
else
return false
end
end
function make_enemy(espr,ex,ey,ed,eframemax,eticks,eticksmax)
en = {}
en.sprite = espr
en.x = ex
en.y = ey
en.d = ed
en.frame = 0
en.framemax = eframemax
en.ticks = eticks
en.ticksmax = eticksmax
en.draw = function(this)
this.ticks += 1 -- increment ticks
if this.ticks == this.ticksmax then
-- have we hit the last tick?
-- if so, inc the frame
if this.frame == this.framemax then
-- have we hit the last frame?
this.frame = 0 -- set back to first frame
else
this.frame += 1 -- inc the frame
end
this.ticks = 0
end
spr(this.sprite+this.frame,this.x,this.y)
end
en.move = function(this)
if player.x < this.x then this.x -= this.d end
if player.x > this.x then this.x += this.d end
if player.y < this.y then this.y -= this.d end
if player.y > this.y then this.y += this.d end
end
add(enemies,en)
end
[includeme src=”https://lofi-gaming.org.uk/gamedev/firstgame/firstgame.html” frameborder=”0″ width=”400″ height=”400″]
