Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Is this the fastest way to code this? — Gideros Forum

Is this the fastest way to code this?

Tom2012Tom2012 Guru
edited January 2013 in General questions
Apologies in advance for the amount of code in this post...

Short version:

1) I have my level data in a lua table, which I load with dofile()
2) I use a for loop to add each sprite to the stage.

I'd like to know if there's any speed tweaks I could make. :D

Thank you

Lua table:
i = {}
i[1] = {}
i[1].file = "mud blank.png"
i[1].center = {}
i[1].center.x = 1.5058
i[1].center.y = -3.4309
i[1].angle = -0.2627
i[1].renderOrder = -20
i[1].scale = 2.0116
i[1].customProperties = {}
i[1].customProperties[1] = {}
i[1].customProperties[1].name = "Atlas"
i[1].customProperties[1].int = 3
i[2] = {}
i[2].file = "mud blank.png"
i[2].center = {}
i[2].center.x = 3.5691
i[2].center.y = -3.8981
i[2].angle = -0.2627
i[2].renderOrder = -20
i[2].scale = 2.0116
i[2].customProperties = {}
i[2].customProperties[1] = {}
i[2].customProperties[1].name = "Atlas"
i[2].customProperties[1].int = 3
i[5] = {}
Code to add sprites to stage:
Rube = Core.class(Sprite)
 
function Rube:init(scene,levelData)
 
	self.scene = scene
 
	-- Set scale
	-- 1 square on rube = x pixels
 
	local worldScale = 100
 
	-- Bring in the level data file
 
	dofile(levelData)
 
	-- Open json file
 
	-------------------------------------------------------
	-- Add sprites
	-------------------------------------------------------
 
	for index,theImage in pairs(i) do
 
		-- Set the default
		self.isImage = false
 
		-- Get position
 
		self.x = math.floor(theImage.center.x * worldScale)
		self.y = math.floor((theImage.center.y * worldScale)*-1)
 
		-- Get custom properties
 
		if(theImage.customProperties) then
 
			self.customProperties = {}
 
			for i,v in pairs(theImage.customProperties) do
 
				-- For each custom property
 
				if(v.name=="Atlas") then
						self.customProperties.atlas = v.int
				elseif(v.name=="xDist") then
						self.customProperties.xDist = v.int
				elseif(v.name=="xSpeed") then
						self.customProperties.xSpeed = v.int
				elseif(v.name=="signText") then
						self.customProperties.signText = v.string
				end
 
			end
 
		end
 
		-- Print image name
		--print(theImage.file)
 
		if(string.find(theImage.file, "head and body")) then
 
			-- Hero
 
			local hero = Hero.new(self.scene,self.x,self.y)
			self.isHero = true
			self.scene.physicsLayer:addChild(hero)
			self.scene.hero = hero
			table.insert(self.scene.spritesOnScreen, hero)
			self.sprite = nil
 
		elseif(string.find(theImage.file, "coin")) then
			-- coin
			self.sprite = Coin.new(self.scene)
			table.insert(self.scene.coins, self.sprite)
		elseif(string.find(theImage.file, "skull")) then
			-- skull
			self.sprite = Loot.new(self.scene,"GREEN_SKULL",50, "green skull")
 
		elseif(string.find(theImage.file, "spider")) then
			-- spider
			self.sprite = Loot.new(self.scene,"GREEN_SPIDER",80, "green spider")
 
		elseif(string.find(theImage.file, "door frame")) then
			-- Exit door
 
			self.sprite = Door.new(self.scene)
 
		elseif(string.find(theImage.file, "gold 1")) then
			self.sprite = Loot.new(self.scene,"gold 1.png",10, "gold")
 
		elseif(string.find(theImage.file, "gold 2")) then
			self.sprite = Loot.new(self.scene,"gold 2.png",20, "gold")
		elseif(string.find(theImage.file, "gold 3")) then
			self.sprite = Loot.new(self.scene,"gold 3.png",30, "gold")
		elseif(string.find(theImage.file, "gold 4")) then
			self.sprite = Loot.new(self.scene,"gold 4.png",40, "gold")
 
 
		-- Crystals
 
		elseif(string.find(theImage.file, "red1")) then
			self.sprite = Crystal.new(self.scene,"red")
			table.insert(self.scene.crystals, self.sprite)
 
		elseif(string.find(theImage.file, "purple1")) then
 
			self.sprite = Crystal.new(self.scene,"purple")
			table.insert(self.scene.crystals, self.sprite)
 
		-- Claw objects
 
		elseif(string.find(theImage.file, "Claw Objects")) then
 
			local parts = explode("/", theImage.file)
			self.sprite = ClawObject.new(self.scene,self.x,self.y,parts[2])
 
		-- Signs
 
		elseif(string.find(theImage.file, "sign")) then
 
			self.sprite = Sign.new(self.scene,self.customProperties.signText)	
 
		-- Enemies
 
		elseif(string.find(theImage.file, "worm wraith")) then
 
		-- Worm Wraith
 
		local xDist = self.customProperties.xDist
		local xSpeed = self.customProperties.xSpeed
 
		self.sprite = WormWraith.new(self.scene,self.x,200,50)
 
		-- Smashable Pots
 
		elseif(string.find(theImage.file, "pot ")) then
 
			self.sprite = Pot.new(self.scene)
 
		else
 
			-- need to make it choose atlas...
 
			self.atlasNum = nil
 
			if(theImage.customProperties) then
 
			-- If this image was in a folder, explode and get image name
			if(string.find(theImage.file, "/")) then
				local parts = explode("/", theImage.file)
				self.imageName = parts[2]
			else
				self.imageName = theImage.file
			end
 
				self.sprite = Bitmap.new(self.scene.atlas[self.customProperties.atlas]:getTextureRegion(self.imageName))
				self.isImage = true
			else
				print("ERROR! Image", theImage.file , "is missing Atlas# property")
			end
 
		end
 
		-- Set the scale
 
		if(self.sprite) then
 
			-- get the size
			local imageHeight = self.sprite:getHeight()
			--print("imageHeight", imageHeight)
 
			-- get scale
			local scale = 100 / imageHeight
			--print("scale", scale)
 
			-- Flip?
 
			if(theImage.flip) then
				self.flipValue = -1
			else
				self.flipValue = 1
			end
 
			if(self.isImage) then
 
				self.sprite:setAnchorPoint(.5,.5) -- Set anchor point
				local xScale = (scale*theImage.scale)*1.030*self.flipValue
				local yScale = (scale*theImage.scale)*1.030
				self.sprite:setScale(xScale,yScale)
 
			else
 
				if(self.flipValue==-1) then
					self.sprite:setScaleX(self.flipValue)
				end
 
			end
 
			-- set position
 
			self.sprite:setPosition(self.x,self.y)
 
			-- get rotation
 
			local angle = theImage.angle
			self.sprite:setRotation(math.deg(angle)*-1)
 
			-- Decide which layer the image should go on
			-- renderOrder 0-100 = behind player
			-- 101 upwards = in front of player
 
				if(theImage.renderOrder<101) then
					self.scene.rube1:addChild(self.sprite)
				else
					self.scene.rube2:addChild(self.sprite)
				end
 
		-- end if there is a sprite
		end
 
	-- end for each image
	end
 
 
	-- delete table from memory
	i = nil

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    @Tom2012 is i an indexed array?
    If so you can loop through it as
    for ind = 1, #i do
        ....
    end
    Some say that it could work up to 8 times faster than pairs()
  • Wow I had no idea.

    Thank you ar2rsawseen

    I owe you another beer. :D
  • @Tom2012 not related to your question but do you use a camera system for the game ?
  • @Tom2012 is i an indexed array?
    If so you can loop through it as
    for ind = 1, #i do
        ....
    end
    Some say that it could work up to 8 times faster than pairs()
    +1 for this code, there are plenty of references online as to why a simple loop is faster than pairs() or ipairs(), I always use a for loop like that as a matter of course (what with being old-skool and all that).

    Guess some of us "old gits" do know a thing or two after all :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • @twisttap

    Yes, this is an iphone game and the camera pans around as the character moves.

    It's based on http://appcodingeasy.com/Gideros-Mobile/Gideros-Camera-Move by ar2rsawseen

    Here's what I do:

    1) I have a file in my project called camera.lua

    The contents of this file are:
    Camera = Core.class(Sprite)
     
    function Camera:init(scene)
     
    self.scene = scene
     
    -- Get screen dimensions
    self.screenWidth = application:getContentWidth()
    self.screenHeight = application:getContentHeight()
     
    end
     
    function Camera:update()
     
    	--define offsets
     
    	local offsetX = 0
    	local offsetY = 0
     
     
    --	print(self.scene.hero:getX())
     
    	if((self.scene.worldWidth - self.scene.hero:getX()) < self.screenWidth/2) then
    		offsetX = -self.scene.worldWidth + self.screenWidth
    	elseif(self.scene.hero:getX() >= self.screenWidth/2) then
    		offsetX = -(self.scene.hero:getX() - self.screenWidth/2)
    	end
     
    	--check if we are not too close to upper or bottom wall
    	--so we won't go further that wall
     
    	if((self.scene.worldHeight - self.scene.hero:getY()) < self.screenHeight/2) then
    		offsetY = -self.scene.worldHeight + self.screenHeight
    	elseif(self.scene.hero:getY()>= self.screenHeight/2) then
    		offsetY = -(self.scene.hero:getY() - self.screenHeight/2)
    	end
     
    	--apply offset so scene
    	self.scene.physicsLayer:setPosition(offsetX,offsetY)
    	self.scene.rube1:setPosition(offsetX,offsetY)
    	self.scene.rube2:setPosition(offsetX,offsetY)
    	--self.scene.backgroundTiles:setPosition((x*-1)*.4, (y*-1)*.4)
     
    	self.scene.frontLayer:setPosition(offsetX, offsetY)
    	self.scene.collectibles:setPosition(offsetX, offsetY)
    	self.scene.enemyLayer:setPosition(offsetX, offsetY)
    	self.scene.behindTiles:setPosition(offsetX, offsetY)
    	self.scene.clawLayer:setPosition(offsetX, offsetY)
     
    end
    2) On my scene I use this code to start the camera
    --------------------------------------------------------------
    -- Set up camera
    --------------------------------------------------------------
     
    local camera = Camera.new(self)
    self:addChild(camera)
    self.camera = camera
    My physics world is on the physics 'layer' and the other layers are scrolled as you can see in the camera class.

    I have my 'layers' which are really just sprites - set up in each scene like this:
    --------------------------------------------------------------
    -- Layers
    --------------------------------------------------------------
     
    -- Behind rube layer
     
    local behindTiles = Sprite.new()
    self:addChild(behindTiles)
    self.behindTiles = behindTiles
     
    -- Enemies
     
    local enemyLayer = Sprite.new()
    self:addChild(enemyLayer)
    self.enemyLayer = enemyLayer
     
    -- Rube images behind hero
    local rube1 = Sprite.new()
    self:addChild(rube1)
    self.rube1 = rube1
     
    -- Collectibles
     
    local collectibles = Sprite.new()
    self:addChild(collectibles)
    self.collectibles = collectibles
    Hope this helps. :D
  • Tom2012Tom2012 Guru
    edited January 2013
    @ar2rsawseen and techdojo

    This for loop definitely seems to run faster.

    I'm also experimenting with the numbers of sprites on screen vs. the size of the sprites. Large sprites doesn't seem to be a problem for Gideros. A large number of sprites doesn't seem to be a problem either.

    As others have stated this framework seems to be very fast! :D
Sign In or Register to comment.