Mouse and Keyboard Input in Gosu

Games are, by definition, interactive. Gosu makes this interaction straightforward with a simple interface for detecting and reacting to key and mouse button presses.

There are two primary ways to handle input in your program. The first is an event-oriented approach. When buttons are pressed, your programs receives an event and you can react accordingly. The second is to check if, at the time of an update, a certain button is pressed. Both techniques are perfectly valid, use whichever one suits you best.

Key and Button Constants

Behind the scenes, buttons are represented by integers. These integer codes are platform-dependent and probably shouldn't find their way into your game code. To abstract this away, Gosu provides a number of constants to use.

For every keyboard key, there is a Gosu::Kb* constant. For most of the keys, the names of these constants are easily guessed. For example, the arrow keys are Gosu::KbLeft, Gosu::KbRight, Gosu::KbUp and Gosu::KbDown. For a complete list, see the documentation for the Gosu module.

There are also similar constants for mouse buttons. You'll mainly be using the Gosu::MsLeft and Gosu::MsRight for left and right click. There is also support for gamepads via the Gosu::Gp* constants.

This article is part of a series. Read more articles about Rapid Game Prototyping in Ruby

Event-Oriented Input

Input events are delivered to the Gosu::Window instance. In the main loop, before update is called, Gosu will deliver events for all buttons that have either been pressed or released. It does this by calling the button_down and button_up methods, passing the id of the key or button pressed.

In the button_down and button_up methods, you often find a case statement. This, beside being very function, provides a very elegant and expressive way to decide what to do depending on which button was pressed or released. The following is a short example of what a button_down method can look like. It should be placed in your Gosu::Window subclass, and will close the window (ending the program) when the escape key is pressed.


def button_down(id)
case id
when Gosu::KbEscape
close
end
end

Easy, right? Let's expand this. Here is a Player class. It can move left and right if the left and right keys are pressed. Note that this class also has button_down and button_up methods. They work just like the methods from a Gosu::Window subclass. Gosu doesn't know anything about Player though, we'll be calling the Player's methods manually from the Gosu::Window's methods. A full, runnable example can be found here.


class Player
# In pixels/second
SPEED = 200
def self.load(window)
with_data('player.png') do|f|
@@image = Gosu::Image.new(window, f, false)
end
end
def initialize(window)
@window = window
@x = (@window.width / 2) - (@@image.width / 2)
@y = @window.height - @@image.height
@direction = 0
end
def update(delta)
@x += @direction * SPEED * delta
@x = 0 if @x @window.width - @@image.width
@x = @window.width - @@image.width
end
end
def draw
@@image.draw(@x, @y, Z::Player)
end
def button_down(id)
case id
when Gosu::KbLeft
@direction -= 1
when Gosu::KbRight
@direction += 1
end
end
def button_up(id)
case id
when Gosu::KbLeft
@direction += 1
when Gosu::KbRight
@direction -= 1
end
end
end

This article is part of a series. Read more articles about Rapid Game Prototyping in Ruby

Querying Input

If event-based input is not your style, you can query any Gosu::Window to see if any button or key is pressed, at any time. You can ignore the button_down and button_up callbacks entirely.

To query the Gosu::Window to see if a key is pressed, call the button_down? method with the id of the button you'd like to check. Don't forget the question mark in this call! If you call button_down(Gosu::KbLeft), you'll be reporting a button press to the Gosu::Window subclass. Even if you don't have any callback methods defined, the parent class, Gosu::Window will. There will be no error, it just won't work as you expect. Just don't forget that question mark!

Here is the Player class re-written to use button_down? instead of events. A full, runnable example is available here. This time, input is checked for at the beginning of the update method. You'll also notice that this example is shorter but, in my opinion, less elegant.


class Player
attr_reader :x, :y
# In pixels/second
SPEED = 200
def self.load(window)
with_data('player.png') do|f|
@@image = Gosu::Image.new(window, f, false)
end
end
def initialize(window)
@window = window
@x = (@window.width / 2) - (@@image.width / 2)
@y = @window.height - @@image.height
@direction = 0
end
def update(delta)
@direction = 0
if @window.button_down?(Gosu::KbLeft)
@direction -= 1
end
if @window.button_down?(Gosu::KbRight)
@direction += 1
end
@x += @direction * SPEED * delta
@x = 0 if @x @window.width - @@image.width
@x = @window.width - @@image.width
end
end
def draw
@@image.draw(@x, @y, Z::Player)
end
end

This article is part of a series. Read more articles about Rapid Game Prototyping in Ruby

Mouse Input

The mouse buttons are handled in the same way as keyboard and gamepad buttons. You can both query them with button_down? and events with button_down and button_up. However, mouse movement may only be queried, there are no events for mouse movement. Gosu::Window's mouse_x and mouse_y methods provide the X and Y coordinates of the mouse pointer.

Note that the X and Y coordinates are relative to the game window. So, for example, if the mouse is at the top left corner, it will be near the coordinate (0,0). Also, if the mouse pointer is outside of the game window entirely, it will still report where the pointer is relative to the window. So both mouse_x and mouse_y can be less than zero and more than the width or height of the window.

The following program will display a new sprite wherever you click the mouse. Note that it uses both event-driven input (for the clicks), and query-driven input (to get the position of the mouse). A full, runnable file is available here.


class MyWindow
Format
mla apa chicago
Your Citation
Morin, Michael. "Mouse and Keyboard Input in Gosu." ThoughtCo, Aug. 27, 2020, thoughtco.com/mouse-and-keyboard-input-in-gosu-2908025. Morin, Michael. (2020, August 27). Mouse and Keyboard Input in Gosu. Retrieved from https://www.thoughtco.com/mouse-and-keyboard-input-in-gosu-2908025 Morin, Michael. "Mouse and Keyboard Input in Gosu." ThoughtCo. https://www.thoughtco.com/mouse-and-keyboard-input-in-gosu-2908025 (accessed March 28, 2024).