-
Notifications
You must be signed in to change notification settings - Fork 9
Events
Events within Metro are predominately user input from the various input devices available. However, they also include global notifications that can be generated by scenes or model objects within the game.
A scene or model can respond to the following events:
-
All possible Keyboard, Gamepad, and Mouse Events can be found in the Gosu Documentation
-
Keyboard button, gamepad button, or mouse button down events or on_down.
This is the first event that is generated when a user presses the button down.
class Hero < Metro::Model
event :on_down, KbSpace, KbA do
jump
end
end
- Keyboard button, gamepad button, or mouse button held events or on_hold, on_held.
This is the second event that is generated when a user holds a button down. This event will continue to trigger while the button is held down.
class Hero < Metro::Model
event :on_hold, KbB do
accelerate
end
end
- Keyboard button, gamepad button, or mouse button up events or on_up.
This is the third event that is generated when a user releases a down/held button.
class ExampleScene
event :on_up, KbEsc, KbDelete do
transition_to :menu
end
end
This event is generated with each update and allows you to respond to the current mouse position
class ExampleScene
# This event fires with each game update
event :on_mouse_movement do |event|
hero.position = event.mouse_point
end
def show
# To see the mouse cursor for troubleshooting
window.show_cursor
end
end
Often times a particular keyboard button, gamepad button, or mouse button or several inputs may be used repeatedly throughout a game to represent a common action like: 'confirmation'; 'cancel'; 'back'; or 'forward'. It is suggested in those cases to reduce the redundancy and define a control within your game configuration.
In this example, when any input defined as the cancel control has been performed, perform the action associated with the event.
class BrandToTitleScene < GameScene
event :cancel do
transition_to :title
end
end
Within the game configuration a cancel control is defined as any button up event for several keyboard buttons.
controls do
cancel is: :button_up, with: [ KbEscape, KbDelete ]
end
A scene or model may subscribe to a global notification. A global notification has a uniquely defined named. Any scene or model may generate a global notification. All scenes and models subscribed will be alerted and execute the associated action.
In this example the score board registers for any notifications of stars being collected:
class ScoreBoard < Metro::Model
property :ding, type: :sample, path: "pickup.wav"
property :score, default: 0
event :notification, :star_collected do
ding.play
self.score += 1
end
end
This event would be generated by another model which determines if the player is close enough to collect the star:
class StarCollectionMonitor < Metro::Model
attr_accessor :player, :star_generator
def update
living_stars = star_generator.living_stars
stars_player_is_close_enough_to_collect = living_stars.find_all {|star| Gosu.distance(player.x, player.y, star.x, star.y) < 35 }
stars_player_is_close_enough_to_collect.each do |star|
star.collapse
notification :star_collected
end
end
end
Both scenes and models can register for events. When a scene or model receives the event, it does not exclude another resource from also receiving the same event.
The signature of input events use the pattern:
event (:on_down|:on_up|:on_held|:on_hold), Input, Input Input do
# course of action to take when event is true
end
The signature of control events use the pattern:
event CONTROL_SYMBOL_NAME do
# course of action to take when event is true
end
The signature of notification events use the pattern:
event :notification, NOTIFICATION_SYMBOL_NAME do
# course of action to take when event is true
end
All of the previously defined examples show registration where a block has been provided as the course of action. This is common way of defining a course of action that should take place if an event.
class Hero < Metro::Model
event :on_down, KbSpace do
jump
end
end
An alternative to this format is to provide a block which accepts a single parameter. The parameter is an EventData object which contains information about the event as well as the state of other buttons or modifier keys.
An example of this is used to determine if any Ctrl key is being held while the keyboard button R is being pressed down and then released:
class Game
event :on_up, KbR do |event|
if event.control?
Metro.reload!
transition_to scene_name
end
end
end
Input related events may also be defined without a block and instead with an additional key-value parameter added to the definition do: :method_name_to_execute
:
class Hero < Metro::Model
event :on_down, KbSpace do: :jump
def jump
# jump is executed when the Keyboard Space key is pressed down
end
end
Notifications can alternatively be defined with a block that accepts 1 parameter or 2 parameters. The first parameter is the sender of the event. When the sender is unknown an UknownSender is present. The second parameter is the name of the notification.
Our previous notifications example could have been defined like the following:
class ScoreBoard < Metro::Model
property :ding, type: :sample, path: "pickup.wav"
property :score, default: 0
event :notification, :star_collected do |sender,event_name|
ding.play
puts "Score updated by #{sender}"
self.score += 1
end
end
Or with a second parameter:
class ScoreBoard < Metro::Model
property :ding, type: :sample, path: "pickup.wav"
property :score, default: 0
event :notification, :star_collected do |sender,event_name|
ding.play
puts "Score updated by #{sender} which sent #{event_name}"
self.score += 1
end
end