14. STATIC BRUSHES
static brushes, materials, example




The material map

So far you accessed only dynamic brushes. But in a map there are a lot of static brushes and, even if they are static, there are times when you need to access some of them too.

A very important thing about static brushes is that they can write in the material map, and instruct the game about where the player can stay or where he must fall. Actaully this is the main reason why the static brushes are accessed during the game.


Start the default template game and press F4 once. You can see the material map, where brushes are painted with special colors, representing their assigned materials. You will see how the walls, red before, are now green, showing their blocking material. Pressing F4 again will display the density of materials. Another F4 press will request the engine not to draw anything. And, another F4 press, will bring everything to normal. This F4 feature is available in developer mode only (dev=1 in dizzy.ini) and should not be activated in released games. The developer mode is marked in the top left corner of the screen and it is set as active in the default template.

Now, it's time for a little bath. An acid bath!
Start from the default template data and add a static brush, representing the animated water (tile=148), with the material hurt set to it and the delay=3. Make sure the draw property is set to 3, to make it write both on screen and in the material map.

Place it under the DizzyAGE logo, as in the picture below. Add a blocking boulder too, that you can pick from a wall (with right or middle mouse button).

Save the map and run the game. Try the water!.
See with the how the water is painted orange in the material map (F4), showing it's hurt material.


Brush properties

Accessing static brushes is very similar to accessing dynamic brushes. Another set of defines is exported for their properties and you must not mix them with the ones for objects:
B_LAYER, B_X, B_Y, B_W, B_H, B_TILE, B_FRAME, B_MAP, B_FLIP, B_COLOR, B_SHADER, B_SCALE, B_ID, B_MATERIAL, B_DRAW, B_DELAY, B_ANIM

BrushFind(id)

This function, exported by the engine, is used to search a static brush from the map, by it's unique id property. If a brush with the specified id exists, it returns the integer index in the internal list of static brushes. This index is used in other brush access functions exported from the engine. If there's no brush with the specified id in the map, this function returns -1.

BrushGet(idx,property)

This function, exported by the engine, is used to get the integer value of a property of a static brush. It uses the brush's internal index obtained with the BrushFind function. The property parameter is the integer value representing the brush's property and it's usually specified using the exported defines, like B_X, B_Y, B_ID, B_MATERIAL, etc.

BrushSet(idx,property,value)

This function, exported by the engine, is used to set the integer value of a property of a static brush. It uses the brush's internal index obtained with the BrushFind function.


While working with static brushes in the script, you must remember that you must not move or resize (actually little movements or sizeing inside their room is permited). Like with dynamic brushes, you should not change the brush's id properety. The properties you will usually need to change are the B_DRAW and maybe the B_MATERIAL.


The door puzzle

A very nice example of working with static brushes is the door puzzle, where you must open a door that blocks your path.

The collision with static brushes is very precise, because the material map allows a pixel perfect testing. Because of that, the blocking with static brushes is better than the blocking with dynamic objects set as a hard colliders. So, our door will be a static brush.

Start from the default template data and try to construct the above scene, as folows:

Build the house of static blocking brushes (draw=3, material=block), except the right wall coresponding to the door (draw=1, material=air).

Add an open version of the door, tile=123, type=static, and set it invisible, draw=0, material=air. Set the id=2000 and place it as in the picture.

Add a closed version of the door, tile=123 (the left side of the open door), draw=3, material=block. Set the id=2001 and place it over the opened door, near the right wall.

Add a trigger, for interaction, tile=0, color=800000ff (transparent), type=dynamic, draw=0, class=action. Set the id=1000 and place it over the opened door, like in the picture. You can use different layers for these overlapping brushes, for easy editing.

Now save the map. In gamedef.gs set PLAYER_BEGINX to 680, to have the player spawned a little to the right. Add the folowing action callback, coresponding to the trigger.



It will deal with opening and closing the door, by hiding and showing the right static brushes. The logic state of the door is stored in the trigger's O_STATUS property, for easy access.
It also tests not to close the door while standing in the way, because it would place the player directly into collision (try it if you're curious).

After one or more brushes are altered to write or not write in the material map, a refresh command is needed, so the engine can repaint the new material map. If this command is not sent, the material map will not be updated until the room is reentered.

GameCommand( CMD_REFRESH )
It requests the repainting of the material map, and should be called after one or more brushes have the been changed in a way that affects the material map.



Homework

Add a little complexity to the door puzzle, by needing a key item to unlock the door. You can store the lock status in the O_USER property of the trigger. Opening the door, before unlocking it, must not be possible.

Try your best, then
see our solution.

Also play a little with other kind of materials, like soft clouds, or killer flames.