Animated Sprite Factory
From GiderosMobile
Here you will find various resources to help you create games and apps in Gideros Studio.
note: You may have to provide your own assets (fonts, gfx, …).
Description
This section deals with animating any of your sprites (player, enemies, collectibles, ...). It can be used either in conjunction with cbump, liquidfun or as a standalone class.
Animation Sprite Factory (player, enemies, collectibles, npcs, ...)
This animation sprite factory class allows you to control all your characters parameters like speed, animations, ...
Sprite_Maker = Core.class(Sprite)
function Sprite_Maker:init(xname, xspritesheet, xcols, xrows, xposx, xposy)
-- settings
self.name = xname
self.x = xposx
self.y = xposy
self.vx = 0
self.vy = 0
self.flip = 1
self.isonfloor = false
self.isattacking = false
self.lives = 1
self.accel = 500
self.maxspeed = 200
self.jumpspeed = 980
-- animations
self.currentanim = ""
self.frame = 0
self.animspeed = 1 / 8
self.animtimer = self.animspeed
-- retrieve all anims in texture
local myanimstex = Texture.new(xspritesheet)
local cellw = myanimstex:getWidth() / xcols
local cellh = myanimstex:getHeight() / xrows
local myanims_list = {}
for r = 1, xrows do
for c = 1, xcols do
local myanimstexregion = TextureRegion.new(
myanimstex, (c - 1) * cellw, (r - 1) * cellh, cellw, cellh)
myanims_list[#myanims_list + 1] = myanimstexregion
end
end
-- create anims
self.anims = {}
if self.name == "player1" then -- you can adapt your name here!
self:createAnim("idle", 1, 2, myanims_list)
self:createAnim("jump_up", 38, 38, myanims_list)
self:createAnim("jump_down", 39, 39, myanims_list)
self:createAnim("walk", 13, 16, myanims_list)
self:createAnim("shoot", 67, 70, myanims_list)
elseif self.name == "enemy01" then -- you can adapt your name here!
self:createAnim("walk", 1, 7, myanims_list)
elseif self.name == "enemy02" then -- you can adapt your name here!
self:createAnim("walk", 1, 5, myanims_list)
elseif self.name == "coin01" then -- you can adapt your name here!
self:createAnim("walk", 1, 6, myanims_list)
end
-- the bitmap
self.bmp = Bitmap.new(myanims_list[1]) -- starting bmp texture
self.bmp:setAnchorPoint(0.5, 0.5)
if self.name == "player1" then -- adapt name here
self.w = self.bmp:getWidth() / 2
self.h = self.bmp:getHeight() - 0
-- set position inside sprite
self.bmp:setPosition(self.w / 2, self.h / 2 - 0 / 2)
elseif self.name == "enemy01" then -- adapt name here
self.w = self.bmp:getWidth() / 2
self.h = self.bmp:getHeight() - 0
-- set position inside sprite
self.bmp:setPosition(self.w / 2, self.h / 2 - 0 / 2)
elseif self.name == "enemy02" then -- adapt name here
self.w = self.bmp:getWidth() / 8
self.h = self.bmp:getHeight() - 0
-- set position inside sprite
self.bmp:setPosition(self.w / 2, self.h / 2 - 0 / 2)
else
self.w = self.bmp:getWidth()
self.h = self.bmp:getHeight()
-- set position inside sprite
self.bmp:setPosition(self.w / 2, self.h / 2)
end
-- collisions debugging
local mypixel = Pixel.new(0xff0000, 0.5, self.w, self.h)
-- our sprite is ready
local mysprite = Sprite.new()
mysprite:addChild(self.bmp)
mysprite:addChild(mypixel) -- debug. you can comment this line when you are done
self:addChild(mysprite)
-- hero controls
if self.name == "player1" then
self.iskeyleft = false
self.iskeyright = false
self.iskeyup = false
self.iskeydown = false
self.iskeyspace = false
self:addEventListener(Event.KEY_DOWN, self.onKeyDown, self)
self:addEventListener(Event.KEY_UP, self.onKeyUp, self)
end
end
-- FUNCTIONS
function Sprite_Maker:createAnim(xanimname, xstart, xfinish, xanimslist)
self.anims[xanimname] = {}
for i = xstart, xfinish do
self.anims[xanimname][#self.anims[xanimname] + 1] = xanimslist[i]
end
end
-- KEYS HANDLER
function Sprite_Maker:onKeyDown(e)
-- keys pressed
if e.keyCode == KeyCode.LEFT then self.iskeyleft = true end
if e.keyCode == KeyCode.RIGHT then self.iskeyright = true end
if e.keyCode == KeyCode.UP then self.iskeyup = true end
if e.keyCode == KeyCode.DOWN then self.iskeydown = true end
if e.keyCode == KeyCode.SPACE then self.iskeyspace = true end
end
function Sprite_Maker:onKeyUp(e)
-- keys released
if e.keyCode == KeyCode.LEFT then self.iskeyleft = false end
if e.keyCode == KeyCode.RIGHT then self.iskeyright = false end
if e.keyCode == KeyCode.UP then self.iskeyup = false end
if e.keyCode == KeyCode.DOWN then self.iskeydown = false end
if e.keyCode == KeyCode.SPACE then self.iskeyspace = false end
end
Example
-- stage
local player1 = Sprite_Maker.new("player1", "gfx/hero/HQ_Trooper_all.png", 6, 13, 64, 128)
player1.lives = 3 -- you can change parameters on the fly
stage:addChild(player1)
local coin = Sprite_Maker.new("coin01", "gfx/coins/coin_20_x01.png", 6, 1, 128, 128)
coin:setScale(3)
coin.animspeed = 1 / 3
stage:addChild(coin)
-- GAME LOOP
stage:addEventListener(Event.ENTER_FRAME, function(e)
updatePlayer(player1, e.deltaTime)
updateCollectibles(coin, e.deltaTime)
end)
-- FUNCTIONS
function updatePlayer(xsprite, dt)
-- anim state
if xsprite.vx == 0 then
xsprite.currentanim = "idle"
elseif xsprite.vx ~= 0 then
xsprite.currentanim = "walk"
end
-- keyboard handling
if xsprite.iskeyright then
xsprite.vx += xsprite.accel * dt
if xsprite.vx > xsprite.maxspeed then xsprite.vx = xsprite.maxspeed end
xsprite.flip = 1
elseif xsprite.iskeyleft then
xsprite.vx -= xsprite.accel * dt
if xsprite.vx < -xsprite.maxspeed then xsprite.vx = -xsprite.maxspeed end
xsprite.flip = -1
else
xsprite.vx = 0
end
-- anim loop
if xsprite.currentanim ~= "" then
xsprite.animtimer = xsprite.animtimer - dt
if xsprite.animtimer <= 0 then
xsprite.frame += 1
xsprite.animtimer = xsprite.animspeed
if xsprite.frame > #xsprite.anims[xsprite.currentanim] then
xsprite.frame = 1
end
xsprite.bmp:setTextureRegion(xsprite.anims[xsprite.currentanim][xsprite.frame])
end
end
-- move & flip
xsprite.x += xsprite.vx * dt
xsprite.y += xsprite.vy * dt
xsprite:setPosition(xsprite.x, xsprite.y)
xsprite.bmp:setScale(xsprite.flip, 1)
end
function updateCollectibles(xsprite, dt)
-- anim state
xsprite.currentanim = "walk"
-- anim loop
if xsprite.currentanim ~= "" then
xsprite.animtimer = xsprite.animtimer - dt
if xsprite.animtimer <= 0 then
xsprite.frame += 1
xsprite.animtimer = xsprite.animspeed
if xsprite.frame > #xsprite.anims[xsprite.currentanim] then
xsprite.frame = 1
end
xsprite.bmp:setTextureRegion(xsprite.anims[xsprite.currentanim][xsprite.frame])
end
end
-- show
xsprite:setPosition(xsprite.x, xsprite.y)
xsprite.bmp:setScale(xsprite.flip, 1)
end