Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Moving background — Gideros Forum

Moving background

edited July 2016 in Code snippets
Hi!

I'm just starting work with Gideros. I'm just making a little project to learn it and came to a problem. I wanted to have a moving background. The background is tiled and I just want it to gently smooth continuously.

Here is a snippet of what I've done:
MovingBackground = gideros.class(Sprite)
 
function MovingBackground:init()
  self.pixelsPerSecond = 30;
  self.backgroundTexture = Texture.new("art/background.png", true, {wrap = Texture.REPEAT})
  self.position=0
  self.originX = (application:getLogicalWidth() - application:getDeviceWidth())/2
  self.originY = (application:getLogicalHeight() - application:getDeviceHeight())/2
 
  self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
 
end
 
function MovingBackground:onEnterFrame(event)
  local matrix = Matrix.new(1, 0, 0, 1, 0, 0)
  matrix:setPosition(self.position,self.position)
  self.position = self.position + self.pixelsPerSecond * event.deltaTime;
  if (self.position > 256) then
    self.position = 0
  end
  if self:getNumChildren() > 0 then
    self:removeChildAt(1)
  end
  local shape = Shape.new()
  shape:setFillStyle(Shape.TEXTURE, self.backgroundTexture, matrix)
  shape:beginPath(Shape.NON_ZERO)
  shape:moveTo(self.originX,self.originY)
  shape:lineTo(application:getDeviceWidth(), self.originY)
  shape:lineTo(application:getDeviceWidth(), application:getDeviceHeight())
  shape:lineTo(self.originX, application:getDeviceHeight())
  shape:lineTo(self.originX,self.originY)
  shape:endPath()
  self:addChild(shape)
end
As you may see, I create the shape for every frame using a matrix. I've tried to create the shape at init and re-apply the matrix at each enterFrame, but that didn't work.

I'm a Java developer, and the idea of creating an object at every frame is scary and (at least in Java) a resource-eater.

So, for the more experienced people. Is there any more effective way of achieving this? could I create a single Texture and a single Shape and animate it? or is this the proper way in Gideros?

Thanks in advance

Comments

  • ar2rsawseenar2rsawseen Maintainer
    1) you dont have to create new Shape each time, create one and just clear it and redraw
    2) you can create 2 shapes and just change their x, y position to move them and when one goes out of screen, jump it back after the current one, etc
    +1 -1 (+1 / -0 )Share on Facebook
  • @ar2rsawseen good one on clear+redraw
    about moving them, afaik I need 4, movement is diagonal
  • hgy29hgy29 Maintainer
    Instead of recreating the shape with modified texture position, why not create a single shape, slightly larger, and change its position and clip region on each frame ? Would be much more efficient, I think.

    Likes: totebo

    +1 -1 (+1 / -0 )Share on Facebook
  • n1cken1cke Maintainer
    function newBackground(texture, width, height, hspeed, vspeed, xpos, ypos)
    	local bg = Mesh.new()
     
    	bg:setIndexArray(1, 2, 3, 1, 3, 4)
    	bg:setTexture(texture)
     
    	local w = width or application:getDeviceWidth()
    	local h = height or application:getDeviceHeight()
    	local dx = hspeed or 0
    	local dy = vspeed or 0
    	local x = xpos or 0
    	local y = ypos or 0
     
    	bg:addEventListener(Event.ENTER_FRAME, function()
    		x = x - dx
    		y = y - dy
    		bg:setVertices(1,0,0, 2,w,0, 3,w,h, 4,0,h)
    		bg:setTextureCoordinates(1, x, y, 2, x+w, y, 3, x+w, y+h, 4, x, y+h)
    	end)
     
    	return bg
    end
     
    local texture = Texture.new("background.png", true, {wrap = Texture.REPEAT})
    local background = newBackground(texture, nil, nil, 1, 1, 32, 32)
    stage:addChild(background)

    Likes: antix, hgy29

    +1 -1 (+2 / -0 )Share on Facebook
  • @n1cke, do you know if the method you use to update a mesh is faster than using a Bitmap and modifying it's TextureRegion?
  • I think that everything underneath is Mesh, so Mesh should be the fastest at least because there is no abstraction over it :)

    Likes: antix

    +1 -1 (+1 / -0 )Share on Facebook
  • @ar2sawseen cool, thanks. I suppose I'll start converting all my Bitmap ode to meshes :)

    Likes: n1cke

    +1 -1 (+1 / -0 )Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    edited August 2016
    You may only need to set the vertices once (so bg:setVertices(1,0,0, 2,w,0, 3,w,h, 4,0,h) may not need to be in the event listener, but could be in the init instead) - every line counts!

    Plus maybe have the scroll in your main event listener rather than in it's own - events are a killer!

    Likes: antix

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • n1cken1cke Maintainer
    > I suppose I'll start converting all my Bitmap ode to meshes :)
    @antix: Bitmap is 10% faster than textured mesh in my synthetic tests. However I like textured mesh features. Would be nice to add `setTexturePosition`, `setDimensions` and `setColor` (if you don't use a texture) methods to Bitmap i.e. mix-in Pixel class methods to make it flexible.
    > You may only need to set the vertices once
    @SinisterSoft: You are right, it affects performance a little. I wanted to show that you can also dynamically modify background width and height i.e. clip it. Useful for roll/unroll animation effects. You can safely move it if you don't need it.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • Just being picky but it seems that you can move the setVertices call outside of the main loop and everything still scrolls.
  • Ahh @SinisterSoft beat me to it!! :)

    @n1cke cool, I'll revert my changes right away :D

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • jdbcjdbc Member
    Use background.lua file from my Arkamania game.
    lua
    lua
    background.lua
    0B
  • @jdbc the file is not present :(
  • jdbcjdbc Member
    edited August 2016
    @jdbc the file is not present :(
    I was using now a Bitmap and a scrolling function.
     
    function MenuScene:init()
     
    ...
     
            local bg = Bitmap.new(MenuScene.texture_bg)
    	bg:setPosition(-30, -45)
    	self.bg = bg
    	self:addChild(bg)
    ...
     
    end
     
    -- Scrolling background
    function MenuScene:scroll_background()
    	local bg = self.bg
     
    	if (bg) then
     
    		local text = bg.text
     
    		if (self.bg_right) then
    			bg:setX(bg:getX() - 0.5)
    		else	
    			bg:setX(bg:getX() + 0.5)
    		end
     
    		if (bg:getX() + bg:getWidth() <= width + 30 ) then
    			self.bg_right = false
    		elseif (bg:getX() == -30) then
    			self.bg_right = true
    		end
    	end
     end
  • @jdbc Thanks, I think though that changing the TextureRegion is a bit more efficient :)
Sign In or Register to comment.