Skip to content

Commit

Permalink
Merge pull request #3 from Nezuo/linear-goal
Browse files Browse the repository at this point in the history
Linear goal
  • Loading branch information
Reselim authored Oct 8, 2020
2 parents a93e87c + e08cad4 commit ca1ed85
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Linear.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
local Linear = {}
Linear.__index = Linear

function Linear.new(targetValue, options)
assert(targetValue, "Missing argument #1: targetValue")

options = options or {}

return setmetatable({
_targetValue = targetValue,
_targetVelocity = options.velocity or 1
}, Linear)
end

function Linear:step(state, dt)
local position = state.value
local velocity = self._targetVelocity -- Linear motion ignores the state's velocity
local goal = self._targetValue

local dPos = dt * velocity

local complete = dPos >= math.abs(goal - position)
position = position + dPos * (goal > position and 1 or -1)
if complete then
position = self._targetValue
velocity = 0
end

return {
complete = complete,
value = position,
velocity = velocity
}
end

return Linear
57 changes: 57 additions & 0 deletions src/Linear.spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
return function()
local SingleMotor = require(script.Parent.SingleMotor)
local Linear = require(script.Parent.Linear)

describe("completed state", function()
local motor = SingleMotor.new(0, false)

local goal = Linear.new(1, { velocity = 1 })
motor:setGoal(goal)

for _ = 1, 60 do
motor:step(1/60)
end

it("should complete", function()
expect(motor._state.complete).to.equal(true)
end)

it("should be exactly the goal value when completed", function()
expect(motor._state.value).to.equal(1)
end)
end)

describe("uncompleted state", function()
local motor = SingleMotor.new(0, false)

local goal = Linear.new(1, { velocity = 1 })
motor:setGoal(goal)

for _ = 1, 59 do
motor:step(1/60)
end

it("should be uncomplete", function()
expect(motor._state.complete).to.equal(false)
end)
end)

describe("negative velocity", function()
local motor = SingleMotor.new(1, false)

local goal = Linear.new(0, { velocity = 1 })
motor:setGoal(goal)

for _ = 1, 60 do
motor:step(1/60)
end

it("should complete", function()
expect(motor._state.complete).to.equal(true)
end)

it("should be exactly the goal value when completed", function()
expect(motor._state.value).to.equal(0)
end)
end)
end
1 change: 1 addition & 0 deletions src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local Flipper = {
GroupMotor = require(script.GroupMotor),

Instant = require(script.Instant),
Linear = require(script.Linear),
Spring = require(script.Spring),

isMotor = require(script.isMotor)
Expand Down
20 changes: 20 additions & 0 deletions typings/Linear.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface LinearState {
complete: boolean
position: number
velocity: number
}

interface LinearOptions {
velocity?: number
}

declare interface Linear {
step(state: LinearState, deltaTime: number): LinearState
}

declare interface LinearConstructor {
new(targetValue: number, options?: LinearOptions): Linear
}

declare const Linear: LinearConstructor
export = Linear

0 comments on commit ca1ed85

Please sign in to comment.