DEV Community

Cover image for OpenGL Game in Clojure CLR (Mono/.Net) - Part3  (Handling Input)

OpenGL Game in Clojure CLR (Mono/.Net) - Part3 (Handling Input)

metacritical profile image Pankaj Doharey Updated on ・2 min read

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.

Print Event Object

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:

Handle Keypress

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:

Part 1 - The Setup
Part 2 - The Game Window

Discussion (0)

Editor guide