6
Gamepad = Sprite:extend
9
-- The index of the gamepad, starting at 1.
12
-- The name of the gamepad, e.g. "XBox Controller".
15
-- The number of available axes, e.g. for analog controls.
18
-- The number of available balls.
20
-- Property: numButtons
21
-- The number of available buttons.
24
-- The number of available hats, e.g. digital movement controls.
27
-- The state of all analog axes on the gamepad, indexed by number.
28
-- Values range from -1 to 1, where 0 is completely neutral.
31
-- The amount of motion by a each ball on the gamepad, indexed by number.
32
-- Not sure what the range of values is here.
35
-- The state of each hat on the gamepad, indexed by number. Each one has
36
-- one of these values: https://love2d.org/wiki/JoystickConstant
39
-- Any motion by an analog control (from 0 to 1) less than this value is
40
-- ignored when simulating digital controls.
44
-- private property: _thisFrame
45
-- what keys are pressed this frame
46
-- if you are interested in this, use allPressed() instead
50
-- private property: _lastFrame
51
-- what buttons were pressed last frame
55
new = function (self, obj)
56
obj = self:extend(obj)
57
assert(type(obj.number) == 'number', 'must set a gamepad number')
63
if obj.number <= love.joystick.getNumJoysticks() then
64
if not love.joystick.isOpen(obj.number) then love.joystick.open(obj.number) end
65
obj.name = love.joystick.getName(obj.number)
66
obj.numAxes = love.joystick.getNumAxes(obj.number)
67
obj.numBalls = love.joystick.getNumBalls(obj.number)
68
obj.numButtons = love.joystick.getNumButtons(obj.number)
69
obj.numHats = love.joystick.getNumHats(obj.number)
71
-- set initial values for axes and balls
72
-- hat values are strings so nil comparisons are safe
74
for i = 1, obj.numAxes do
78
for i = 1, obj.numBalls do
79
obj.balls[i] = { x = 0, y = 0 }
82
obj.name = 'NO DEVICE CONNECTED'
89
love.joystickpressed = Gamepad._dispatchPress
90
love.joystickreleased = Gamepad._dispatchRelease
91
if obj.onNew then obj:onNew() end
96
-- Are *any* of the buttons passed held down this frame?
99
-- button numbers passed as individual arguments
104
pressed = function (self, ...)
105
local buttons = {...}
107
for _, value in pairs(buttons) do
108
if self._thisFrame[value] then
116
-- Method: justPressed
117
-- Are *any* of the buttons passed pressed for the first time this frame?
120
-- button numbers passed as individual arguments
125
justPressed = function (self, ...)
126
local buttons = {...}
128
for _, value in pairs(buttons) do
129
if self._thisFrame[value] and not self._lastFrame[value] then
138
-- Are *all* of the buttons passed not held down this frame?
141
-- button numbers passed as individual arguments
146
released = function (self, ...)
147
local buttons = {...}
149
for _, value in pairs(buttons) do
150
if self._thisFrame[value] then
158
-- Method: justReleased
159
-- Are *any* of the buttons passed released after being held last frame?
162
-- button numbers passed as individual arguments
167
justReleased = function (self, ...)
168
local buttons = {...}
170
for _, value in pairs(buttons) do
171
if self._lastFrame[value] and not self._thisFrame[value] then
179
-- Method: allPressed
180
-- Returns all buttons currently pressed this frame.
186
-- string button descriptions; if nothing is pressed, nil
188
allPressed = function (self)
191
for key, value in pairs(self._thisFrame) do
192
if value then table.insert(result, key) end
195
return unpack(result)
198
-- Method: allJustPressed
199
-- Returns all buttons just pressed this frame.
205
-- string button descriptions; if nothing is just pressed, nil
207
allJustPressed = function (self)
210
for key, value in pairs(self._thisFrame) do
211
if value and not self._lastFrame[key] then table.insert(result, key) end
214
return unpack(result)
217
-- Method: allJustReleased
218
-- Returns all buttons just released this frame.
224
-- string button descriptions; if nothing is just pressed, nil
226
allJustReleased = function (self)
229
for key, value in pairs(self._thisFrame) do
230
if not value and self._lastFrame[key] then table.insert(result, key) end
233
return unpack(result)
236
buttonPressed = function (self, button)
237
self._thisFrame[button] = true
240
buttonReleased = function (self, button)
241
self._thisFrame[button] = false
244
endFrame = function (self, elapsed)
245
-- move button values to the previous frame
247
for key, value in pairs(self._thisFrame) do
248
self._lastFrame[key] = value
253
for i = 1, self.numAxes do
254
self.axes[i] = love.joystick.getAxis(self.number, i)
257
for i = 1, self.numBalls do
258
self.balls[i].x, self.balls[i].y = love.joystick.getBall(self.number, i)
261
for i = 1, self.numHats do
262
self.hats[i] = love.joystick.getHat(self.number, i)
265
-- simulate digital controls
267
self._thisFrame['up'] = false
268
self._thisFrame['down'] = false
269
self._thisFrame['left'] = false
270
self._thisFrame['right'] = false
272
if self.numHats > 0 then
273
local hat = self.hats[1]
276
self._thisFrame['up'] = true
277
elseif hat == 'd' then
278
self._thisFrame['down'] = true
279
elseif hat == 'l' then
280
self._thisFrame['left'] = true
281
elseif hat == 'r' then
282
self._thisFrame['right'] = true
283
elseif hat == 'lu' then
284
self._thisFrame['up'] = true
285
self._thisFrame['left'] = true
286
elseif hat == 'ru' then
287
self._thisFrame['up'] = true
288
self._thisFrame['right'] = true
289
elseif hat == 'ld' then
290
self._thisFrame['down'] = true
291
self._thisFrame['left'] = true
292
elseif hat == 'rd' then
293
self._thisFrame['down'] = true
294
self._thisFrame['right'] = true
298
if self.numAxes > 1 then
299
local xAxis = self.axes[1]
300
local yAxis = self.axes[2]
302
if math.abs(xAxis) > self.deadZone then
304
self._thisFrame['left'] = true
306
self._thisFrame['right'] = true
310
if math.abs(yAxis) > self.deadZone then
312
self._thisFrame['up'] = true
314
self._thisFrame['down'] = true
319
Sprite.endFrame(self)
322
-- private method: _dispatchPress
323
-- receives a Love joystickpressed callback and hands it off
324
-- to the appropriate gamepad.
326
_dispatchPress = function (number, button)
327
if the.gamepads[number] then
328
the.gamepads[number]:buttonPressed(button)
332
-- private method: _dispatchRelease
333
-- receives a Love joystickreleased callback and hands it off
334
-- to the appropriate gamepad.
336
_dispatchRelease = function (number, button)
337
if the.gamepads[number] then
338
the.gamepads[number]:buttonReleased(button)