This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Antelux's profile picture

Keyboard v1.032

Started by Antelux, 04 August 2015 - 12:20 PM
Antelux #1
Posted 04 August 2015 - 02:20 PM
You can get the API by running this: pastebin get itm2dNC1

While working on an upcoming engine of mine, I required an API that easily allowed me to get multiple key inputs at one time. Seeing how there were none on the forums that I know of, I decided to post mine here.

It's a rather small API, but it can be used to do interesting things. Here's some function documentation:

Keyboard.isDown( key )
Returns true if the key is being held. It now only accepts strings for ease of use. You can also check if it's holding down certain combos. For example: Keyboard.isDown("leftCtrl+c") can now be used. It can be any combination of letters, even something like Keyboard.isDown("q+w+e+r+t+y"). However, keep in mind, the order that you specify is specific to the order inputted. For example, Keyboard.isDown("a+b") is not the same as Keyboard.isDown("b+a"). Since the ordering of the two is different, it will only return true if that specific ordering of key presses is met.

Keyboard.getHeldKeys()
This returns a table of all keys currently being held down. For example, if you pressed a, b, then c, in that order, it would return the table {"a", "b", "c"}.

Keyboard.setKeyRepeat( bool )
Enables or disables key repeat. If enabled (which it is, by default), the key your holding will be considered held until you release the key. If disabled, holding it down does not make it count as it being held. Instead, the key will have to be pressed again in order to signal that it's being pressed.

Keyboard.getKeyRepeat()
Gets the state of keyRepeat in the form of a bool. If it's enabled, then it'll return true.

Keyboard.reset()
Resets the keyboard input table. If the API is used correctly, you shouldn't really have reason to do this.

Keyboard.version()
Returns the version of the API in the form of a string. Currently, it will return "1.032"

Keyboard.updateKeys( eventData )
This function must be ran in order to use the API. It is possible to over write the default os.pullEvent function in order to not be required to run this function. So, in the API, there's a commented out version of the over written os.pullEvent function if you prefer not to run this function. When using this function, eventData must be a table of events.

Here's how your code should look: (The below code is a piece from my engine.)

local eventData = {os.pullEvent()}

if eventData[1] == "key" or eventData[1] == "key_up" then
	 Keyboard.updateKeys(eventData) -- Comment out if youre using the over written os.pullEvent function
	 if Keyboard.isDown("w") then updateMesh("x", degrees) end
	 if Keyboard.isDown("s") then updateMesh("x", -degrees) end
	 if Keyboard.isDown("a") then updateMesh("y", -degrees) end
	 if Keyboard.isDown("d") then updateMesh("y", degrees) end

	 if Keyboard.isDown("one") then renderWireframe = not renderWireframe end
	 if Keyboard.isDown("two") then renderTextures = not renderTextures end

	 if Keyboard.isDown("q") then scale = scale - 0.1; updateMesh("s", scale) end
	 if Keyboard.isDown("e") then scale = scale + 0.1; updateMesh("s", scale) end

	 if Keyboard.isDown("z") then if degrees ~= 1 then degrees = degrees - 1 end end
	 if Keyboard.isDown("c") then if degrees ~= 360 then degrees = degrees + 1 end end

	 if Keyboard.isDown("r") then
		  scale = 5.0; degrees = 8
		  updateMesh("x", "r")
		  updateMesh("y", "r")
		  updateMesh("s", scale)
	 end

	 if Keyboard.isDown("up") then camera.position.y = camera.position.y - 1 end
	 if Keyboard.isDown("down") then camera.position.y = camera.position.y + 1 end
	 if Keyboard.isDown("left") then camera.position.x = camera.position.x - 1 end
	 if Keyboard.isDown("right") then camera.position.x = camera.position.x + 1 end
end

If you want to try out and see the Keyboard API in action, run pastebin get 9RkLdc3x key

Some of you may have noticed that this API is similar to the Keyboard module from Love2D. This was intentional.

New: Keyboard "NS": pastebin get UYSkLKMY
I've added another version of the API, named Keyboard "NS" (NS standing for non string).
It's very similar to the original. However, it's a lot faster because it doesn't deal with strings.
It's highly recommended for programs which need fast, real time input.

What's the key difference? Well, basically, this:

Keyboard.isDown("w")
becomes this:

Keyboard.isDown(keys.w)

The other main difference is that you no longer give the function Keyboard.updateKeys() a table.
Instead, this code would be used:

local event, key, held = os.pullEvent()
if event == "key" or event == "key_up" then
	  Keyboard.updateKeys(event, key, held)
	  -- Key checking is done here
	  if Keyboard.isDown(keys.s) then
			-- etc
	  end
end

It also can't check for multiple key inputs at a time. This can be easily fixed though, and it will probably be later updated to include the feature (Meaning, you can't do something like Keyboard.isDown(keys.w.. "+" ..keys.s)).
Edited on 25 October 2015 - 11:51 AM
Exerro #2
Posted 04 August 2015 - 08:21 PM
Very nice. I'd suggest adding some utilities for key-combos, something like this maybe:

Keyboard.isPressed "ctrl-shift-tab"

Also, string key names are more helpful:

Keyboard.isDown "left"
You can use keys.getName() to get the name of the numeric key ID or make a reverse lookup table from the keys API.
Antelux #3
Posted 07 August 2015 - 06:49 PM
I've updated it to include those ideas of yours, awsumben13. Thanks for that.
Edited on 07 August 2015 - 04:50 PM
flaghacker #4
Posted 07 August 2015 - 09:36 PM
I've updated it to include those ideas of yours, awsumben13. Thanks for that.

I thing you forgot to update the code on pastebin.
Edited on 07 August 2015 - 07:41 PM
Antelux #5
Posted 07 August 2015 - 09:38 PM
I thing you forgot to update the code on pastebin.

I just checked the link myself. It was updated?
flaghacker #6
Posted 07 August 2015 - 09:40 PM
I thing you forgot to update the code on pastebin.

I just checked the link myself. It was updated?

Euhm… You're entirely correct. I'm a complete derp, sorry.
Antelux #7
Posted 07 August 2015 - 09:43 PM
Euhm… You're entirely correct. I'm a complete derp, sorry.

Don't worry about it, it never happened :P/>
cyanisaac #8
Posted 23 August 2015 - 06:33 PM
Wow, this is just what I was looking for! Excellent :D/>
Antelux #9
Posted 23 August 2015 - 09:10 PM
Wow, this is just what I was looking for! Excellent :D/>

Thanks. Glad someone is using it :P/>
Edited on 23 August 2015 - 07:12 PM
cyanisaac #10
Posted 24 August 2015 - 07:08 PM
I seem to be having some trouble with this API, here's a snippet of code

local function getKeyCommands()
while true do
  Keyboard.updateKeys(os.pullEvent())
  if Keyboard.isDown("leftAlt+q") then
   break
  else
   coroutine.yield()
  end
end
end
local inp = nil
local function runShellInput()
shell.run(inp)
end

When I press "leftAlt+q" it gives me an error as well, the error is

window:94: arguments must be the same length

is this an error in my code or your API?
Antelux #11
Posted 24 August 2015 - 07:14 PM
I seem to be having some trouble with this API, here's a snippet of code

When using the function Keyboard.updateKeys(), a table of events should be passed as the first argument. Here's the fixed code for you:

local function getKeyCommands()
  while true do
	Keyboard.updateKeys({os.pullEvent()})
	if Keyboard.isDown("leftAlt+q") then
	  break
	else
	 -- Because yielding prevents the API from catching key events, this makes the API preform weirdly.
	 -- Using the function Keyboard.updateKeys() to capture events from this sort of helps, but its best
	 -- To remove coroutine.yield() from the function all together for the most accurate results from the api.
	 coroutine.yield()
	end
  end
end

EDIT: There's actually a problem I found with my API in regard to key combos. I plan to fix it now.
EDIT 2: Alright, fixed it. The API works correctly now.
Edited on 24 August 2015 - 05:47 PM
cyanisaac #12
Posted 24 August 2015 - 08:12 PM
I seem to be having some trouble with this API, here's a snippet of code

When using the function Keyboard.updateKeys(), a table of events should be passed as the first argument. Here's the fixed code for you:

local function getKeyCommands()
  while true do
	Keyboard.updateKeys({os.pullEvent()})
	if Keyboard.isDown("leftAlt+q") then
	  break
	else
	 -- Because yielding prevents the API from catching key events, this makes the API preform weirdly.
	 -- Using the function Keyboard.updateKeys() to capture events from this sort of helps, but its best
	 -- To remove coroutine.yield() from the function all together for the most accurate results from the api.
	 coroutine.yield()
	end
  end
end

EDIT: There's actually a problem I found with my API in regard to key combos. I plan to fix it now.
EDIT 2: Alright, fixed it. The API works correctly now.

ooooooh thank you very very much! So glad this works now :D/>

What does the commented out code for os.pullEvent do?
Antelux #13
Posted 24 August 2015 - 08:17 PM
What does the commented out code for os.pullEvent do?

If you use that piece of commented code, then you can use os.pullEvent() normally without the need for using the function Keyboard.updateKeys().
Here's an example:

Keyboard.updateKeys({os.pullEvent()})
Becomes

os.pullEvent()
cyanisaac #14
Posted 24 August 2015 - 08:52 PM
oh neat.

BTW it still seems to give me
window:94:arguments must be the same length
with my code.

Any suggestions?
Antelux #15
Posted 24 August 2015 - 09:15 PM
Do you think you can show me the exact code of the program?
Antelux #16
Posted 27 August 2015 - 02:19 AM
I've updated the API to fix a slight bug when checking what keys are down.
Antelux #17
Posted 21 October 2015 - 10:41 PM
Added a different version of the Keyboard API. See the main post for details.