Game Loop Question

Hi,

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

Thanks in advance!!

you can’t if your sleeping

while  begin_ticks < ( begin_ticks + dt ) 
        ############################################
        ## try to detect keyboard button here???  ##
        ############################################
end

might work…

john

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 

your example code instantly locks up SU for me…

have you had a recent look at knight game [ i sent it to you years ago]…

it still works, and captures keys using javascript, which should be even better now we all have CEF in HtmlDialogs…

john

Yes, I have successfully done games inside SketchUp using javascript with the methods found in knight game before…

However, I wanted to test if I could do a Game Loop without javascript.

This simple game was the reason I started to learn how to do programming…Thanks!

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).

3 Likes