Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Box2dEasy not working as expected — Gideros Forum

Box2dEasy not working as expected

bayopbayop Member
edited July 2013 in Game & application design
I'm still a bit new to Gideros, but I've been playing around with some of the libraries and now I'm trying to integrate physics into a game using Box2dEasy, but having some problems.

When I start the simulation, my physics enabled sprite just moves to the top left hand corner of the screen and goes out of view. I'm not applying any force on it and box2d gravity have been set to zero. I even setup some debug print messages and found that the sprite's velocity (linear and angular) were not changing. However, the body was still moving. The code for object initialization and world updates is reproduced below;

Initializing the game scene (Using sceneManager)
require "box2d"
 
gameScn =  Core.class(Sprite)
 
local car
local world = {}
 
function gameScn:init(level_id)
   ...
  world = b2.World.new(0, 0, true)
  ....
  car = Car.new()	
  ...
  world:createRectangle(car, {type = "dynamic" })
  ...
  self:addChild(car)
  ...
  self:addEventListener(Event.ENTER_FRAME,self.onEnterFrame, self)
end
updating the game scene
function gameScn:onEnterFrame(event) 	
   world:update()
end
Car sprite initialization
Danfo = Core.class(Sprite)
 
function Car:init() 
	local pack = TexturePack.new(getImgBase() .. "vehicles.txt",getImgBase() .. "vehicles.png")
 
	self.anim = {
		Bitmap.new(pack:getTextureRegion("danfo_up"), true),
		Bitmap.new(pack:getTextureRegion("danfo_cond1"), true),
		Bitmap.new(pack:getTextureRegion("danfo_cond2"), true),
		Bitmap.new(pack:getTextureRegion("danfo_crash"), true),
	}
	self.yOffset = 400;
	self:setAnchorPoint(0,0)
	self.frame = 1
	self:addChild(self.anim[1])
	self:setX(Utils.LANE_ONE)
	self:setY(self.yOffset)
 
 
	self.nframes = #self.anim
end
Does anybody have an idea of what I could be doing wrong. I initially thought that there was a difference in my sprite and attached physics body positioning which was causing this movement everytime the world:update() function was called, but when I look at the debug statements both values initially start off at the same point (save rounding errors).

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Hi @bayop ;)
    well thats interesting.
    1) you can add self:addChild(world:getDebug()) in your gameScn you could see where actually physics body is
    2) Box2DEasy and physics in all should require (and in Box2DEasy case I think even reset) anchor points to 0.5, 0.5 to match physics bodies position, maybe that is causing the problem?
  • bayopbayop Member
    Maybe it has something to do with that, I try the debug mode and see how it goes. Thanks
  • bayopbayop Member
    @ar2rsawseen

    Thanks for the tip, I eventually found where the problem was coming from, but I don't know if my fix will cause more problems somewhere else. Here's a quick explanation;

    Firstly, I created a sprite and included physics properties using the Box2DEasy module's create Rectangle Method. Note that on line 373, the sprite's anchor point is set to 0.5, after which body position is set using setPosition (For physics bodies this is usually, the body's center point).
    		if object then
    			if getmetatable(object) ~= MovieClip then
    				object:setAnchorPoint(0.5, 0.5)
    			end
    			body:setPosition(object:getX(), object:getY())
    			body:setAngle(math.rad(angle))
    			object.body = body
    			body.object = object
    			if conf.type == "dynamic" and conf.draggable then
    				self:makeDraggable(object)
    			end
    			object:setRotation(angle)
    			self:__enchanceObject(object)
    		end
    In my game screen module, I added an ENTER FRAME listener and this called b2.World.update() on every time-step. In that method, after the World step function is called, the sprites are updated with the physical properties of their respective body objects;
    			if sprite.body then
    				--update position to match box2d world object's position
    				--get physical body reference
    				local body = sprite.body
    				--get body coordinates
    				local bodyX, bodyY = body:getPosition()
    				--apply coordinates to sprite
    				sprite:setPosition(bodyX, bodyY)
    				--apply rotation to sprite
    				sprite:setRotation(math.deg(body:getAngle()))
    			end
    The problem was actually from the Sprite:setPosition function in the GiderosCodingEasy module. from line 494
    			if self._offX then
    				value = value + self._offX
    			end
    			value = math.round(value)
    			if self.body then
    				local x,y = self.body:getPosition()
    				self.body:setPosition(value, y)
    			end
    Put very simply, every time the sprite's position in modified world:update(). The sprite's setPosition function (from GiderosCodingEasy) also modifies the attached physics body's position. However, this update includes the _offX and -offY offset values (used to modify the standard behaviour of setPosition for sprites). This results in the physics body's position being out of sync with the actual sprite position (Since it's own setPosition function automatically uses centre as reference point).


    What baffles me is why this does not cause problems in the demo app included in the library. Thanks for the assist though.
  • ar2rsawseenar2rsawseen Maintainer
    @bayop neat
    it will produce a bug only on Sprite inherited objects with none 0 anchorpoints, that is why it did not happen before.
    Nice, let me think of a fix for this ;)
  • bayopbayop Member
    I think there's a simple fix for this though, just set the value of the physics body before applying the offset
  • Apologies for resurrecting this thread, but I just wanted to note that the version of GiderosCodingEasy at github still has this bug, which I stumbled upon independently. My solution is the same as bayop's -- I modifed the Sprite:setPosition function to set the physics body's position before applying the offset.
  • @Alsacefan no worries, that was a great reminder. Updating repo now ;)
Sign In or Register to comment.