Gravity control

When experimenting with the Gravity functions in Codea, I thought it would be nice to make some sort of controller where the gravity is used to trigger certain actions.

GravityControl = class()

GravityControl.null={name="NULL",gravity=vec3(0,0,0)}
GravityControl.upright={name="UPRIGHT",gravity=vec3(0,-1,0)}
GravityControl.upsidedown={name="UPSIDEDOWN",gravity=vec3(0,1,0)}
GravityControl.back={name="BACK",gravity=vec3(0,0,-1)}
GravityControl.front={name="FRONT",gravity=vec3(0,0,1)}
GravityControl.left={name="LEFT",gravity=vec3(-1,0,0)}
GravityControl.right={name="RIGHT",gravity=vec3(1,0,0)}

GravityControl.pollingInterval=0.25

function GravityControl:init(restState, actionState, action)
    self.currentState=self.null
    self.probability=0
    self.restState=restState
    self.actionState=actionState
    self.action=action
    
    self.devicePositions={
        self.upright,
        self.upsidedown,
        self.back,
        self.front,
        self.left,
        self.right
    }
end

function GravityControl:start()
    tween.delay(GravityControl.pollingInterval, function() self:update() end)
end

function GravityControl:guessState()
    local minDistance=9999
    local bestMatch=self.null
    
    for i,p in pairs(self.devicePositions) do
        local currentDistance=Gravity:dist(p.gravity)
        if currentDistance<minDistance then
            minDistance=currentDistance
            bestMatch=p
        end
    end
    return bestMatch,minDistance
end

function GravityControl:getPosition()
    return self.currentState.name, 1-self.probability
end

function GravityControl:update()
    self.currentState,self.probability=self:guessState()
    
    if (self.currentState==self.actionState) and (self.previousState==self.restState) then
        self:action()
    end
    self.previousState=self.currentState
    self:start()
end


GravityControl = class()

GravityControl.null={name="NULL",gravity=vec3(0,0,0)}
GravityControl.upright={name="UPRIGHT",gravity=vec3(0,-1,0)}
GravityControl.upsidedown={name="UPSIDEDOWN",gravity=vec3(0,1,0)}
GravityControl.back={name="BACK",gravity=vec3(0,0,-1)}
GravityControl.front={name="FRONT",gravity=vec3(0,0,1)}
GravityControl.left={name="LEFT",gravity=vec3(-1,0,0)}
GravityControl.right={name="RIGHT",gravity=vec3(1,0,0)}

GravityControl.pollingInterval=0.25

function GravityControl:init(restState, actionState, action)
    self.currentState=self.null
    self.probability=0
    self.restState=restState
    self.actionState=actionState
    self.action=action
    
    self.devicePositions={
        self.upright,
        self.upsidedown,
        self.back,
        self.front,
        self.left,
        self.right
    }
end

function GravityControl:start()
    tween.delay(GravityControl.pollingInterval, function() self:update() end)
end

function GravityControl:guessState()
    local minDistance=9999
    local bestMatch=self.null
    
    for i,p in pairs(self.devicePositions) do
        local currentDistance=Gravity:dist(p.gravity)
        if currentDistance<minDistance then
            minDistance=currentDistance
            bestMatch=p
        end
    end
    return bestMatch,minDistance
end

function GravityControl:getPosition()
    return self.currentState.name, 1-self.probability
end

function GravityControl:update()
    self.currentState,self.probability=self:guessState()
    
    if (self.currentState==self.actionState) and (self.previousState==self.restState) then
        self:action()
    end
    self.previousState=self.currentState
    self:start()
end

function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_RIGHT)
    
    textAlign(CENTER)
    textMode(CENTER)
    
    gControl1=GravityControl(GravityControl.front,GravityControl.upright,
        function() sound("Game Sounds One:Assembly 1") end)
    gControl1:start()
    gControl2=GravityControl(GravityControl.left,GravityControl.right,
        function() sound("Game Sounds One:Assembly 2") end)
    gControl2:start()
end

function draw()
    local positionName,probability=gControl1:getPosition()
    local probabilityString=string.format("(%d%%)",probability*100)

    print(positionName)
    print(probabilityString)
end

This example plays a sound when there is a transition from tilted front to upright and a different sound when tilted from left to right …

@JhaSeh When you post code, use ~~~ , not — at the top and bottom of your code. I corrected it for you.

The class tries to determine the position (as far as gravity goes) the device is in (or closest to). By defining a rest state and an action state, eaxh time that sequence passes the attached callback is called. Can be used for several games …

@JhaSeh Can you post the setup, draw, or any other functions so your example can be run without having to add extra code. If just a class is posted, I don’t even bother to look at it because I’m not going to take the time to create the extra functions to make it run. I’m sure other users probably don’t try it either. You can edit one of your example and add the code.