physics drive example

Here’s an example I have of a physics body driving another physics body using a physics connection between the two of them. I’m not sure if this is the correct way, but it seems to work. The speed of the physics body P2 can be increased by tapping the top of the screen. By using a connection between P2 and P4, the speed of wheel P4 will also increase. You can then tap the bottom of the screen to break the connection between P2 and P4. With the connection broken, P2 will continue at it’s speed, but the wheel P4 will slow down and stop. Tap the bottom to restart the demo. You can’t reconnect the joints while P2 or P4 are in motion because the connection has to be the correct length for P2 and P4 to rotate correctly. The same thing will happen in real life if the connection isn’t the right length.


displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)

function setup()
    speed=90
    
    -- anchor point for p2
    p1=physics.body(CIRCLE,0)
    p1.x=WIDTH/2
    p1.y=HEIGHT-200
    p1.type=STATIC
    
    -- P2 drive circle
    p2=physics.body(CIRCLE,50)
    p2.x=WIDTH/2
    p2.y=HEIGHT-200
    
    -- point to connect both wheels
    p5=physics.body(CIRCLE,0)
    p5.x=WIDTH/2
    p5.y=HEIGHT-200-48
    
    -- anchor point for p4
    p3=physics.body(CIRCLE,0)
    p3.x=WIDTH/2
    p3.y=300
    p3.type=STATIC
    
    -- P4 circle
    p4=physics.body(CIRCLE,150)
    p4.x=WIDTH/2
    p4.y=300
    
    -- point to connect both wheels
    p6=physics.body(CIRCLE,0)
    p6.x=WIDTH/2
    p6.y=300-48
    
    -- join p2 to anchor p1
    j1=physics.joint(REVOLUTE,p1,p2,vec2(p1.x,p1.y))
    -- join p4 to anchor p3
    j2=physics.joint(REVOLUTE,p3,p4,vec2(p3.x,p3.y))  
    -- join p5 drive point to p2  
    j3=physics.joint(REVOLUTE,p2,p5,vec2(p2.x,p2.y-48))
    -- join p6 drive pount to p 4
    j4=physics.joint(REVOLUTE,p4,p6,vec2(p4.x,p4.y-48))   
    -- join drive point p5 and p6 together 
    j5=physics.joint(DISTANCE,p5,p6,vec2(p6.x,p6.y))
end

function draw()
    background(40, 40, 50)    
    stroke(255)
    strokeWidth(2)
   
    fill(255)
    text("P2 drive shaft",WIDTH/2+150,HEIGHT-200)
    text("P4",WIDTH/2+200,300)
    
    --draw p2 and others
    pushMatrix()
    translate(p1.x,p1.y)
    rotate(p2.angle)
    ellipse(0,0,20)
    ellipse(0,-48,10)
    line(0,0,0,-48)
    popMatrix()

    noFill()
    
    -- draw p4 and others
    pushMatrix()
    translate(p3.x,p3.y)
    rotate(p4.angle)
    ellipse(0,0,304)
    fill(255)
    ellipse(0,0,20)
    ellipse(0,-48,20)
    line(-150,0,150,0)
    line(0,-150,0,150)
    popMatrix()
    
    -- draw connecting line between p5 and p6
    if j5~=nil then
        line(p2.joints[1].bodyB.x,p2.joints[1].bodyB.y,
            p4.joints[1].bodyB.x,p4.joints[1].bodyB.y)
    end
    
    -- angular speed
    p2.angularVelocity=speed 
    
    text("Tap here to double the speed.",WIDTH/2,HEIGHT-50)
    text("Tap here to break the   P2 to P4   joint or restart.",WIDTH/2,100)
    text("P2 speed:   "..speed.."   degrees per second.",WIDTH/2,HEIGHT-100)
end

function touched(t)
    if t.state==BEGAN then
        if t.y<HEIGHT/2 then
            -- break the connecting joint between p5 and p6
            if j5~=nil then
                j5:destroy()
                j5=nil
                p4.angularDamping=.3
            else
                restart()
            end
        else
            -- increase speed
            speed=speed*2   -- double speed each tap
        end
    end
end

@dave1707 this looks great and could have lots of practical applications, an engine maybe?