Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Hmm why doesnt this work? — Gideros Forum

Hmm why doesnt this work?

Tom2012Tom2012 Guru
edited October 2012 in General questions
Trying to make a class that spawns a caveman with animation and physics.

All works fine, except the physics body is not attaching to the sprite.

Any ideas please?
Caveman = Core.class(Sprite);
 
-- Do on load
 
function Caveman:init(scene,atlas)
 
local animLoader = CTNTAnimatorLoader.new()
animLoader:loadAnimations("Animations/atlas-2-animation.tan", atlas, true)
local caveman = CTNTAnimator.new(animLoader)
caveman:setAnimation("CAVEMAN_FALLING")
 
 
caveman:addToParent(caveman)
 
caveman:playAnimation()
 
local body = scene.world:createBody{type = b2.DYNAMIC_BODY}
body:setPosition(caveman:getX(), caveman:getY());
body:setAngle(caveman:getRotation() * math.pi/180);
local poly = b2.PolygonShape.new()
poly:setAsBox((caveman:getWidth()/2)-10,10,0,4,0)
local fixture = body:createFixture{shape = poly, density = 1.0, friction = 0.1, restitution = 0.2}
local filterData = {categoryBits = 2, maskBits = 1};
fixture:setFilterData(filterData);
 
caveman.body = body
 
self:addChild(caveman)
 
 
 
--caveman.body.type = "caveman";
 
 
self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
 
end

Comments

  • bowerandybowerandy Guru
    edited October 2012
    @Tom2012, you don't show what you've got in your onEnterFrame() method.

    By default, Gideros doesn't keep any real links between physics bodies and their associated sprites. You have to do this yourself.

    Take a look at how the Sleeping Bodies example does it. You'll see that there is a global ENTER_FRAME handler that steps the physics world on by 1/60 sec. This will move the physics bodies to their new locations. However, at this point the sprites are still where they were before. What the example does is to keep another table called "actors" that has a mapping back from physics body to sprite. The ENTER_FRAME handler goes through all the bodies in the actors table and updates the position of the equivalent sprite to match.

    That is one way to do it. An alternative might be to use @ar2rsawseen's new GiderosInit library. See this thread. I haven't really used this part of it but the example program seems to show an easier way to use physics where the bodies and sprites are automatically tied together.

    best regards

    Likes: Tom2012

    +1 -1 (+1 / -0 )Share on Facebook
  • Tom2012Tom2012 Guru
    edited October 2012
    Hello,

    Thanks for the reply ;-)

    I've actually got the method that updates all the box 2D bodies each frame. The physics body falls away by itself while the sprite remains at the top of the screen.

    If I take the code from the class and place it on the scene, it works fine. I've got something wrong with the child / parent I think?
    1.png
    347 x 524 - 200K
    1.png 200.5K
  • are u calling Caveman:new() from scene1 and there is a enterframe event to change the position of physics body over there in that case it can happen as you have not given physics body to right instance ?

    if my guess is true then try this in scene.lua
    local caveman = Caveman:new()
    local body = scene.world:createBody{type = b2.DYNAMIC_BODY}
    body:setPosition(caveman:getX(), caveman:getY());
    body:setAngle(caveman:getRotation() * math.pi/180);
    local poly = b2.PolygonShape.new()
    poly:setAsBox((caveman:getWidth()/2)-10,10,0,4,0)
    local fixture = body:createFixture{shape = poly, density = 1.0, friction = 0.1, restitution = 0.2}
    local filterData = {categoryBits = 2, maskBits = 1};
    fixture:setFilterData(filterData);
     
    caveman.body = body
     
     
    ps i have just copy and pasted the code and havent tried that 
     
    <img class="emoji" src="http://forum.gideros.rocks/resources/emoji/smile.png" title=":)" alt=":)" height="20" />

    Likes: Tom2012

    +1 -1 (+1 / -0 )Share on Facebook
  • Tom2012Tom2012 Guru
    edited October 2012
  • Tom2012Tom2012 Guru
    edited October 2012
    Think Ive figured it out...

    If anyone in the future wants to use TNT animator and physics, in a class that spawns sprites, here's my code.

    The scene:
    level1 = Core.class(Sprite)
    function level1:init()
     
    -- Physics
     
    -- Setup box2D world
    self.world = b2.World.new(0, 10, true)
     
    -- Variables
     
    local secondsLeft = 45;
     
    -- Bring in atlases
     
    local Atlas2 = TexturePack.new("Atlases/Atlas 2.txt", "Atlases/Atlas 2.png");
     
    -- Get images from atlas
     
    local bg3 = Bitmap.new(Atlas2:getTextureRegion("bg3.png"));
    local bg2 = Bitmap.new(Atlas2:getTextureRegion("bg2.png"));
    local bg1 = Bitmap.new(Atlas2:getTextureRegion("bg1.png"));
    local ground = Bitmap.new(Atlas2:getTextureRegion("ground.png"));
     
     
     
    local clock = Bitmap.new(Atlas2:getTextureRegion("clock.png"));
     
    -- Anchor points
     
    bg3:setAnchorPoint(0.5,0);
    bg2:setAnchorPoint(0.5,0);
    bg1:setAnchorPoint(0.5,0);
    ground:setAnchorPoint(0.5,0.5);
    clock:setAnchorPoint(0.5,0.5);
     
    -- Add to screen
     
    self:addChild(bg3);
    self:addChild(bg2);
    self:addChild(bg1);
    self:addChild(ground);
    self:addChild(clock);
     
     
     
     
    -- Allign
     
    bg3:setPosition(application:getContentWidth()/2, 0);
    bg2:setPosition(application:getContentWidth()/2, 164);
    ground:setPosition(application:getContentWidth()/2, 432);
    bg1:setPosition(application:getContentWidth()/2, 160);
    clock:setPosition(220,35);
     
    -- Setup ground
     
    -- Create box2D body
     
    local body = self.world:createBody{type = b2.STATIC_BODY}
    body:setPosition(ground:getX(), ground:getY());
    body:setAngle(ground:getRotation() * math.pi/180);
    local poly = b2.PolygonShape.new()
    poly:setAsBox(ground:getWidth()/2,30,0,20,0)
    local fixture = body:createFixture{shape = poly, density = 1.0, friction = 0.1, restitution = 0.2}
    ground.body = body
    local filterData = {categoryBits = 1, maskBits = 2};
    fixture:setFilterData(filterData);
     
    -- Setup sounds
     
    --------------------------------------------------
    -- Setup countdown
    --------------------------------------------------
     
    -- Create text
     
    local font = BMFont.new("Fonts/hairy-monster.fnt", "Fonts/hairy-monster.png");
    local secondsText = BMTextField.new(font, tostring(secondsLeft));
    self:addChild(secondsText);
    secondsText:setPosition(250,16);
     
    -- Timer
    local countDown = Timer.new(1000);
     
    local function reduceTime()
    secondsLeft = secondsLeft -1;
    secondsText:setText(tostring(secondsLeft));
    end
    a
    countDown:addEventListener(Event.TIMER, reduceTime);
    countDown:start();
     
     
     
     
    --------------------------------------------------
    -- Spawn Caveman Section
    --------------------------------------------------
     
    local function spawnCaveman()
     
    local caveman = Caveman.new(self,Atlas2);
    self:addChild(caveman);
     
    local debugDraw = b2.DebugDraw.new()
    self.world:setDebugDraw(debugDraw)
    self:addChild(debugDraw)
     
    end
     
     
    --temp
     
    spawnCaveman();
     
    -- Create a function to decice whether to spawn or not
     
    local timeBetween = 0;
    local minTimeBetween = 2000;
    local maxTimeBetween = 5000;
     
    local function spawnTimer()
    timeBetween = timeBetween + 100;
    print(timeBetween);
     
    -- over minimum time, decide whether to spawn or not
    if(timeBetween > minTimeBetween) then
    if(math.random(1,8) == 3) then
    timeBetween = 0;
    spawnCaveman()
    end
    end
     
    -- gone over max time, spawn and reset counter
    if(timeBetween >= maxTimeBetween) then
    timeBetween = 0;
    spawnCaveman()
    end
     
    end
     
    local cavemanTimer = Timer.new(100);
    cavemanTimer:addEventListener(Event.TIMER, spawnTimer);
    cavemanTimer:start();
     
     
    -- Function to update box2D world each frame
     
    local function onEnterFrame() 
     
    -- edit the step values if required. These are good defaults!
    self.world:step(1/60, 8, 3)
     
    for i = 1, self:getNumChildren() do
    local sprite = self:getChildAt(i)
    if sprite.body then
    local body = sprite.body
    local bodyX, bodyY = body:getPosition()
    sprite:setPosition(bodyX, bodyY)
    sprite:setRotation(body:getAngle() * 180 / math.pi)
    end
    end
    end
     
    --run world
    self:addEventListener(Event.ENTER_FRAME, onEnterFrame)
     
     
    -- end of sceneManager stuff
     
    end
    And the class is:
    Caveman = Core.class(Sprite);
     
    -- Do on load
     
    function Caveman:init(scene,atlas)
     
    --local atlas2 = TexturePack.new("Atlases/Atlas 2.txt", "Atlases/Atlas 2.png")
     
    local animLoader = CTNTAnimatorLoader.new()
    animLoader:loadAnimations("Animations/atlas-2-animation.tan", atlas, true)
    local caveman = CTNTAnimator.new(animLoader)
    caveman:setAnimation("CAVEMAN_FALLING")
    caveman:addToParent(caveman)
    caveman:playAnimation()
     
    self:addChild(caveman)
     
    local body = scene.world:createBody{type = b2.DYNAMIC_BODY}
    body:setPosition(self:getX(), self:getY());
    body:setAngle(self:getRotation() * math.pi/180);
    local poly = b2.PolygonShape.new()
    poly:setAsBox((self:getWidth()/2)-10,10,0,4,0)
    local fixture = body:createFixture{shape = poly, density = 1.0, friction = 0.1, restitution = 0.2}
    local filterData = {categoryBits = 2, maskBits = 1};
    fixture:setFilterData(filterData);
    self.body = body
     
    self.body:setPosition(math.random(0,320), 10);
     
    self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
     
    end
     
    function Caveman:onEnterFrame(event)
     
    -- Do on enterFrame
     
    --[[
    if(self:getY() > 300) then
     
    self:getParent().world:destroyBody(self.body) -- destroy physics body
     
    self:removeEventListener(Event.ENTER_FRAME, self.onEnterFrame, self) -- remove event listener
     
    self:getParent():removeChild(self); -- finally, remove sprite
     
    end
    --]]
    end
     
     
    -- Some other function
     
    function Caveman:SpawnCaveman(atlas,scene,x,y)
     
    end
    Thank you!
Sign In or Register to comment.