Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Scrolling & box2D — Gideros Forum

Scrolling & box2D

Tom2012Tom2012 Guru
edited January 2013 in General questions
Hey everyone

In my current game, I've been scrolling the physics world.

The problem is that this produces some odd visual effects and after researching it, I've read you should not scroll the box2D world but instead adjust the camera view.

I'm trying to get my head around scrolling without scrolling the box2D world... if that makes sense :D

Thanks

Tom

Comments

  • I had exactly same confusion
    http://www.giderosmobile.com/forum/discussion/729/moving-screen-in-box2d-world#Item_21

    So this might help
    http://appcodingeasy.com/Gideros-Mobile/Gideros-Camera-Move

    Basically you need to move the scene (by changing it's positions) because all objects inside scene are relative to scene's anchor point and not scene position, thus they will equal box2d coordinates. If that makes any sense ;)

    Likes: Tom2012

    +1 -1 (+1 / -0 )Share on Facebook
  • Thanks ar2rsawseen

    I'll research into those links now

    :D
  • So on this part:

    self:setX(offsetX)

    self would be the sprite that is the scene? So everything is added as a child of the scene, and then the entire scene is scrolled?

    Thanks
  • Tom2012Tom2012 Guru
    edited January 2013
    OK so silly question:

    If you're scrolling the entire scene, how do you not scroll certain elements - such as the HUD?

    My logic was to create a 'physics layer' as a child of the scene, and scroll that. But that's different to your idea - and your's works! :D
  • evsevs Member
    Hello,

    I suppose you would add all scrolling elements to a sprite (scroller) and all static elements to a sprite (hud) then add these to the stage and only do self:setX(offsetX) on the scroller


    cheers

    evs
  • Ah, I've recreated the problem I'm having with your example too:

    If I change the mouseDown part to:
    	-- create a mouse joint on mouse down
    	function self:onMouseDown(event)
     
    		if(self.direction=="left") then
    			self.ball.body:setLinearVelocity(5,0)
    			self.direction = "right"
    		else
    			self.ball.body:setLinearVelocity(-5,0)
    			self.direction = "left"
    		end
    	end
    The ball makes an ugly 'jolt' to the left or right when the click happens.

    I think this is because the ball is moving and then the world is being scrolled on that frame too. Can you reproduce this problem?

    Thanks!
  • I've attached an example. :D
    zip
    zip
    Example.zip
    42K
  • Aha! If you move the code that works out and sets the offset to after the for loop that updates the sprites, it works fine.

    Example attached.
    zip
    zip
    Archive.zip
    42K

    Likes: Yan

    +1 -1 (+1 / -0 )Share on Facebook
  • Tom2012Tom2012 Guru
    edited January 2013
    Ah this works beautifully now - thanks ar2rsawseen

    Here's the Camera class I'm using for my box2D world.
    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
     
    	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
     
    	--apply offset so scene
    	self.scene.physicsLayer:setX(offsetX)
     
    	--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:setY(offsetY)
     
    end
    NOTES
    ==============

    - physicsLayer contains my physics world
    - I manually set self.worldWidth and height at the start of each Level scene
    - I run the update part from the enterFrame loop that updates the physics world
    - AFTER the for loop...
    function Box2d:onEnterFrame() 
     
    if(not self.scene.paused and not self.scene.gameEnded) then
     
    -- edit the step values if required. These are good defaults!
    self.scene.world:step(1/60, 8, 3)
     
    --print("#self.scene.spritesOnScreen: ", #self.scene.spritesOnScreen)
     
    for i,v in pairs(self.scene.spritesOnScreen) do
     
    	local sprite = v;
     
    	local body = sprite.body
     
    		if(not body.destroyed) then
     
    			if(not(body.disabled)) then -- if we haven't disabled physics
    				local bodyX, bodyY = body:getPosition()
    				sprite:setPosition(bodyX, bodyY)
    				sprite:setRotation(body:getAngle() * 180 / math.pi)
    			end
    		else
    			-- the body has been removed, we dont need this sprite in the table any more
    			table.remove(self.scene.spritesOnScreen,i)
    		end
     
    	end
     
    end
     
    	-- Update camera
    	self.scene.camera:update()
     
    end
    end

    Likes: ar2rsawseen

    +1 -1 (+1 / -0 )Share on Facebook
  • Hi,
    This code is great, but I was wondering if someone could help me. I am trying to setup a mousejoint on the ball so I can drag it around the screen instead.
    This works ok until the scroll the screen and it goes horribly wrong.

    any ideas?

    http://appcodingeasy.com/Gideros-Mobile/Gideros-Camera-Move
  • john26john26 Maintainer
    I haven't read all the above but I would say the basic rule is "don't scroll the box2d world". Instead position sprites at shifted positions relative to the body coordinates depending on how far along you have scrolled. Sprites and bodies are separate in Gideros so its up to you where you actually draw the sprites. You should not disturb the Box2d world just because you are scrolling. These commands should almost never be used: body:setPosition(), body:setAngle().
Sign In or Register to comment.