1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
--[[ Public API ]] --
return movementController
end
MOVEMENT_CONTROLLER_DIRECTION_VERTICAL = 1
MOVEMENT_CONTROLLER_DIRECTION_HORIZONTAL = 2
if direction == MOVEMENT_CONTROLLER_DIRECTION_VERTICAL then
end
end
local NUM_TICKS_TO_START_ACCELERATING = 5
local ACCELERATION_MAGNTITUDE_FACTOR = 3
local MAX_TICKS_TO_ACCEL_ACROSS = 30
function ZO_MovementController : Initialize ( direction , accumulationPerSecondForChange , magnitudeQueryFunctionOverride )
self . direction = direction or MOVEMENT_CONTROLLER_DIRECTION_VERTICAL
self . accumulationPerSecondForChange = accumulationPerSecondForChange or 8
self . totalAccumulation = 0
self . debt = 0
self . lastMagnitude = 0
self . allowAcceleration = true
self . numTicksToStartAccelerating = NUM_TICKS_TO_START_ACCELERATING
self . accelerationMagnitudeFactor = ACCELERATION_MAGNTITUDE_FACTOR
self . numAccumulationTicks = 0
end
self . allowAcceleration = allowAcceleration
end
self . accumulationPerSecondForChange = accumulation
end
self . numTicksToStartAccelerating = numTicks
end
self . accelerationMagnitudeFactor = accelerationMagnitudeFactor
end
if self . numAccumulationTicks > MAX_TICKS_TO_ACCEL_ACROSS then
return true --if we're over the MAX_TICKS_TO_ACCEL_ACROSS we definitely aren't accelerating anymore
end
if self . debt == 0 then --otherwise if a snapshot of the accumulation right now is greater than the accumulation per second required,
local magnitude = self : GetMagnitude ( ) --we're already updating every frame regardless of being at max velocity
local snapshotAccumulation = magnitude * GetFrameDeltaNormalizedForTargetFramerate ( ) * self : CalculateAccelerationFactor ( )
if snapshotAccumulation >= self . accumulationPerSecondForChange then
return true
elseif snapshotAccumulation <= - self . accumulationPerSecondForChange then
return true
end
end
--for sufficiently large accumulation per second for change, you can potentially get to max velocity for a several frames before
--numAcculmulationTicks > MAX_TICKS_TO_ACCEL_ACROSS, ie you might get MOVE, NO, NO, MOVE, NO, MOVE, NO, NO, MOVE, NO, but short of
--keeping a running history of the last several frames we can't accurately predict that we've gotten to that point. Also 20 ticks
--a second is way too many to require a move
return false
end
MOVEMENT_CONTROLLER_NO_CHANGE = 0
MOVEMENT_CONTROLLER_MOVE_NEXT = 1
MOVEMENT_CONTROLLER_MOVE_PREVIOUS = 2
return ( previousMagnitude > 0 and newMagnitude < 0 )
or ( previousMagnitude < 0 and newMagnitude > 0 )
end
local ACCUMULATION_DEBT_PERCENT_AFTER_FIRST_SELECT = 1
local MIN_MAGNITUDE_FOR_ACCEL = . 8
if magnitude == 0 then
self . totalAccumulation = 0
self . isMovingFromAccumulation = false
self . lastMagnitude = 0
self . numAccumulationTicks = 0
else
-- reset moving state when changing a direction
self . isMovingFromAccumulation = false
self . lastMagnitude = magnitude
-- consume this input, some devices will "flip back" when the stick is tapped in a direction
-- this will help, but not eliminate that effect
return MOVEMENT_CONTROLLER_NO_CHANGE
end
self . numAccumulationTicks = 0
end
if self . isMovingFromAccumulation then
if self . debt > 0 then
-- Consume it all, nothing to do here
if self . debt >= absNormalizedMagnitude then
self . debt = self . debt - absNormalizedMagnitude
return MOVEMENT_CONTROLLER_NO_CHANGE
end
self . debt = 0
end
self . totalAccumulation = self . totalAccumulation + normalizedMagnitude * self : CalculateAccelerationFactor ( )
else
self . isMovingFromAccumulation = true
self . numAccumulationTicks = 0
self . totalAccumulation = magnitude > 0 and self . accumulationPerSecondForChange or - self . accumulationPerSecondForChange
end
self . lastMagnitude = magnitude
if self . totalAccumulation >= self . accumulationPerSecondForChange then
self . totalAccumulation = self . totalAccumulation - self . accumulationPerSecondForChange
self . numAccumulationTicks = self . numAccumulationTicks + 1
return MOVEMENT_CONTROLLER_MOVE_PREVIOUS
elseif self . totalAccumulation <= - self . accumulationPerSecondForChange then
self . totalAccumulation = self . totalAccumulation + self . accumulationPerSecondForChange
self . numAccumulationTicks = self . numAccumulationTicks + 1
return MOVEMENT_CONTROLLER_MOVE_NEXT
end
end
return MOVEMENT_CONTROLLER_NO_CHANGE
end
--[[ Private API ]] --
end
if self . allowAcceleration then
return 1.0 + ZO_EaseOutQuartic ( zo_clampedPercentBetween ( self . numTicksToStartAccelerating , MAX_TICKS_TO_ACCEL_ACROSS , self . numAccumulationTicks ) ) * self . accelerationMagnitudeFactor
end
return 1.0
end |