Difference between revisions of "Animated Sprite Factory"

From GiderosMobile
m
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
__TOC__
 
__TOC__
<languages />
+
Here you will find various resources to help you create games and apps in Gideros Studio.
<translate>Here you will find various resources to help you create games and apps in Gideros Studio.</translate>
 
<br/>
 
<translate>'''note''': You may have to provide your own assets (fonts, gfx, …).</translate>
 
<br/>
 
  
=== <translate>Description</translate> ===
+
'''note''': You may have to provide your own assets (fonts, gfx, ).</br>
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.
+
'''note 2''': You can copy/paste the code :-)
  
=== <translate>Animation Sprite Factory (player, enemies, collectibles, npcs, ...)</translate> ===
+
=== Description ===
This animation sprite factory class allows you to control all your characters parameters like speed, animations, ...
+
This section deals with animating any of your sprites (player, enemies, collectibles, ...). It can be used either in conjunction with cbump, liquidfun(box2d) or as standalone.
 +
 
 +
=== Spritesheet Animations (player, enemies, collectibles, npcs, ...) ===
 +
This is an example of how to animate using a spritesheet.
 
<source lang="lua">
 
<source lang="lua">
--[[
+
-- spritesheet animations
-- FREE TO USE AND MODIFY
+
local spritesheettex = Texture.new("gfx/hero/HQ_Trooper_all.png") -- change accordingly
 
+
local xcols, xrows = 6, 13 -- change accordingly
Sprite_Maker:init(xname, xspritesheet, xcols, xrows, xposx, xposy)
+
local spritesheetimgs = {} -- table that will hold all the images in the sprite sheet
 
+
local anims = {} -- table that will hold all our animations ("idle", "run", ...)
Where:
+
local currentanim = ""
xname (String) = the name of your sprite (default are "player1", "enemy01", "enemy02", "coin01")
+
local frame = 0
xspritesheet (String) = the path to your spritesheet gfx (png, jpeg, ...)
+
local animspeed = 1 / 7 -- change accordingly
xcols (int) = the number of columns of your sprite spritesheet
+
local animtimer = animspeed
xrows (int) = the number of rows of your sprite spritesheet
 
xposx (int) = initial x position of your sprite
 
xposy (int) = initial y position of your sprite
 
 
example:
 
local player1 = Sprite_Maker.new("player1", "gfx/hero/HQ_Trooper_all.png", 6, 13, 64, 128)
 
]]
 
 
 
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) -- you can uncomment this line for debugging
 
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)
+
-- 1 retrieve all anims in spritesheet
self:addEventListener(Event.KEY_UP, self.onKeyUp, self)
+
local w, h = spritesheettex:getWidth() / xcols, spritesheettex:getHeight() / xrows
 +
local spritesheettexregion = nil
 +
for r = 1, xrows do
 +
for c = 1, xcols do
 +
spritesheettexregion = TextureRegion.new(spritesheettex, (c - 1) * w, (r - 1) * h, w, h)
 +
spritesheetimgs[#spritesheetimgs + 1] = spritesheettexregion
 
end
 
end
 
end
 
end
  
-- FUNCTIONS
+
-- 2 create animations
function Sprite_Maker:createAnim(xanimname, xstart, xfinish, xanimslist)
+
function createAnim(xanimname, xstart, xfinish)
self.anims[xanimname] = {}
+
anims[xanimname] = {}
 
for i = xstart, xfinish do
 
for i = xstart, xfinish do
self.anims[xanimname][#self.anims[xanimname] + 1] = xanimslist[i]
+
anims[xanimname][#anims[xanimname] + 1] = spritesheetimgs[i]
 
end
 
end
 
end
 
end
 +
createAnim("idle", 1, 2)
 +
createAnim("run", 25, 30)
  
-- KEYS HANDLER
+
-- 3 we can now create the player
function Sprite_Maker:onKeyDown(e)
+
local bitmap = Bitmap.new(spritesheetimgs[1])
-- keys pressed
+
bitmap:setAnchorPoint(0.5, 0.5)
if e.keyCode == KeyCode.LEFT then self.iskeyleft = true end
+
bitmap:setPosition(128, 64)
if e.keyCode == KeyCode.RIGHT then self.iskeyright = true end
+
stage:addChild(bitmap)
if e.keyCode == KeyCode.UP then self.iskeyup = true end
+
currentanim = "idle"
if e.keyCode == KeyCode.DOWN then self.iskeydown = true end
+
--currentanim = "run"
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
 
</source>
 
 
 
=== <translate>Example</translate> ===
 
<source lang="lua">
 
-- 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
 
-- GAME LOOP
stage:addEventListener(Event.ENTER_FRAME, function(e)
+
function onEnterFrame(e)
updatePlayer(player1, e.deltaTime)
+
if currentanim ~= "" then
updateCollectibles(coin, e.deltaTime)
+
animtimer = animtimer - e.deltaTime
end)
+
if animtimer <= 0 then
 
+
frame += 1
-- FUNCTIONS
+
animtimer = animspeed
function updatePlayer(xsprite, dt)
+
if frame > #anims[currentanim] then
-- anim state
+
frame = 1
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
 
end
xsprite.bmp:setTextureRegion(xsprite.anims[xsprite.currentanim][xsprite.frame])
+
bitmap:setTextureRegion(anims[currentanim][frame])
 
end
 
end
 
end
 
end
-- show
 
xsprite:setPosition(xsprite.x, xsprite.y)
 
xsprite.bmp:setScale(xsprite.flip, 1)
 
 
end
 
end
 +
stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)
 
</source>
 
</source>
  
=== <translate>Assets</translate> ===
+
=== Assets ===
 
You can pick the files from opengameart.org:
 
You can pick the files from opengameart.org:
 
* https://opengameart.org/content/space-soldier-resize-64x64
 
* https://opengameart.org/content/space-soldier-resize-64x64
 
* https://opengameart.org/content/pixel-coins-asset
 
* https://opengameart.org/content/pixel-coins-asset

Revision as of 18:24, 23 November 2020

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, …).
note 2: You can copy/paste the code :-)

Description

This section deals with animating any of your sprites (player, enemies, collectibles, ...). It can be used either in conjunction with cbump, liquidfun(box2d) or as standalone.

Spritesheet Animations (player, enemies, collectibles, npcs, ...)

This is an example of how to animate using a spritesheet.

-- spritesheet animations
local spritesheettex = Texture.new("gfx/hero/HQ_Trooper_all.png") -- change accordingly
local xcols, xrows = 6, 13 -- change accordingly
local spritesheetimgs = {} -- table that will hold all the images in the sprite sheet
local anims = {} -- table that will hold all our animations ("idle", "run", ...)
local currentanim = ""
local frame = 0
local animspeed = 1 / 7 -- change accordingly
local animtimer = animspeed

-- 1 retrieve all anims in spritesheet
local w, h = spritesheettex:getWidth() / xcols, spritesheettex:getHeight() / xrows
local spritesheettexregion = nil
for r = 1, xrows do
	for c = 1, xcols do
		spritesheettexregion = TextureRegion.new(spritesheettex, (c - 1) * w, (r - 1) * h, w, h)
		spritesheetimgs[#spritesheetimgs + 1] = spritesheettexregion
	end
end

-- 2 create animations
function createAnim(xanimname, xstart, xfinish)
	anims[xanimname] = {}
	for i = xstart, xfinish do
		anims[xanimname][#anims[xanimname] + 1] = spritesheetimgs[i]
	end
end
createAnim("idle", 1, 2)
createAnim("run", 25, 30)

-- 3 we can now create the player
local bitmap = Bitmap.new(spritesheetimgs[1])
bitmap:setAnchorPoint(0.5, 0.5)
bitmap:setPosition(128, 64)
stage:addChild(bitmap)
currentanim = "idle"
--currentanim = "run"

-- GAME LOOP
function onEnterFrame(e)
	if currentanim ~= "" then
		animtimer = animtimer - e.deltaTime
		if animtimer <= 0 then
			frame += 1
			animtimer = animspeed
			if frame > #anims[currentanim] then
				frame = 1
			end
			bitmap:setTextureRegion(anims[currentanim][frame])
		end
	end
end
stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)

Assets

You can pick the files from opengameart.org: