-
Notifications
You must be signed in to change notification settings - Fork 0
/
zinput.lua
133 lines (123 loc) · 3.62 KB
/
zinput.lua
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
local zinput = {
_VERSION = 'Zinput v0.1',
_DESCRIPTION = 'A simple love2d input mixin for middleclass based on tactile',
_URL = 'HTTPS://github.com/wec22/Zinput',
inputs = {}
}
local button = {
__call = function(self, what)
what = what or "value"
local time = self.time
if what == "value" or what == "down" then --always true if down
return self.value, time
elseif what == "prev" then --true if button was pressed last frame
return self.prev
elseif what == "pressed" then --true if first pressed this frame
self.time = 0
return self.value and not self.prev, time
elseif what == "released" then --true if released this frame
self.time = 0
return not self.value and self.prev, time
elseif what == "up" then --always true if the button is not pressed opposite of "value" or "down"
return not self.value, time
end
end
}
button.__index=button
function zinput:newbutton(name, ...)
assert(type(name) == "string", "name must be a string")
self.inputs[name] = {
detectors = {...},
prev = false,
value = false,
time = 0
}
setmetatable(self.inputs[name], button)
end
--button definitions
function button:addDetector(detector)
assert(type(detector) == "function", "detector must be a function")
table.insert(self.detectors, detector)
end
function button:update(dt)
self.prev = self.value
self.value = false
self.time = self.time + (dt or 0)
--loop to go through detectors and check if true
for i in ipairs(self.detectors) do
if self.detectors[i]() then
self.value = true
break
end
end
end
local axis = {
__call = function(self, what)
what = what or "value"
assert(type(what) == "string", "'what' must be a string")
if what == "value" then
return self.value
elseif what == "prev" then
return self.prev
elseif what == "vel" then
return self.vel
end
end
}
axis.__index = axis
function zinput:newaxis(name, ...)
self.inputs[name] = {
prev = 0,
value = 0,
vel = 0,
dz = 0.5,
detectors = {...}
}
setmetatable(self.inputs[name], axis)
end
--axis definitions
function axis:addDetector(detector)
assert(type(detector)=="function", "detector must be a function")
table.insert(self.detectors, detector)
end
function axis:update(dt)
self.prev = self.value
self.value = 0
for i in pairs(self.detectors) do
local value = self.detectors[i]() or 0
if math.abs(value) > self.dz then
self.value = value
end
end
--get the instantaneous velocity during this frame
self.vel = (self.value - self.prev) / (dt or love.timer.getDelta())
end
function axis:setdeadzone(dz)
self.dz = dz
end
--experimental joystick wrapper for axes
local joy = {}
joy.__index = joy
function zinput:newjoy(name, x, y, ...)
self:newaxis(name..'x', x)
self:newaxis(name..'y', y)
self.inputs[name] = {
x = self.inputs[name..'x'],
y = self.inputs[name..'y']
}
setmetatable(self.inputs[name],joy)
end
function joy:update()
--doesn't need to do anything since the axes are updated already
--it just needs to exist
end
function joy:addDetector(x, y)
self.x:addDetector(x)
self.y:addDetector(y)
end
function zinput:inputUpdate(dt)
for k,v in next, self.inputs do
self.inputs[k]:update(dt)
end
end
return zinput