Handling Keyboard input and Game loop.
Most 3D applications like games run in a game loop where are series of events modify the game and OpenGL state to draw things on screen. One such important event is user input event. OpenTK GameWindow
class has
one such method called OnUpdateFrame
which as the name suggest gets triggered every time the frame is rendered.
Right now it is getting it isnt doing anything since it is in the parent class and we are dealing with an instance of GameWindow
.
What we really need to do is inherit the GameWindow
and override the OnUpdateFrame
methods and capture the window events as they happen.
In order to do so there are primarily 3 mechanisms in in Clojure to deal with Inheritance. gen-class
, proxy
and reify
. But since we are dealing with the instance of the inherited class reify
cannot be used.
Since i aim to keep the tutorial largely functional my tool of choice is proxy
.
So let us modify our core
namespace and create a proxy object and override the OnUpdateFrame
method like so:
As you can see OpenTK.GameWindow
constructor has one more overloading function which can take four parameters, width
,height
, GraphicsMode
and Title
of the window. For now we are sticking with default graphics mode thus a nil
is passed.
If you compile and run this program it will print the event object to the terminal with every refresh.
Since, much of our game logic will go inside the OnUpdateFrame
method it will be better to dispatch the events to a separate on-update-frame function to handle the inputs and keep only the override definition in the proxy object like so:
Lets us compile and run this application:
You see every time we press the escape key it would print Escape Pressed
on the terminal multiple times because the refresh rate of the window is so fast that it ends up capturing the escape key press event multiple times.
For now we want the Escape key to exit the current window. But the on-update-frame
does not have a handle of the proxy
instance.
There is a way though C#
has a special keyword this
which gives a handle on the current execution context. Thus we would modify our OnUpdateFrame
override and on-update-frame
function and pass this as a parameter. Then we can simply call (.Exit this)
in the input let
block.
Let us modify our code like so:
This exits the window when you press escape.
Next we will refactor and properly organise the code, and learn how to draw shapes on the screen ...
To be continued ...
Previous Posts:
Top comments (0)