code.pyret.org icon indicating copy to clipboard operation
code.pyret.org copied to clipboard

on-raw-key

Open jpolitz opened this issue 6 years ago • 3 comments

A prototype of on-raw-key, which gives more control over keydown and keyup events, as well as information about meta keys

jpolitz avatar Mar 11 '18 18:03 jpolitz

Here's an example program that uses this for reference (not using a share link because the review app doesn't currently have Drive doing what I expect). You can run it by copy/pasting into

https://pyret-horizon-pr-262.herokuapp.com/editor

include image
include reactors

#|
   The Pong structure tracks whether each of the relevant keys is
   currently pushed down. W and S refer to the WASD setup for up
   and down, and up/down refer to the arrow keys. y1 and y2 correspond
   to the y positions of the two paddles
|#
data Pong:
  | pong(
      up :: Boolean,
      down :: Boolean,
      w :: Boolean,
      s :: Boolean,
      y1 :: Number,
      y2 :: Number)
end

DY = 3
paddle= rectangle(20, 50, "solid", "green")

draw-state :: Pong -> Image
fun draw-state(p):
  put-image(paddle, 20, p.y1,
    put-image(paddle, 480, p.y2,
      rectangle(500, 400, "solid", "black")))
end

next-state-tick :: Pong -> Pong
# This does all of the changing of actual positions - the two y values
# change according to the values in the up/down/w/s fields. The idea is
# that the up/down/w/s fields represent "moving right now", and all
# movement happens on ticks
fun next-state-tick(p):
  new-y1 =
    if p.s: p.y1 - DY
    else if p.w: p.y1 + DY
    else: p.y1
    end
  new-y2 =
    if p.up: p.y2 + DY
    else if p.down: p.y2 - DY
    else: p.y2 end
  pong(p.up, p.down, p.w, p.s, new-y1, new-y2)
end

next-state-raw-key :: Pong, Event -> Pong
#| This simply manipulates the up/down/w/s fields. The only two options
for the key-action field are "keydown" and "keyup" (this could potentially
be a boolean field on the Event). This means that on keyup, the
corresponding key state will become false, and on keydown it will become true,
and in all the intervening ticks it will be true.

The Event type is roughly what's specified in
 https://github.com/brownplt/code.pyret.org/issues/35#issuecomment-278417548
 
Currently, it's:
   
data Event:
  | time-tick
  | mouse(x :: Number, y :: Number, kind :: String)
  | keypress(key :: String)
  | raw-key(key :: String, key-action :: String, caps :: Boolean, shift :: Boolean, alt :: Boolean, command :: Boolean, control :: Boolean)
end

   and on-raw-key will _always_ receive a raw-key event. 
   
|#
fun next-state-raw-key(p, x):
  is-keydown = x.key-action == "keydown"
  if x.key == "s":
    pong(p.up, p.down, p.w, is-keydown, p.y1, p.y2)
  else if x.key == "w":
    pong(p.up, p.down, is-keydown, p.s, p.y1, p.y2)
  else if x.key == "ArrowUp":
    pong(is-keydown, p.down, p.w, p.s, p.y1, p.y2)
  else if x.key == "ArrowDown":
    pong(p.up, is-keydown, p.w, p.s, p.y1, p.y2)
  else:
    p
  end
end

r = reactor:
  init: pong(false, false, false, false, 200, 200),
  to-draw: draw-state,
  on-tick: next-state-tick,
  on-raw-key: next-state-raw-key
end

r.interact()

jpolitz avatar Mar 11 '18 21:03 jpolitz

Where does this PR stand?

schanzer avatar Mar 17 '20 02:03 schanzer

Is there any update on this?

L1Z3 avatar Dec 10 '21 03:12 L1Z3