12. THE ROOMS
room open, close, update callbacks




Room open and close

While moving from room to room, the player can trigger a few events and special handlers are called. Again, these handlers can call callback functions, specific to the current room, if they are implemented by the developer.

This is very usefull, because sometimes you must know when you enter a specific room, to initialize some objects inside, to display a message, or even to deny entering (or exiting), if certain conditions are not met.

HandlerRoomOut()
This handler is called by the engine when the player wants to exit the current room. It will call the OutRoom_RX_RY() non-latent callback, if implemented. In this callback, developers can move the player to a different position, preventing him from exiting the room. Or, they can teleport him to a totally different room, than the one expected. This callback can request a latent function if needed.

HandlerRoomClose()
This handler is called by the engine when the player exits a room, before the next room is opened. It will call the CloseRoom_RX_RY() non-latent callback, if implemented. In this callback, developers can change various objects if needed. They should not change the player's position. Requesting a latent function from this callback is NOT recommended.

HandlerRoomOpen()
This handler is called by the engine when the player enters in a new room, immediately after the previous room was closed. It will call the OpenRoom_RX_RY() non-latent callback, if it's implemented. In this callback, developers can initialize various objects from the room, or reposition the player. This callback can request a latent function if needed.

RX and RX from the callbacks names are the room's coordinates in the rooms matrix. Room 0,0 is the first room in the world, in the top left corner. Next one to the right is room 1,0 and so on. You can see these room's coordinates in the map editor.


Start from the default template data and add the following callback in the game.gs file. Since it is a non-latent callback, it can't call the Message function directly. It requests a latent execution of another function and the message is placed there.



Now try the OutRoom callback as well. Add the following code that will prevent the player from exiting the initial room.




Room update

A special update handler is called each game cycle. A game cycle, also called frame, represents one game update. In DizzyAGE games, it happens about 37 times per second. This number is called FPS (frames per second).

It can be used to update various objects that must move in the current room, like elevators, platforms, spiders etc. Some of these objects can be updated each game cycle, but some of them can be update only once in two or three game cycles.

HandlerGameUpdate()
This handler is called by the engine each game's cycle. If the game is not paused, it will call the UpdateRoom_RX_RY() non-latent callback, if implemented. In this callback, developers can update and move various objects, usually situated in the current room. This callback can request a latent function if needed.

Start from the default template data. Add a dynamic brush in the map, representing a little bat (tile=151, x=504 y=208, type=dynamic, id=1000, collider=call handler, class=hurt).
In the game.gs add the following callback and run the game.

This is the simplest way of moving an object on the update callback. It's horizontal coordinate is incremented until a specific position and then it's set back at the begining.



GameFrame()
This function, exported by the engine, returns the game cycle as an incrementing number. It can be used to perform the update of some objects, only once in two frames, or three frames, etc.

IsUpdate( delay )
This helping function from utils.gs uses GameFrame() to tell if the game cycle is multiple of the delay parameter. It returns 1 if so, and it can be used to restrict the object's update, only once each delay frames.

Note that you can adjust the speed of a moving object, either by updateing it more rarely, allowing more game cycles to pass between it's updates, or by changing the moving step, in pixels. Bigger steps means faster but less smoother movements. The player is updated once each 3 frames and have a 4 pixels horizontal step.

Let's try to extend the bat's movement to the second room as well. Instead of limiting it's horizontal coordinate to 696 (the right side of the first room), let it go up to 920 (the right side of the second room). In case you're still wondering how I get these numbers... it's from the editor, by moving the bat (or the mouse cursor) in the desired position and reading the displayed coordinates. Save the script and run the game. After it exits the first room wait for it there and see how it apears again, after a little while, time spent to travel the second room.

If you go to the second room and expect to see the bat moving there, you are wrong. The second room doesn't have an update callback, and the one from the first room is no longer called, since you are not in that room anymore. So let's adjust the script, to fix that.



ObjPresent( idx )
This function, exported by the engine, presents the object with the specified index, to the current room.

To gain performance, the engine updates and paints only the objects present in the current room. This list of dynamic brushes is build when the players enters the room. If an object is relocated in the room, after that, like an item being dropped down or a moving object from another room, this object has to be presented to the room, to be added to the update and draw list.

Failing to use this function when needed, may result in the object not being visible until the room is renetered.

On rare occasions, there are things that require update, no matter in which room the player is. These updates must be called directly from the HandlerGameUpdate itself. However, almost all moving objects are to be updated from the rooms where they may be located.


Homework

Add a little mouse, moving back and forth, between the two rooms, reversing it's direction when the end of path is reached. Use the mouse from tile=150, map=(71,19,104,30). Update it from two to two frames, to make it walk faster than the bat, and try to flip it to look in the right direction. You can consider the moving direction as the O_FLIP property dictates (0=right, 1=left).

Here is a possible solution.