Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Class with physics entity — Gideros Forum

Class with physics entity

burak76burak76 Member
edited February 2014 in General questions
Hi,

I've been playing around with box2d lately. I moved a ball sprite including its physics body to it's own separate class.
For some reason now when I am updating the physics and then updating the ball graphics it needs to be relative to the original location of the ball.

Below is the partial class code of the ball
function Ball:init(colour, x, y, vx, vy, world)
 
	self.world = world
	local filename = ballzFilename[colour]
 
	-- Create ball bitmap object from ball graphic
        local ball = Bitmap.new(Texture.new(filename, true))
 
        -- Reference center of the ball for positioning
        ball:setAnchorPoint(0.5, 0.5)
        ball:setPosition(x, y)
	ball:setScale(2.0) 
 
         -- Create box2d physical object
	local radius = ball:getWidth() / 2
        local body = self.world:createBody{type = b2.DYNAMIC_BODY,
									   fixedRotation = false	
									  }
    body:setPosition(ball:getX(), ball:getY())
    body:setAngle(ball:getRotation() * math.pi/180)
    local circle = b2.CircleShape.new(0, 0, radius)
    local fixture = body:createFixture{shape = circle, density = 1.0, 
									  friction = 0.0, restitution = 0.2}
 
	body:setLinearVelocity(vx, vy)
 
	local torqueDirection = -1
	if math.random() > 0.5 then
		torqueDirection = 1
	end
 
	body:applyTorque(-100 * torqueDirection)
 
	body.type = "ball"
 
 
	body.origx = x
	body.origy = y
	self.body = body
 
 
	self:addChild(ball)	
 
	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
	self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
	self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)
end
This the update code used in the game play module:
function GameScreen:onEnterFrame(event)
	--
	-- Physics
    self.world:step(1/60, 8, 3)
 
    -- Iterate through all child sprites
    for i = 1, self:getNumChildren() do
 
		-- Get specific sprite
        local sprite = self:getChildAt(i)
 
		-- Check if sprite HAS a body (ie, physical object reference we added)
        if sprite.body then
 
			-- Update position to match box2d world object's position
            -- Get physical body reference
            local body = sprite.body
 
			if body.type == "ball" then
 
				local bodyx, bodyy = body:getPosition()
 
                                -- HACK!!!!!!!!!!!
				-- Apply physics body coordinates to sprite
				sprite:setPosition(bodyx-body.origx, bodyy-body.origy)
 
				-- Apply rotation to sprite				
				sprite:setRotation(math.rad(body:getAngle()))
			end
        end
    end
 
end
I have to subtract the original position of the body from the current position for the sprite and physics body to line up.
The rotation is not working either.

This was working when it was not encapsulated within a class i.e. The position was not relative.

What am I missing here?

Thanks
Burak

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    @burak76
    The problem is because you have this hierachy:
    stage -> GameScreen -> Ball -> ball(Bitmap)

    So what you do, when you create ball(Bitmap) you set it at x1,y1 coordinates in Ball class coordinates
    Then in GameScreen:onEnterFrame you set Balls coordinates to x2, y2,
    thus relative to the GameScreen, you Ball object is at (x2, y2) and ball(Bitmap) inside it is at x1, y1 thus they sum

    There are two ways to handle it:

    1) don't set ball(Bitmap) coordinates at all, let it be at 0,0 and only change Ball object coordinates

    2) create Ball:update method and only update ball(Bitmap) position there, leaving Ball object always at 0,0 coordinates

    Hope that helps ;)
Sign In or Register to comment.