Doors
This tutorial describes how to use a door in a room.
Step 1: Draw the doorway into the picture

Draw the doorway as if there is no door there, and you can see
into the room behind the door. Also make sure there is a blue
control line in front of the doorway so the player can't walk
through it when the door is there. If the door is on the left or
right wall (as in this example), the edge of the door closest to
the front of the screen should be at the bottom of a priority
band, and the wall beside it should be given the appropriate
priority. This is so when the player walks through the door, they
are hidden behind the wall but they can be seen when they walk in
front of the wall.
We will place an object on top of the doorway, which will be
used to show the door (either open or closed).
Step 2: Create a view for the door
The next thing to do is to create a view which will represent
the door. The first cel in the view (cel 0) should show the door
closed. The next few cels should show the door opening, and the
last cel should show the door fully opened.

Note that I have only drawn the door itself, not the door
frame. This is mainly because the left side of the door frame has
a different priority to the rest of the door.
Now we have all the graphics we need. The next thing to do is
to program the door into the room.
Step 3: Setting up the door object
We will place an object on screen which will show the door. We
will call this object "door", so we have to define
"door" as an object. At the top of the logic, put the
following line:
#define door o1
I have used object 1 here but you may need to use a different
object number of you have another object with that number.
We must now put some code in the initialization section to set
up the object:
animate.obj(door);
load.view(3);
set.view(door,3);
set.loop(door,0);
set.cel(door,0);
position(door,24,118);
ignore.blocks(door);
ignore.objs(door);
set.priority(door,4);
stop.cycling(door);
draw(door);
The first 6 lines basically say the following: I want to use
the door object. Load view 3 into memory and assign it to the
door. I initially want to display cel 0 of loop 0, and position
the bottom-left corner of the door at 24,117.
The ignore.blocks command tells the door object to ignore
obstacles such as blue control lines. If this is not used, and
there is a blue control line in the way of the door, it will move
up or down so that it is not touching the line (which wouldn't
look right). The ignore.objs command stops other objects (such as
ego) from being blocked by the door's baseline (bottom row of
pixels). And the set.priority command gives the door a priority
of 4 so that the player will always be in drawn in front of it.
When you first set up an object, it cycles continuously
through the cels in the current loop. Since we only want it on
cel 0 initially, the stop.cycling command is used.
Then finally, we draw the door.
Step 4: Allowing the player to open the door
In order to open the door, the player must walk in front of it
and type "open door". When they do this, an animation
of the door opening will be played (by cycling the cels until the
end of the loop is reached), and then the player will
automatically walk through the doorway and into the next room.
The first piece of code we have to write is to detect whether
the player has said "open door", and if so, test if
they are in the correct position:
if (said("open","door")) {
if (posn(ego,21,112,32,119)) {
.........
}
else {
print("You're not close enough.");
}
}
Of course, the words "open" and "door"
must be present in the WORDS.TOK file.
Now in order to play an animation of the door opening, we will
use the end.of.loop command. This cycles through all the cels in
the current loop until the last one, and then sets a flag. For
this example, I'll give the flag the name
"door_finished_opening" (the following line should go
near the top with the other defines):
#define door_finished_opening f200
(you may have to use a different flag number if f200 is
already in use)
Then, the end.of.loop command goes in place of the ....... in
the previous section of code:
end.of.loop(door,door_finished_opening);
However, before the door opens, we should stop ego from
moving, and prevent the player from controlling it:
stop.motion(ego);
program.control();
So the code for opening the door should look like this:
if (said("open","door")) {
if (posn(ego,21,112,32,119)) {
stop.motion(ego);
program.control();
end.of.loop(door,door_finished_opening);
}
else {
print("You're not close enough.");
}
}
Next we write the code which moves the player through the
doorway once the door has finished opening. To detect when to do
this, we test to see if the flag door_finished_opening is set.
When it is, we use the move.obj command to move ego into a
certain position on the other side of the door. The flag
ego_through_doorway needs to be defined first:
#define ego_through_doorway f201
(This should go up the top with the other defines)
Then, the following code goes in the main part below the
previous block of code:
if (door_finished_opening) {
reset(door_finished_opening); // If door_finished_opening remains set, the
// following code will be executed on every
// cycle (which we don't want).
ignore.blocks(ego); // allow ego to cross the blue control line
move.obj(ego,21,114,1,ego_through_doorway);
}
The move.obj command moves ego to 21,114 with a step size of 1
(i.e. ego moves 1 pixel every cycle) and when ego reaches this
position, the flag ego_through_doorway is set. When this flag is
set, we want to take the player to a new room:
if (ego_through_doorway) {
observe.blocks(ego);
new.room(2);
}
Once all this code is in the logic, the player will be able to
open the door and go through it. There is one final thing we have
to do for this, however, and that is to make sure the two flags
we are using are not initially set. It is possible that one or
both of these was set in the previous room we were in, and if so,
ego might start moving back through the door as soon as the
player enters the room. This potential problem is solved by
resetting both flags in the initialization section:
reset(door_finished_opening);
reset(ego_through_doorway);
At this stage, the room's logic should look something like
this:
// ****************************************************************************
//
// Logic 3: Door tutorial room
//
// ****************************************************************************
#include "defines.txt"
#define door o1
#define door_finished_opening f200
#define ego_through_doorway f201
if (new_room) {
load.pic(room_no);
draw.pic(room_no);
discard.pic(room_no);
set.horizon(50);
animate.obj(door);
load.view(3);
set.view(door,3);
set.loop(door,0);
set.cel(door,0);
position(door,24,118);
ignore.blocks(door);
ignore.objs(door);
set.priority(door,4);
stop.cycling(door);
draw(door);
reset(door_finished_opening);
reset(ego_through_doorway);
draw(ego);
show.pic();
}
if (said("look")) {
print("You are in the room for the door tutorial.");
}
if (said("open","door")) {
if (posn(ego,21,112,32,119)) {
stop.motion(ego);
program.control();
end.of.loop(door,door_finished_opening);
}
else {
print("You're not close enough.");
}
}
if (door_finished_opening) {
reset(door_finished_opening); // If door_finished_opening remains set, the
// following code will be executed on every
// cycle (which we don't want).
ignore.blocks(ego); // allow ego to cross the blue control line
move.obj(ego,21,114,1,ego_through_doorway);
}
if (ego_through_doorway) {
observe.blocks(ego);
new.room(2);
}
return();
|
Step 5: Making the player enter the room through the door
If the player is allowed to go through the door to get into
the next room, then when they come back from the next room they
should be shown coming through the door. For this, we basically
do the reverse of what we did for when they exit the room through
the door.
In the initialization section, we must determine if they have
come from the room that is behind the door (in this example, room
2), and if so, set the door to be initially open, make the player
walk through the doorway, then close the door. For this we will
use two flags, ego_exited_doorway and door_finished_closing, so
these must be defined:
#define ego_exited_doorway f202
#define door_finished_closing f203
They should both be reset in the initialization section:
reset(ego_exited_doorway);
reset(door_finished_opening);
The first bit is done with the following code, placed in the
initialization section just before the draw(ego) command:
if (prev_room_no == 2) {
set.cel(door,4);
position(ego,21,114);
ignore.blocks(ego);
move.obj(ego,31,114,1,ego_exited_doorway);
}
This changes the door to be open, positions ego just behind
the door and starts moving it through the doorway into the room.
Then, in the main part of the room, the following code is
added, which closes the door when ego has finished exiting the
doorway.
if (ego_exited_doorway) {
reset(ego_exited_doorway);
observe.blocks(ego);
reverse.loop(door,door_finished_closing);
}
The door_finished_closing does not actually do anything, but a
flag is required by the reverse.loop command (which cycles
through the cels in reverse until it gets to cel 0, then sets the
flag).
Step 6: Providing a description for the door
The last (and easiest) thing that needs to be done is to
provide a description for the door, so when the player types
"look door" they will get an appropriate response. This
of course is not required, but it makes the game more friendly if
the player can "look" at everything that's in the room.
if (said("look","door")) {
print("There is a red door in the left wall.");
}
The finished room should look something like this:
// ****************************************************************************
//
// Logic 3: Door tutorial room
//
// ****************************************************************************
#include "defines.txt"
#define door o1
#define door_finished_opening f200
#define ego_through_doorway f201
#define ego_exited_doorway f202
#define door_finished_closing f203
if (new_room) {
load.pic(room_no);
draw.pic(room_no);
discard.pic(room_no);
set.horizon(50);
animate.obj(door);
load.view(3);
set.view(door,3);
set.loop(door,0);
set.cel(door,0);
position(door,24,118);
ignore.blocks(door);
ignore.objs(door);
set.priority(door,4);
stop.cycling(door);
draw(door);
reset(door_finished_opening);
reset(ego_through_doorway);
reset(ego_exited_doorway);
reset(door_finished_opening);
if (prev_room_no == 2) {
set.cel(door,4);
position(ego,21,114);
ignore.blocks(ego);
move.obj(ego,31,114,1,ego_exited_doorway);
}
draw(ego);
show.pic();
}
if (said("look")) {
print("You are in the room for the door tutorial.");
}
if (said("look","door")) {
print("There is a red door in the left wall.");
}
if (ego_exited_doorway) {
reset(ego_exited_doorway);
observe.blocks(ego);
reverse.loop(door,door_finished_closing);
}
if (said("open","door")) {
if (posn(ego,21,112,32,119)) {
stop.motion(ego);
program.control();
end.of.loop(door,door_finished_opening);
}
else {
print("You're not close enough.");
}
}
if (door_finished_opening) {
reset(door_finished_opening); // If door_finished_opening remains set, the
// following code will be executed on every
// cycle (which we don't want).
ignore.blocks(ego); // allow ego to cross the blue control line
move.obj(ego,21,114,1,ego_through_doorway);
}
if (ego_through_doorway) {
observe.blocks(ego);
new.room(2);
}
return();
|