Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Moving screen in Box2d world — Gideros Forum

Moving screen in Box2d world

ar2rsawseenar2rsawseen Maintainer
edited March 2012 in General questions
Hello,
have a prototype for the app, and just wanted to consult you folks before getting any further in wrong direction.
So let's say I have a large, predefined, generated box2d world, that is larger than visible screen. And I have a main character (which is a dynamic body) walking, running, jumping in this box2d world, interacting with it's objects, etc.

So what would be the best way to move the screen through box2d world, so it follows the character.

In simple game (without box2d), I'd simply leave character at constant position and move all the world by adding all world elements to one sprite and moving this sprite.

But in box2d world, this dynamic body moves with it's own forces, you can't restrict him to one position, only need to move screen as camera.

So unless I'm not missing any possible feature, the first solution that comes to mind, is to store global x and y offsets and apply them when positioning sprites according to box2d bodies, which would mean that sprites are actually elsewhere, not where the bodies are. Can't imagen if it would work or not right now, but still seems to be kind of a pain to implement and not sure if it is the right solution.

So want to hear your thoughts. Anyone?

Likes: pmanna, fxone, Yan

+1 -1 (+3 / -0 )Share on Facebook

Comments

  • I'm facing the same issue in these days, with an additional requirement: the world could be MUCH larger than the screen, so it would be better to add/remove bodies/sprites on a as-needed basis to avoid overloading the code with objects that are too far away to have any influence on the game.
    I'm still experimenting, so I don't have an answer right now: would certainly be interesting to know what the best practice is!
  • Yet another person struggling with the same issue. Was beginning to think of not using box 2d for now unless a solution can be thought of.

    Mike
    What would you do for your other half?

    http://www.sharksoupstudios.com
  • ar2rsawseenar2rsawseen Maintainer
    Found something like this: http://www.emanueleferonato.com/2010/04/29/following-a-body-with-the-camera-in-box2d/
    and this: http://www.emanueleferonato.com/2010/05/04/following-a-body-with-the-camera-in-box2d-the-smart-way/

    But either due to lack of my ActioncScript knowledge or error in example, I can't seem to figure out what he does with x and y variables, which are calculated in the bottom of update function
  • @mykyl66 I've indeed avoided box2d when it turned out to be too much of a pain to adapt to its quirks than just doing simple things myself, and I'll do it again.
    However, there are requirements for interactions so complex that physics can definitely help: in those cases, knowing where to look at (and especially what to avoid) would help!
  • ar2rsawseenar2rsawseen Maintainer
    Ok it seems it is much easier than I thought, as box2d object are positioned relatively to world and not to sprite (which I kind of misinterpreted before), meaning we can easily position scene according to object, and all elements inside (sprites representing bodies) will be positioned according to bodies position inside the world.
    Let me built something to proof the concept.

    Likes: atilim

    +1 -1 (+1 / -0 )Share on Facebook
  • atilimatilim Maintainer
    On the other hand, rendering a much larger world than the screen will have performance issues. Currently the only way is dividing the world into some pieces (e.g. about the size of the screen) and adding only the visible parts.

    I know this can be really complicated but we're also working on efficient culling of off-screen sprites.
  • ar2rsawseenar2rsawseen Maintainer
    edited March 2012
    Here is an idea on implementation part.
    Inactive bodies does not participate in calculations, thus meaning they will consume lesser resources.

    So how about create boundary of sensors around screen and move these boundaries together with screen, and on collision with object, activate and deactivate bodies.

    Activate the ones that go inside and deactive the ones that go outside the screen. I think it could be comparably easier to implement, but would that provide enough optimization?

    Edited: Yes of course if only inactive bodies received collisions :))
  • This wouldn't solve the issue @atilim was talking about, i.e. sprites off screen still affect performance right now.
    IMO, if you need to add and remove sprites while the game proceeds, then it's worth to add and remove related bodies as well: maybe not exactly on screen boundaries, as you probably want to give the impression that "something" is happening while you get there, but certainly when they're too far to have any influence on the game.
  • ZoytZoyt Member
    edited March 2012
    I'm having the same problem with wanting to make a jumping game with physics. I prefer physics than done manually.
  • atilimatilim Maintainer
    edited March 2012
    @ar2rsawseen If I understand you correctly, Box2D does have a similar optimization already: When Box2D determines that a body (or group of bodies) has come to rest, the body enters a sleep state which has very little CPU overhead.

    Even if you have a large number of bodies (e.g. outside of the screen) and many of them are sleeping then Box2D handles this case very well.
  • ar2rsawseenar2rsawseen Maintainer
    edited March 2012
    Ok about a moving camera, here is an example: http://appcodingeasy.com/Gideros-Mobile/Gideros-Camera-Move

    About optimization, would it be possible to set some sort of callback, when body starts to sleep, to remove representing sprite?

    World I'm creating is too small to bother this kind of optimization, but still it would be interesting to see a viable solution
  • Yet another person struggling with the same issue. Was beginning to think of not using box 2d for now unless a solution can be thought of.

    Mike
    Did you try what I had suggested to you several days ago on Skype? Moving the stage with a negative X offset by the players global X position?
  • @ar2rsawseen, good example, that was quick!

    I like @MikeHart's approach since it doesn't require you to change how you draw your physics objects. I'd like someone to develop a small camera class based on this idea ... I've tried it myself but my small attempts so far have ended in frustration. I (think) I want something like:
    camera = Camera.new{ sprite=worldSprite,  rotation=..., scale=..., etc.}
    -- create physics world as you normally would, with worldSprite as the parent
    Other functions:
    camera:move(x,y)
    camera:rotate(angle)
    camera:follow(body)
    camera:unfollow()
    camera:zoom(scale)
    In the event update function:
    camera:update() 
    -- draw physics objects as you would normally
    The code I've used for my "camera:update()" function:
    function Camera:update()
        if self.body then -- if we're following something, update camera position
            local x,y = self.body:getPosition()
            self.sprite:setPosition(-x+self.viewportWidth/2, -y+self.viewportHeight/2)
            --  most of the time, self.viewportWidth = application:getContentWidth()
            --  doesn't do the nice bounds checking that <a href="https://forum.gideros.rocks/profile/ar2rsawseen" rel="nofollow">@ar2rsawseen</a> has in his example
        end
    end
  • Yet another person struggling with the same issue. Was beginning to think of not using box 2d for now unless a solution can be thought of.

    Mike
    Did you try what I had suggested to you several days ago on Skype? Moving the stage with a negative X offset by the players global X position?
    I completely forgot. Kids and constant illness kind of helps the mind lose track of things. :D

    Mike

    What would you do for your other half?

    http://www.sharksoupstudios.com
  • ar2rsawseenar2rsawseen Maintainer
    @ndoss my example does practically what @MikeHart wrote, I do not modify box2d object positions, they are still the same. I'm only moving the scene and that's it.
  • I agree that you achieve the same effect, I just like the separation of concerns that his approach enables. in your method, the drawing code has to be modified. In his, it doesn't.
  • PramodPramod Member
    edited November 2012
    I had the same problem and here is my solution,
    place the movie clips in a sprite and re position the sprite.(see the source file)

    swf
    swf
    LandRover.swf
    171K
    txt
    txt
    LandRover.txt
    10K
  • Box 2D is running in global coordinates. Just move the stage after your main character's body. I do this with players ship. I even implemented layer parallax. Its really really easy and from yesterdays tests some specs: Ipod 4th gen retina 1 core 800Mhz : ~20 static bodies, something like 150 dynamic bodies or more /30 ships and all missiles and cannonballs/, activate/deactivate body state gives huge optimization, 4kx4k cloud map sprite. @Atilim: great job, steady 30fps i can post new video but still cant beat first complete level i made. Can't believe how fast this framework runs.
  • The only problem I see with this is utilizing the Debug drawing. I can move the stage (EaselJS terms) relative to the position of the body, but I don't want to have to move every one of my Body's individually with a global offset. Is there a clear way I can assign my Bodys to a global Sprite in Box2d, and then just offset that by the appropriate amount (So I can see my Debug Drawings say 2000 pixels away?
  • Tommy. Use a Sprite container, and then play with the offsetY and offsetX, realign based on where your centre will be. guessed you already solved it, seeing this was a year ago.
    REAL programmers type copy con filename.exe
    ---------------------------------------
Sign In or Register to comment.