Author Topic: Chipmunk Physics  (Read 25379 times)

0 Members and 1 Guest are viewing this topic.

Offline Jim Bauwens

  • Lua! Nspire! Linux!
  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1881
  • Rating: +206/-7
  • Linux!
    • View Profile
    • nothing...
Chipmunk Physics
« on: July 26, 2012, 03:59:10 pm »
Hi all.

3.2 integrates the Chipmunk physics engine with Lua bindings. This allows us create fun games with the physics.
However there is just one problem. It's pretty complex.
So here is some useful info if you want to start programming.

1. The API documentation for 3.2
Download it at http://education.ti.com/nspire/scripting-api .
It's a must have in order to find all the API function names (duh :P )

2. The online chipmunk docs
http://chipmunk-physics.net/release/Chipmunk-5.x/Chipmunk-5.3.4-Docs/
Even though it describes the C API, it shows how the concepts of the engine and how it's structured.
And most Lua functions have similar names to the C ones.
You will find yourself checking this resource often when you start programming with the engine ;)

3. A tutorial (although for the C API)
http://www.alexandre-gomes.com/articles/chipmunk/
This tutorial helps you understand the concepts and inner workings of the physics engine.

4. Example code (by me)
Spoiler For Basic start:


platform.apilevel = '2.0'
require 'physics'


LARGE=physics.misc.INFINITY()
ZERO =physics.Vect(0,0)
------------------
-- Space Object --
------------------

pSpace   = class()

function pSpace:init(gravity)
   self.space = physics.Space()
         :setGravity(physics.Vect(0, gravity))
         :setSleepTimeThreshold(.5)
         
   self.objects   = {}
end

function pSpace:step(n)
   self.space:step(n)
end

function pSpace:addObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   self.space:addBody(obj.body)
   
   self.space:addShape(obj.shape)
   if obj.added then obj:added(self) end
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:addTerrainObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   --self.space:addBody(obj.body)
   
   for _, ss in ipairs(obj.segments) do
      self.space:addStaticShape(ss)
   end
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:addStaticObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   --self.space:addBody(obj.body)
   self.space:addStaticShape(obj.shape)
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:paint(gc)
   for _, obj in ipairs(self.objects) do
      obj:paint(gc)
   end
end

----------------
-- Box Object --
----------------

pBox   = class()

function pBox:init(w,h,mass,color)
   self.h=h
   self.w=w
   self.mass=mass
   self.color=color
   
   self.verts = {
      physics.Vect(-w/2, -h/2),
      physics.Vect(-w/2,  h/2),
      physics.Vect(w/2 ,  h/2),
      physics.Vect(w/2 , -h/2)
   } 
   
   self.body   = physics.Body(1, 1)
   self.body:setMass(mass)
   self.body:setMoment(physics.misc.momentForPoly(mass, self.verts, ZERO))
   self.body:setVel(ZERO)
   
   self.shape = physics.PolyShape(self.body, self.verts, ZERO)

   self.shape:setRestitution(0.6)
   self.shape:setFriction(0.6)
end

function pBox:paint(gc)
   local coords   = self.shape:points()
   local polycoords   = {}
   for k, vert in ipairs(coords) do
      table.insert(polycoords, vert:x())
      table.insert(polycoords, vert:y())
   end   
   local x,y=coords[1]:x(),coords[1]:y()
   table.insert(polycoords, x)
   table.insert(polycoords, y)           

   gc:setColorRGB(self.color)
   gc:fillPolygon(polycoords)
   gc:setColorRGB(0,0,0)
   gc:drawPolyLine(polycoords)
end


-----------------
-- Ball Object --
-----------------

pBall   = class()

function pBall:init(r,mass,color)
   self.r=r
   self.mass=mass
   self.color=color
   
   self.body   = physics.Body(1, 1)
   self.body:setMass(mass)
   self.body:setMoment(physics.misc.momentForCircle(mass, 0, r, ZERO))
   self.body:setVel(ZERO)
   
   self.shape = physics.CircleShape(self.body, r, ZERO)

   self.shape:setRestitution(0.6)
   self.shape:setFriction(0.6)
   --[[
   self.segment = physics.SegmentShape(self.body, physics.Vect(0,-r), physics.Vect(0,0), 1)
    self.segment:setRestitution(0)
   self.segment:setFriction(0)
   --]]
end

function pBall:added(spaceObj)
   --spaceObj.space:addShape(self.segment)
end

function pBall:paint(gc)
   local pos=self.body:pos()
   local x, y = pos:x(), pos:y()
    local r = self.r
         
    gc:setColorRGB(self.color)                           
    gc:fillArc(x-r, y-r, 2*r+1, 2*r+1, 0, 360)
    gc:setColorRGB(0)
    gc:drawArc(x-r, y-r, 2*r, 2*r, 0, 360)
   
    local x2,y2
    local angle=self.body:angle()
    x2   = math.cos(angle)*self.r+x
    y2   = math.sin(angle)*self.r+y
    gc:drawLine(x,y,x2,y2)
end



------------------
-- Terrain code --
------------------

function getMidPoint(line)
    local xdif    = math.abs(line[3]-line[1])
    local ydif    = math.abs(line[4]-line[2])
    local x    = math.min(line[3], line[1]) + xdif/2
    local y    = math.min(line[4], line[2]) + ydif/2
    return x, y
end

function terrain(bline, range, roughness, tms)
    local lines    = {bline}
    local lines2    = {}

    local midX, midY

    for times=1, tms do
        for index, line in pairs(lines) do
            midX, midY    = getMidPoint(line)
            midY    = midY + math.random(-range, range)

            table.insert(lines2, {line[1], line[2], midX, midY})
            table.insert(lines2, {midX, midY, line[3], line[4]})
        end
        lines    = lines2
        lines2    = {}
        range    = range * (roughness*2^-roughness)
    end

    return lines
end

------------------------
-- Terrain to physics --
------------------------

pTerrain   = class()

function pTerrain:init(bline, range, roughness, times)
   self.lines    = terrain(bline, range, roughness, times)
   self.segments = {}

   self.mass   = LARGE
   self.body   = physics.Body(1, 1)
   self.body:setMass(self.mass)
   
   self.inertia   = 0
   
   local a, b, ss
   for index, line in ipairs(self.lines) do
        a   = physics.Vect(line[1], line[2])
        b   = physics.Vect(line[3], line[4])
       
        self.inertia   = self.inertia + physics.misc.momentForSegment(self.mass/#self.lines, a, b)
        ss   = physics.SegmentShape(self.body, a, b, 1)
        ss:setRestitution(0)
      ss:setFriction(1)
        table.insert(self.segments, ss)
    end

   self.body:setMoment(self.inertia)
   self.body:setVel(ZERO)
   
end

function pTerrain:paint(gc)
   local a,b
    for index, ss in ipairs(self.segments) do
      a = ss:a()
      b = ss:b()
        gc:drawLine(a:x(), a:y(), b:x(), b:y())
    end
end



function on.construction()
   space   = pSpace(9. 8)
   
   timer.start(0.01)
   count=0
   
   ter   = pTerrain({0,120,318,120}, 60, 0.6, 5)
   space:addTerrainObj(ter, 0,0)
   
   ball = pBall(10, 5, 0xaaffaa)
   space:addObj(ball, 160,10)
end


function physicsUpdate()
   space:step(0.1)

   count = count + 1
   if count == 2 then
      platform.window:invalidate()
      count = 1
   end   
end

py,px=100,160

function on.paint(gc)
   space:paint(gc)
   gc:fillRect(px, py, 4, 4)
end

kaction   = {up={0,-5}, down={0,5}, left={-5,0}, right={5,0}}
function on.arrowKey(key)
   px=px+kaction[1]
   py=py+kaction[2]
end

function on.enterKey()
   local box   = pBox(20, 20, 5, math.random(2^16))
   space:addObj(box, px, py)
end

function on.timer()
   physicsUpdate()
end


Spoiler For A bit more advanced (motors/springs/etc):


platform.apilevel = '2.0'
require 'physics'


LARGE=physics.misc.INFINITY()
ZERO =physics.Vect(0,0)
------------------
-- Space Object --
------------------

pSpace   = class()

function pSpace:init(gravity)
   self.space = physics.Space()
         :setGravity(physics.Vect(0, gravity))
         :setSleepTimeThreshold(.5)
         --:resizeActiveHash(30, 500)
   self.objects   = {}
end

function pSpace:step(n)
   self.space:step(n)
end

function pSpace:addObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   self.space:addBody(obj.body)
   
   self.space:addShape(obj.shape)
   if obj.added then obj:added(self) end
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:addTerrainObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   --self.space:addBody(obj.body)
   
   for _, ss in ipairs(obj.segments) do
      self.space:addStaticShape(ss)
   end
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:addStaticObj(obj, x, y)
   obj.body:setPos(physics.Vect(x, y))
   --self.space:addBody(obj.body)
   self.space:addStaticShape(obj.shape)
   
   table.insert(self.objects, obj)
   return self
end

function pSpace:addComplexObj(obj, x, y)
   for _, childObj in ipairs(obj.objects) do
      self:addObj(childObj.obj, x+childObj.x, y+childObj.y)
   end
   
   for _, constraint in ipairs(obj.constraints) do
      self.space:addConstraint(constraint)
   end   
   
   table.insert(self.objects, obj)
   return self   
end

function pSpace:paint(gc)
   for _, obj in ipairs(self.objects) do
      obj:paint(gc)
   end
end

----------------
-- Box Object --
----------------

pBox   = class()

function pBox:init(w, h, mass, color, f, e, group)
   self.h=h
   self.w=w
   self.mass=mass
   self.color=color
   
   self.verts = {
      physics.Vect(-w/2, -h/2),
      physics.Vect(-w/2,  h/2),
      physics.Vect(w/2 ,  h/2),
      physics.Vect(w/2 , -h/2)
   } 
   
   self.body   = physics.Body(1, 1)
   self.body:setMass(mass)
   self.body:setMoment(physics.misc.momentForPoly(mass, self.verts, ZERO))
   self.body:setVel(ZERO)
   
   self.shape = physics.PolyShape(self.body, self.verts, ZERO)

   self.shape:setRestitution(e or 0.6)
   self.shape:setFriction(f or 0.6)
   
   if group then self.shape:setGroup(group) end
end

function pBox:paint(gc)
   local coords   = self.shape:points()
   local polycoords   = {}
   for k, vert in ipairs(coords) do
      table.insert(polycoords, vert:x())
      table.insert(polycoords, vert:y())
   end   
   local x,y=coords[1]:x(),coords[1]:y()
   table.insert(polycoords, x)
   table.insert(polycoords, y)           

   gc:setColorRGB(self.color)
   gc:fillPolygon(polycoords)
   gc:setColorRGB(0,0,0)
   gc:drawPolyLine(polycoords)
end


-----------------
-- Ball Object --
-----------------

pBall   = class()

function pBall:init(r,mass,color, f, e, group)
   self.r=r
   self.mass=mass
   self.color=color
   
   self.body   = physics.Body(1, 1)
   self.body:setMass(mass)
   self.body:setMoment(physics.misc.momentForCircle(mass, 0, r, ZERO))
   self.body:setVel(ZERO)
   
   self.shape = physics.CircleShape(self.body, r, ZERO)

   self.shape:setRestitution(e or 0.6)
   self.shape:setFriction(f or 0.6)
   
   if group then self.shape:setGroup(group) end
end

function pBall:paint(gc)
   local pos=self.body:pos()
   local x, y = pos:x(), pos:y()
    local r = self.r
         
    gc:setColorRGB(self.color)                           
    gc:fillArc(x-r, y-r, 2*r+1, 2*r+1, 0, 360)
    gc:setColorRGB(0)
    gc:drawArc(x-r, y-r, 2*r, 2*r, 0, 360)
   
    local x2,y2
    local angle=self.body:angle()
    x2   = math.cos(angle)*self.r+x
    y2   = math.sin(angle)*self.r+y
    gc:drawLine(x,y,x2,y2)
end





pCar   = class()

function pCar:init()
   local group   = 5
   
   local wheelR   = 5   -- wheel Radius
   local wheelM   = 5   -- wheel Mass
   local wheelF   = 0.9   -- wheel Friction
   local wheelE   = 0.0   -- wheel Elasticity
   
   local chassisM   = 10   -- Chassis Mass
   local chassisW   = 24   -- Chassis Width
   local chassisH   = 10   -- Chassis Height
   local chassisF   = 0.7   -- Chassis Friction
   local chassisE   = 0.0   -- Chassis Elasticity
   
   self.wheel1   = pBall(wheelR, wheelM, 0x55CC55, wheelF, wheelE, group)
   self.wheel2   = pBall(wheelR, wheelM+8, 0x55CC55, wheelF, wheelE, group)
   
   self.chassis   = pBox(chassisW, chassisH, chassisM, 0x5555CC, chassisF, chassisE, group)
   
   self.joint1   = physics.GrooveJoint(self.chassis.body, self.wheel1.body, physics.Vect(-10, 5), physics.Vect(-10, 25), ZERO)
   self.joint2   = physics.GrooveJoint(self.chassis.body, self.wheel2.body, physics.Vect( 10, 5), physics.Vect( 10, 25), ZERO)
   
   self.spring1   = physics.DampedSpring(self.chassis.body, self.wheel1.body, physics.Vect(-10, 0), ZERO, 17, 10, 10)
   self.spring2   = physics.DampedSpring(self.chassis.body, self.wheel2.body, physics.Vect( 10, 0), ZERO, 17, 10, 10)
   
   self.Fmotor   = physics.SimpleMotor(self.chassis.body, self.wheel2.body, 0):setMaxForce(1000)
   self.Pmotor   = physics.SimpleMotor(self.chassis.body, self.wheel2.body, 0):setMaxForce(1000)
   self.gear   = physics.GearJoint(self.wheel1.body, self.wheel2.body, 0, 1)
   
   self.objects   = {
      {obj = self.wheel1 , x = -10 ,y = 7},
      {obj = self.wheel2 , x = 10  , y = 7},
      {obj = self.chassis, x = 0 ,y = -7},
   }
   
   self.constraints   = {self.joint1, self.joint2, self.spring1, self.spring2, self.Fmotor, self.Pmotor, self.gear}   
end

function pCar:paint(gc)
   self.wheel1:paint(gc)
   self.wheel2:paint(gc)
   self.chassis:paint(gc)
end






------------------
-- Terrain code --
------------------

function getMidPoint(line)
    local xdif    = math.abs(line[3]-line[1])
    local ydif    = math.abs(line[4]-line[2])
    local x    = math.min(line[3], line[1]) + xdif/2
    local y    = math.min(line[4], line[2]) + ydif/2
    return x, y
end

function terrain(bline, range, roughness, tms)
    local lines    = {bline}
    local lines2    = {}

    local midX, midY

    for times=1, tms do
        for index, line in pairs(lines) do
            midX, midY    = getMidPoint(line)
            midY    = midY + math.random(-range, range)

            table.insert(lines2, {line[1], line[2], midX, midY})
            table.insert(lines2, {midX, midY, line[3], line[4]})
        end
        lines    = lines2
        lines2    = {}
        range    = range * (roughness*2^-roughness)
    end

    return lines
end

------------------------
-- Terrain to physics --
------------------------

pTerrain   = class()

function pTerrain:init(bline, range, roughness, times)
   self.lines    = terrain(bline, range, roughness, times)
   self.segments = {}

   self.mass   = LARGE
   self.body   = physics.Body(1, 1)
   self.body:setMass(self.mass)
   
   self.inertia   = 0
   
   local a, b, ss
   for index, line in ipairs(self.lines) do
        a   = physics.Vect(line[1], line[2])
        b   = physics.Vect(line[3], line[4])
       
        self.inertia   = self.inertia + physics.misc.momentForSegment(self.mass/#self.lines, a, b)
        ss   = physics.SegmentShape(self.body, a, b, 1)
        ss:setRestitution(0)
      ss:setFriction(1)
        table.insert(self.segments, ss)
    end

   self.body:setMoment(self.inertia)
   self.body:setVel(ZERO)
   
end

function pTerrain:paint(gc)
   local a,b
    for index, ss in ipairs(self.segments) do
      a = ss:a()
      b = ss:b()
        gc:drawLine(a:x(), a:y(), b:x(), b:y())
    end
end













function on.construction()
   space   = pSpace(9. 8)
   
   timer.start(0.02)
   count=0
   
   --[[
   floor   = pBox(300, 20, LARGE, 0xCC5555, 0.9)
   space:addStaticObj(floor, 150, 200)
   --]]
   
   ter   = pTerrain({0,120,318,120}, 60, 0.6, 5)
   space:addTerrainObj(ter, 0,0)
   
   car   = pCar()
   space:addComplexObj(car, 50, 50)
end


function on.tabKey()
   car.Pmotor:setMaxForce(10000)
   car.Pmotor:setRate(car.Pmotor:rate()-0.3)
end

function on.escapeKey()
   car.Pmotor:setMaxForce(0)
   car.Pmotor:setRate(0)   
end

function physicsUpdate()
   space:step(0.1)

   count = count + 1
   if count == 2 then
      platform.window:invalidate()
      count = 1
   end   
end

py,px=100,160

function on.paint(gc)
   local f   = math.abs(car.Pmotor:rate())
   gc:drawString("Force: " .. f, 2, 2, "top")
   space:paint(gc)
   gc:fillRect(px, py, 4, 4)
end

kaction   = {up={0,-5}, down={0,5}, left={-5,0}, right={5,0}}
function on.arrowKey(key)
   px=px+kaction[1]
   py=py+kaction[2]
end

function on.enterKey()
   local box   = pBox(20, 20, 5, math.random(2^16))
   space:addObj(box, px, py)
end

function on.timer()
   physicsUpdate()
end


I spend some time making this code, so please take care of it  ;)

5. Take a look at other exisiting activities for the TI-Nspire that use the physics engine
http://education.ti.com/calculators/tisciencenspired/US/Activities/Detail?sa=5029&id=17888

And last but not least ...
Have fun !
« Last Edit: August 12, 2016, 04:39:19 pm by Sorunome »

Offline leafy

  • CoT Emeritus
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1554
  • Rating: +475/-97
  • Seizon senryakuuuu!
    • View Profile
    • keff.me
Re: Chipmunk Physics
« Reply #1 on: July 26, 2012, 04:03:21 pm »
Wow, that's fantastic! I still find it amazing that Chipmunk can even run on a calculator, so this is all very cool stuff :D I'm more familiar with Box2D myself, but I've heard that Chipmunk is better at handling large numbers of objects, so it should be interesting to see what people can come up with.
In-progress: Graviter (...)

Offline Jim Bauwens

  • Lua! Nspire! Linux!
  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1881
  • Rating: +206/-7
  • Linux!
    • View Profile
    • nothing...
Re: Chipmunk Physics
« Reply #2 on: July 26, 2012, 04:08:13 pm »
Yeah, it's indeed a very nice addition :)

However, don't expect super complex and graphically advanced games to be possible :P
It's still a calculator, and the Lua bindings are of course a bit slower than the C one. (This is why Ndless 3.2 will be awesome :D).
But a (good functioning) Angry Birds clone should be possible.
« Last Edit: July 26, 2012, 04:08:56 pm by jimbauwens »

Offline 3rik

  • LV3 Member (Next: 100)
  • ***
  • Posts: 92
  • Rating: +8/-0
  • My TI-84+ SE
    • View Profile
Re: Chipmunk Physics
« Reply #3 on: July 26, 2012, 04:36:17 pm »
Thanks for gathering these resources!  :)


space = pSpace(9.8)

got turned into

space = pSpace(9.8)

in your code.
Userbars

Offline cyanophycean314

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 363
  • Rating: +43/-1
  • It's You!
    • View Profile
Re: Chipmunk Physics
« Reply #4 on: July 26, 2012, 05:44:40 pm »
I'm not sure if I'm going to give this a try in my programs, but it is interesting.

Thanks for gathering these resources!  :)


space = pSpace(9.8)

got turned into

space = pSpace(9.8)

in your code.


Yeah, I saw that.  8)

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
Re: Chipmunk Physics
« Reply #5 on: January 07, 2013, 06:21:53 am »
So, I looked into the documentation, and could not find any sign of liquidsimulation. Is this present in the physics lib or not?
It's sad to see that noone has made a game with it yet, someone should try this out :)

Offline Levak

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1002
  • Rating: +208/-39
    • View Profile
    • My website
Re: Chipmunk Physics
« Reply #6 on: January 07, 2013, 06:43:19 am »
So, I looked into the documentation, and could not find any sign of liquidsimulation. Is this present in the physics lib or not?
It's sad to see that noone has made a game with it yet, someone should try this out :)
It is so laggy that you could not make any complex nor simple game with it.
Adriweb, Jim and me tried the basic samples of Chipmunk demo. None of them can run smoothly on the handheld. It seems TI Enginners are only taking care of the PC version witch is a shame.
Sad to say but better recode it your own physic engine...
« Last Edit: January 07, 2013, 06:43:31 am by Levak »
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
Re: Chipmunk Physics
« Reply #7 on: January 07, 2013, 07:26:25 am »
hmm, thanks for that fast reply :)

well, that's sad indeed.. Isn't there any speed improvement with the non-physics Lua on the handheld? (I haven't upgraded, and I won't)
That might be an idea, I guess a Lua physics engine would run smoother then, but that's a massive amount of work, especially the colission detection, how do you even do that with polygons?

Offline Augs

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 306
  • Rating: +30/-29
    • View Profile
Re: Chipmunk Physics
« Reply #8 on: January 07, 2013, 02:37:14 pm »
Sounds interesting, any one have a video?

Offline ElementCoder

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 611
  • Rating: +42/-2
    • View Profile
Re: Chipmunk Physics
« Reply #9 on: January 08, 2013, 10:55:21 am »
@Nick My eat nethams game seems to run somewhat faster on 3.2 than it did on 3.1. The lobsters definitely fall smoother when setting it to the 100% spawn rate. It's not much of an improvement, but to me it seems to be something like 5-10%. It also could be I'm just imagining it, sadly I do not own 2 CXes so I can't test :p

Some people need a high five in the face... with a chair.
~EC

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
Re: Chipmunk Physics
« Reply #10 on: January 08, 2013, 12:09:09 pm »
Sounds interesting, any one have a video?
A video of the chipmunk engine? Well, if you have the student software a handheld, you could try the code Jim posted above (they're really nice tbh)

@Nick My eat nethams game seems to run somewhat faster on 3.2 than it did on 3.1. The lobsters definitely fall smoother when setting it to the 100% spawn rate. It's not much of an improvement, but to me it seems to be something like 5-10%. It also could be I'm just imagining it, sadly I do not own 2 CXes so I can't test :p
That's what I hoped, that it would be faster, but still :o pff, I guess we could never expect it to be superlightningthunderboltfast, but at least a little afster than now xs but yeah, any improvement is nice..

Offline Rhombicuboctahedron

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 437
  • Rating: +41/-6
    • View Profile
Re: Chipmunk Physics
« Reply #11 on: January 08, 2013, 07:55:43 pm »
Sounds interesting, any one have a video?
A video of the chipmunk engine? Well, if you have the student software a handheld, you could try the code Jim posted above (they're really nice tbh)

Or watch this

Offline AnToX98

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 107
  • Rating: +10/-0
    • View Profile
Re: Chipmunk Physics
« Reply #12 on: December 07, 2013, 09:42:48 am »
Thank you jim's !
It's so hard to start using physics, your example code really helped me :)



My Lua projects :

Offline AnToX98

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 107
  • Rating: +10/-0
    • View Profile
Re: Chipmunk Physics
« Reply #13 on: March 17, 2014, 02:11:45 pm »
Can we modify shapes position ? I



My Lua projects :

Offline AnToX98

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 107
  • Rating: +10/-0
    • View Profile
Re: Chipmunk Physics
« Reply #14 on: April 12, 2014, 05:54:41 am »
Hi jims :)



I'm back with my falldown but I have 2 problems :
- The ball don't falls in the hole --'
- It slows down so much : why ?

Code: [Select]
------------------------------------------------
----------- LUA FALLDOWN, BY ANTOX98 -----------
------------------------------------------------

platform.apilevel = "2.0"

require "physics"

----------------------
----- BALL CLASS -----
----------------------

Ball = class()
Seg = class()

function Ball:init(x, y, w, mass)   
    self.width = w
    self.body = physics.Body(mass, physics.misc.momentForCircle(mass, 0, 10, ZERO))
    self.body:setPos(physics.Vect(x, y))
    self.body:setMass(mass)
    self.shape = physics.CircleShape(self.body, w, ZERO)
    self.shape:setRestitution(0.6)
    self.shape:setFriction(0.6)
end

function Seg:init(x1, y1, x2, y2)
    local a, b = physics.Vect(x1, y1), physics.Vect(x2, y2)       
    local mass = physics.misc.INFINITY()
    self.coor = {x1,y1,x2,y2}
    self.body = physics.Body(mass, physics.misc.momentForSegment(mass, a, b))
    --self.body:setPos(physics.Vect(x1, y1))
    self.body:setMass(mass)
    self.shape = physics.SegmentShape(self.body, a, b, 18)
    self.shape:setRestitution(0.6)
    self.shape:setFriction(0.6)
end

function Ball:paint(gc)
    local p = self.body:pos()
    local x, y = p:x(), p:y()
    local r = self.width / 2
   
    gc:setColorRGB(255,0,0)
    gc:fillArc(x+r, y+r , self.width, self.width, 0, 360)
end

function Seg:paint(gc)
   
    local a = self.shape:a()
    local b = self.shape:b()
    gc:setPen("thick")
    gc:setColorRGB(0,0,0)
    gc:drawLine(a:x(), a:y(), b:x(), b:y())
end

function initGame()
    w = 318
    h = 212
   
    ZERO = physics.Vect(0,0)
    LARGE = physics.misc.INFINITY()
   
    space = physics.Space()
    space:setGravity(physics.Vect(0,9.8))
   
    count = 100
   
    walls = {Seg(0,0,0,h), Seg(0,h,w,h), Seg(w,h,w,0)}
    for i = 1, #walls do
        space:addShape(walls[i].shape)   
    end
   
    seg = {}
    --space:addBody(sol.body)

   
    ball = Ball(w/2-10, 30, 20, 1000)
   
    space:addBody(ball.body)
    space:addShape(ball.shape)
   
    timer.start(0.01)
end
initGame()

function on.timer()
    space:step(0.1)
   
    if count == 100 then
        count = 0
        generate()
    else   
        count = count + 1
    end   
    moveSeg(0.5)
    platform.window:invalidate()
end

function generate()
    r = math.random(0, w-40)
   
    seg[#seg+1] = Seg(0, h, r, h)
    seg[#seg+1] = Seg(r+40, h, w, h)
    space:addShape(seg[#seg-1].shape)
    space:addShape(seg[#seg].shape)
end

function moveSeg(n)
    for i = 1, #seg do
        seg[i].coor = {seg[i].coor[1],seg[i].coor[2]-n,seg[i].coor[3],seg[i].coor[4]-n}
        local a, b = physics.Vect(seg[i].coor[1], seg[i].coor[2]), physics.Vect(seg[i].coor[3], seg[i].coor[4])       
        local mass = physics.misc.INFINITY()       
        seg[i].body = physics.Body(mass, physics.misc.momentForSegment(mass, a, b))
        --self.body:setPos(physics.Vect(x1, y1))
        seg[i].body:setMass(mass)
        seg[i].shape = physics.SegmentShape(seg[i].body, a, b, 18)
        seg[i].shape:setRestitution(0.6)
        seg[i].shape:setFriction(0.6)
        space:addShape(seg[i].shape)
    end   
end

function on.arrowKey(key)
    if key == "right" then
        ball.body:setAngVel(5)
    elseif key == "left" then
        ball.body:setAngVel(-5)
    end
end

function on.paint(gc)
    ball:paint(gc)   
    for i = 1, #seg do
        seg[i]:paint(gc)
    end
 
   
end



My Lua projects :