/ld28

To get this branch, use:
bzr branch http://9ix.org/bzr/ld28
1 by Josh C
zoetrope 1.4
1
-- Class: Keys
2
-- This tracks the state of the keyboard, i.e. if a key
3
-- was just pressed or released this frame. You can look
4
-- up a key either by its name or its Unicode number.
5
-- Not all keys sensed have Unicode equivalents (e.g. modifiers
6
-- like Control or Alt).
7
--
8
-- Only one Keys object can be active at one time. The one currently
9
-- listening to the keyboard can be accessed globally via <the>.keys.
10
--
11
-- See http://love2d.org/wiki/KeyConstant for a list of key names.
12
-- This class aliases modifiers for you, so that if you want to check
13
-- whether either the left or right Control key is pressed, you can check
14
-- on 'ctrl' instead of both 'lctrl' and 'rctrl'.
15
--
16
-- Extends:
17
--		<Sprite>
18
19
Keys = Sprite:extend{
20
	visible = false,
21
22
	-- Property: typed
23
	-- This is literally what is being typed during the current frame.
24
	-- e.g. if the user holds the shift key and presses the 'a' key,
25
	-- this will be set to 'A'. Consult <allPressed()> if you
26
	-- want to know what specific keys are being pressed.
27
28
	typed = '',
29
30
	-- private property: _thisFrame
31
	-- what keys are pressed this frame
32
	-- if you are interested in this, use allPressed() instead
33
34
	_thisFrame = {},
35
36
	-- private property: _lastFrame
37
	-- what keys were pressed last frame
38
	
39
	_lastFrame = {},
40
	
41
	new = function (self, obj)
42
		obj = self:extend(obj)
43
		the.keys = obj
44
		love.keypressed = function (key, unicode) obj:keyPressed(key, unicode) end
45
		love.keyreleased = function (key, unicode) obj:keyReleased(key, unicode) end
46
		if obj.onNew then obj:onNew() end
47
		return obj
48
	end,
49
	
50
	-- Method: pressed
51
	-- Are *any* of the keys passed held down this frame?
52
	--
53
	-- Arguments:
54
	--		string key descriptions passed as individual arguments
55
	--
56
	-- Returns:
57
	-- 		boolean
58
59
	pressed = function (self, ...)
60
		local keys = {...}
61
		for _, value in pairs(keys) do
62
			if STRICT then
63
				assert(type(value) == 'string', 'all keys are strings; asked to check a ' .. type(value))
64
			end
65
66
			if self._thisFrame[value] then
67
				return true
68
			end
69
		end
70
		
71
		return false
72
	end,
73
74
	-- Method: justPressed
75
	-- Are *any* of the keys passed pressed for the first time this frame?
76
	--
77
	-- Arguments:
78
	--		string key descriptions passed as individual arguments
79
	--
80
	-- Returns:
81
	-- 		boolean
82
83
	justPressed = function (self, ...)
84
		local keys = {...}
85
86
		for _, value in pairs(keys) do
87
			if STRICT then
88
				assert(type(value) == 'string', 'all keys are strings; asked to check a ' .. type(value))
89
			end
90
91
			if self._thisFrame[value] and not self._lastFrame[value] then
92
				return true
93
			end
94
		end
95
		
96
		return false
97
	end,
98
99
	-- Method: released
100
	-- Are *all* of the keys passed not held down this frame?
101
	-- 
102
	-- Arguments:
103
	--		string key descriptions passed as individual arguments
104
	--
105
	-- Returns:
106
	-- 		boolean
107
108
	released = function (self, ...)
109
		local keys = {...}
110
111
		for _, value in pairs(keys) do
112
			if STRICT then
113
				assert(type(value) == 'string', 'all keys are strings; asked to check a ' .. type(value))
114
			end
115
116
			if self._thisFrame[value] then
117
				return false
118
			end
119
		end
120
		
121
		return true
122
	end,
123
124
	-- Method: justReleased
125
	-- Are *any* of the keys passed released after being held last frame?
126
	--
127
	-- Arguments:
128
	--		string key descriptions passed as individual arguments
129
	--
130
	-- Returns:
131
	-- 		boolean
132
133
	justReleased = function (self, ...)
134
		local keys = {...}
135
136
		for _, value in pairs(keys) do
137
			if STRICT then
138
				assert(type(value) == 'string', 'all keys are strings; asked to check a ' .. type(value))
139
			end
140
141
			if self._lastFrame[value] and not self._thisFrame[value] then
142
				return true
143
			end
144
		end
145
		
146
		return false
147
	end,
148
149
	-- Method: allPressed
150
	-- Returns all buttons currently pressed this frame.
151
	--
152
	-- Arguments:
153
	--		none
154
	--
155
	-- Returns:
156
	--		string key descriptions; if nothing is pressed, nil
157
158
	allPressed = function (self)
159
		local result = {}
160
161
		for key, value in pairs(self._thisFrame) do
162
			if value then table.insert(result, key) end
163
		end
164
		
165
		return unpack(result)
166
	end,
167
168
	-- Method: allJustPressed
169
	-- Returns all keys just pressed this frame.
170
	--
171
	-- Arguments:
172
	--		none
173
	--
174
	-- Returns:
175
	--		string key descriptions; if nothing is just pressed, nil
176
177
	allJustPressed = function (self)
178
		local result = {}
179
180
		for key, value in pairs(self._thisFrame) do
181
			if value and not self._lastFrame[key] then table.insert(result, key) end
182
		end
183
		
184
		return unpack(result)
185
	end,
186
187
	-- Method: allJustReleased
188
	-- Returns all keys just released this frame.
189
	--
190
	-- Arguments:
191
	--		none
192
	--
193
	-- Returns:
194
	--		string key descriptions; if nothing is just pressed, nil
195
196
	allJustReleased = function (self)
197
		local result = {}
198
199
		for key, value in pairs(self._thisFrame) do
200
			if not value and self._lastFrame[key] then table.insert(result, key) end
201
		end
202
		
203
		return unpack(result)
204
	end,
205
206
	-- Connects to the love.keypressed callback
207
208
	keyPressed = function (self, key, unicode)
209
		self._thisFrame[key] = true
210
		if unicode and unicode >= 0x20 and unicode ~= 127 and unicode < 0x3000 then
211
			self.typed = self.typed .. string.char(unicode)
212
		end
213
214
		-- aliases for modifiers
215
216
		if key == 'rshift' or key == 'lshift' or
217
		   key == 'rctrl' or key == 'lctrl' or
218
		   key == 'ralt' or key == 'lalt' or
219
		   key == 'rmeta' or key == 'lmeta' or
220
		   key == 'rsuper' or key == 'lsuper' then
221
			self._thisFrame[string.sub(key, 2)] = true
222
		end
223
	end,
224
225
	-- Connects to the love.keyreleased callback
226
227
	keyReleased = function (self, key, unicode)
228
		self._thisFrame[key] = false
229
230
		-- aliases for modifiers
231
232
		if key == 'rshift' or key == 'lshift' or
233
		   key == 'rctrl' or key == 'lctrl' or
234
		   key == 'ralt' or key == 'lalt' or
235
		   key == 'rmeta' or key == 'lmeta' or
236
		   key == 'rsuper' or key == 'lsuper' then
237
			self._thisFrame[string.sub(key, 2)] = false
238
		end
239
	end,
240
241
	endFrame = function (self, elapsed)
242
		for key, value in pairs(self._thisFrame) do
243
			self._lastFrame[key] = value
244
		end
245
246
		self.typed = ''
247
		Sprite.endFrame(self, elapsed)
248
	end,
249
250
	update = function() end
251
}