I am trying to detect a keyboard press while inside a loop and can’t figure it out.
def update
## Start off assuming an ideal frame time (30 FPS)
dt = 1.0 / 30.0
## Prime the pump by reading the current time.
begin_ticks = Process.clock_gettime(Process::CLOCK_MONOTONIC)
while true do ## game loop
sleep(dt)
############################################
## How to detect keyboard button here??? ##
############################################
## Read the current time again, and calculate the delta.
end_ticks = Process.clock_gettime(Process::CLOCK_MONOTONIC)
## Check our units:
dt = (end_ticks - begin_ticks)
## If dt is too large, we must have resumed from a
## breakpoint -- frame-lock to the target rate this frame.
if dt > 1.0
dt = 1.0 / 30.0
end
## Use end_ticks as the new begin_ticks for next frame.
begin_ticks = end_ticks
end ## Game Loop
end ## def
Not working…maybe I need to check for keystrokes with something other than onKeyDown observer.
Here is the full code that I used for test…
module RafaelRivera
module FirstGame
class Game
def initialize
@stop = false
update
end # initialize
def onKeyDown(key, repeat, flags, view)
puts "KeyDown"
@stop = true
end
def update
## Start off assuming an ideal frame time (30 FPS)
dt = 1.0 / 30.0
## Prime the pump by reading the current time.
begin_ticks = Process.clock_gettime(Process::CLOCK_MONOTONIC)
#while @stop == false do ## game loop
while begin_ticks < ( begin_ticks + dt )
puts dt
if @stop == true
puts "Stoped the loop!"
break
end
## Read the current time again, and calculate the delta.
end_ticks = Process.clock_gettime(Process::CLOCK_MONOTONIC)
## Check our units...
dt = (end_ticks - begin_ticks)
## If dt is too large, we must have resumed from a
## breakpoint -- frame-lock to the target rate this frame.
if dt > 1.0
dt = 1.0 / 30.0
end
## Use end_ticks as the new begin_ticks for next frame.
begin_ticks = end_ticks
end #### Game Loop ####
end
end # class
end # module
end # module
Sketchup.active_model.select_tool RafaelRivera::FirstGame::Game.new
Any kind of a loop or an iterator locks SketchUp. The only way to be able to detect any events (including keystrokes) is to use a timer. Here is UI.start_timer and UI.stop_timer API methods documentation for a reference.
In JavaScript you were not using sleep (synchronous, blocking) but setTimeout (asynchronous, non-blocking), which gives the browser time to update its UI, the DOM, receive input events. Sketchup is single-threaded and our Ruby plugins use the same thread as the UI and everything else. When your script creates an infinite loop (with blocking operations), it never gives SketchUp time to update its UI or receive events.
There can only be one main loop. In most game tutorials that instruct you to create a game/main loop, you are the owner of the main loop. In SketchUp, you are not, but SketchUp is the owner and also controls the frame rate.
You need to develop the game event-driven. SketchUp’s Tool class gives you a lot of events: when ever an input happens (onKeyDown) and when SketchUp is going to draw a frame (draw). You should use these.
If you need to draw more frames (when there is no input that causes SketchUp to redraw), you can use an asynchronous timer to invalidate the view, and then your draw method is going to be called again (for example done in sketchup-gl-animation).