Balance

Here’s something I did long ago but I couldn’t find it so I thought I’d rewrite it. How long can you balance the white bar and green ball using the red ball. Slide your finger anywhere on the screen to move the red ball. The high score is kept in project data and can be reset using clearProjectData. Just remember to comment it out once it’s reset.

Not sure how this looks on an iPhone. I’ll find out after I post it and load it on my phone. I’ll make changes if required.

viewer.mode=FULLSCREEN

function setup()
    --clearProjectData()        -- clear high score
    rectMode(CENTER)
    getHighScore()
    getSizes()
    createBalls()
    createBar()
    
    dx,dy=0,0
    gameOver=false
    st=os.clock()
    ct=st
end

function draw()
    background()
    
    fontSize(math.min(w1,h1)/10)
    text(string.format("High  %.1f",currHigh),WIDTH/2,HEIGHT-100)
    text(string.format("Curr  %.1f",ct-st),WIDTH/2,HEIGHT-200)
    
    if bar.y<0 or ball1.y<0 then
        if ct-st>currHigh then
            currHigh=ct-st
            saveProjectData("high",currHigh)
        end
        gameOver=true
        fill(255)
        fontSize(20)
        text("Double tap to restart",WIDTH/2,HEIGHT/2)
        return
    end  
    
    ct=os.clock()
    ball2.x=ball2.x+dx
    ball2.y=ball2.y+dy
    
    fill(0,255,0)
    ellipse(ball1.x,ball1.y,ballSize*2)
    
    fill(255,0,0)
    ellipse(ball2.x,ball2.y,ballSize*2)
    
    fill(255)
    translate(bar.x,bar.y+3)
    rotate(bar.angle)
    rect(0,0,barSize*2,6)
    translate()
end

function touched(t)
    if t.state==BEGAN and gameOver then
        if t.tapCount==2 then
            viewer.restart()
        end
    end
    if t.state==CHANGED and not gameOver then
        dx=t.deltaX
        dy=t.deltaY
    end
end

function getHighScore()
    currHigh=readProjectData("high")
    if currHigh==nil then
        currHigh=0
        saveProjectData("high",0)
    end
end

function getSizes()
    w1,h1=WIDTH,HEIGHT
    barSize=math.min(w1,h1)//6
    ballSize=math.min(w1,h1)//40
end

function createBalls()
    ball1=physics.body(CIRCLE,ballSize)
    ball1.x=WIDTH/2+10
    ball1.y=HEIGHT/2+100
    ball1.type=DYNAMIC
    
    ball2=physics.body(CIRCLE,ballSize)
    ball2.x=WIDTH/2
    ball2.y=HEIGHT/2-80
    ball2.type=KINEMATIC
end

function createBar()
    bar=physics.body(POLYGON,vec2(0,0),vec2(barSize,0),vec2(barSize,6),
    vec2(-barSize,6),vec2(-barSize,0),vec2(0,0))
    bar.x=WIDTH/2+6
    bar.y=HEIGHT/2
    bar.type=DYNAMIC 
end

The above code didn’t work too well on the iPhone. I modified the code below so it worked better on the iPhone in portrait mode.

You might have to modify some of the values to make it fit better.

viewer.mode=FULLSCREEN

function setup()
    --clearProjectData()        -- clear high score
    rectMode(CENTER)
    getHighScore()
    getSizes()
    createBalls()
    createBar()
    
    dx,dy=0,0
    gameOver=false
    st=os.clock()
    ct=st
end

function draw()
    background()
    
    fontSize(math.min(w1,h1)/10)
    text(string.format("High  %.1f",currHigh),WIDTH/2,HEIGHT-50)
    text(string.format("Curr  %.1f",ct-st),WIDTH/2,HEIGHT-100)
    
    if bar.y<0 or ball1.y<0 then
        if ct-st>currHigh then
            currHigh=ct-st
            saveProjectData("high",currHigh)
        end
        gameOver=true
        fill(255)
        fontSize(20)
        text("Double tap to restart",WIDTH/2,HEIGHT/2)
        return
    end  
    
    ct=os.clock()
    ball2.x=ball2.x+dx
    ball2.y=ball2.y+dy
    
    fill(0,255,0)
    ellipse(ball1.x,ball1.y,ballSize*2)
    
    fill(255,0,0)
    ellipse(ball2.x,ball2.y,ballSize*2)
    
    fill(255)
    translate(bar.x,bar.y+3)
    rotate(bar.angle)
    rect(0,0,barSize*2,6)
    translate()
end

function touched(t)
    if t.state==BEGAN and gameOver then
        if t.tapCount==2 then
            viewer.restart()
        end
    end
    if t.state==CHANGED and not gameOver then
        dx=t.deltaX
        dy=t.deltaY
    end
end

function getHighScore()
    currHigh=readProjectData("high")
    if currHigh==nil then
        currHigh=0
        saveProjectData("high",0)
    end
end

function getSizes()
    w1,h1=WIDTH,HEIGHT
    barSize=math.min(w1,h1)//4
    ballSize=math.min(w1,h1)//30
end

function createBalls()
    ball1=physics.body(CIRCLE,ballSize)
    ball1.x=WIDTH/2+10
    ball1.y=HEIGHT/2+150
    ball1.type=DYNAMIC
    
    ball2=physics.body(CIRCLE,ballSize)
    ball2.x=WIDTH/2
    ball2.y=HEIGHT/2+50
    ball2.type=KINEMATIC
end

function createBar()
    bar=physics.body(POLYGON,vec2(0,0),
vec2(barSize,0),vec2(barSize,6),
    vec2(-barSize,6),vec2(-barSize,0),vec2(0,0))
    bar.x=WIDTH/2+6
    bar.y=HEIGHT/2+100
    bar.type=DYNAMIC 
end

Looks interesting, I’ll check it out when next at iPad. What about using gravity? :smile:

@RonJeffries Apparently you haven’t tried it yet. The white bar and green ball are balancing on the red ball. Gravity is pulling at both of them and the object is to move the red ball to keep both of them from falling. Once either of them fall thru the bottom of the screen, you get to try again. There’s a timer to keep track of how well you’re doing and your max time.

I haven’t. Thought it was controlled by touch, was suggesting using device tilt / gravity.

@RonJeffries I don’t think device tilt will work. The reaction time and control wouldn’t be fast enough.