CBump Template

From GiderosMobile
Revision as of 17:08, 27 November 2019 by MoKaLux (talk | contribs) (added content)


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 various ways to use CBump.


Using CBump and TILED (handles collisions)

-- usage
--local map = CBumpTiled.new("tiled/test.lua", world, bg, true)
-- where world is the cbump world
-- bg is a sprite layer (here a background sprite layer)
-- true if only foreground is added to cbump collision world

CBumpTiled = Core.class(Sprite)

local function gid2tileset(map, gid)
	for i = 1, #map.tilesets do
		local tileset = map.tilesets[i]
		if tileset.firstgid <= gid and gid <= tileset.lastgid then
			return tileset
		end
	end
end

function CBumpTiled:init(filename, xworld, xlayer, xtop)
	-- Bits on the far end of the 32-bit global tile ID are used for tile flags (flip, rotate)
	local FLIPPED_HORIZONTALLY_FLAG = 0x80000000;
	local FLIPPED_VERTICALLY_FLAG   = 0x40000000;
	local FLIPPED_DIAGONALLY_FLAG   = 0x20000000;
	local map = loadfile(filename)()
	for i = 1, #map.tilesets do
		local tileset = map.tilesets[i]
		tileset.sizex = math.floor((tileset.imagewidth - tileset.margin + tileset.spacing) / (tileset.tilewidth + tileset.spacing))
		tileset.sizey = math.floor((tileset.imageheight - tileset.margin + tileset.spacing) / (tileset.tileheight + tileset.spacing))
		tileset.lastgid = tileset.firstgid + (tileset.sizex * tileset.sizey) - 1
		tileset.texture = Texture.new(tileset.image, false, {transparentColor = tonumber(tileset.transparentcolor)})
	end
	for i = 1, #map.layers do
		if map.layers[i].type == "tilelayer" then
			local layer = map.layers[i]
			local tilemaps = {}
			for y = 1, layer.height do
				for x = 1, layer.width do
					local i = x + (y - 1) * layer.width
					local gid = layer.data[i]
					if gid ~= 0 then
						-- Read flipping flags
						flipHor = gid & FLIPPED_HORIZONTALLY_FLAG
						flipVer = gid & FLIPPED_VERTICALLY_FLAG
						flipDia = gid & FLIPPED_DIAGONALLY_FLAG
						-- Convert flags to gideros style
						if(flipHor ~= 0) then flipHor = TileMap.FLIP_HORIZONTAL end
						if(flipVer ~= 0) then flipVer = TileMap.FLIP_VERTICAL end
						if(flipDia ~= 0) then flipDia = TileMap.FLIP_DIAGONAL end
						-- Clear the flags from gid so other information is healthy
						gid = gid & ~ (
							FLIPPED_HORIZONTALLY_FLAG |
							FLIPPED_VERTICALLY_FLAG |
							FLIPPED_DIAGONALLY_FLAG
						)
					end

					local tileset = gid2tileset(map, gid)
					if tileset then
						local tilemap = nil
						tilemap = TileMap.new(
							layer.width, 
							layer.height,
							tileset.texture,
							tileset.tilewidth,
							tileset.tileheight,
							tileset.spacing,
							tileset.spacing,
							tileset.margin,
							tileset.margin,
							map.tilewidth,
							map.tileheight
						)
						tilemaps[tileset] = tilemap
						local tx = (gid - tileset.firstgid) % tileset.sizex + 1
						local ty = math.floor((gid - tileset.firstgid) / tileset.sizex) + 1
						-- Set the tile with flip info
						tilemap:setTile(x, y, tx, ty, (flipHor | flipVer | flipDia))
						xlayer:addChild(tilemap)
						xlayer:setAlpha(layer.opacity)
						if xtop then
							if layer.id == 1 then
								xworld:add(
									tilemap,
									(x - 1) * tileset.tilewidth * xlayer:getScaleX(),
									(y - 1) * tileset.tileheight * xlayer:getScaleY(),
									tileset.tilewidth * xlayer:getScaleX(),
									tileset.tileheight * xlayer:getScaleY()
								)
							end
						else
							xworld:add(
								tilemap,
								(x - 1) * tileset.tilewidth * xlayer:getScaleX(),
								(y - 1) * tileset.tileheight * xlayer:getScaleY(),
								tileset.tilewidth * xlayer:getScaleX(),
								tileset.tileheight * xlayer:getScaleY()
							)
						end
					end
				end
			end
		end
	end
end


Usage

This is an example of how to set up CBump and TILED.


-- cbump
local cbump = require "cbump"
local world = cbump.newWorld() -- default is 64

-- camera
local camera = Sprite.new()
local bg = Sprite.new()
bg:setColorTransform(255/255, 0/255, 0/255, 255/255)
local fg = Sprite.new()
camera:setScale(1)
camera:addChild(bg)
camera:addChild(fg)
stage:addChild(camera)

-- tiled
local map = CBumpTiled.new("tiled/test.lua", world, bg, true)



A Sprite Factory (player, enemies, collectibles...)

This is a sprite factory class where you can 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 -- 150 -- 200
	self.jumpspeed = GRAVITY / 1.5

	-- 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
		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)
	elseif self.name == "enemy01" then
		self:createAnim("walk", 1, 7, myanims_list)
	elseif self.name == "enemy02" then
		self:createAnim("walk", 1, 5, myanims_list)
	elseif self.name == "coin01" then
		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
		self.w = self.bmp:getWidth() / 2
		self.h = self.bmp:getHeight() - 6
		-- set position inside sprite
		self.bmp:setPosition(self.w / 2, self.h / 2 - 6 / 2)
	elseif self.name == "enemy01" then
		self.w = self.bmp:getWidth() / 2
		self.h = self.bmp:getHeight() - 12
		-- set position inside sprite
		self.bmp:setPosition(self.w / 2, self.h / 2 - 12 / 2)
	elseif self.name == "enemy02" then
		self.w = self.bmp:getWidth() / 8
		self.h = self.bmp:getHeight() - 38
		-- set position inside sprite
		self.bmp:setPosition(self.w / 2, self.h / 2 - 38 / 2 + 6)
	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
	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