-
Notifications
You must be signed in to change notification settings - Fork 0
Demo 02 Construction
Demo 02 contains a reasonably complex logic system to force the player to collide with 4 entities 3 times in a row. The logic for the "laps" the player must run relies heavily on the Save system.

After the player moves into the level they are prompted with a Dialog with a couple choices about enabling weapons. It should be noted that this entity does not define a sid. Each time the player enters the level and collides with the entity the Dialog will attempt to appear.
| Setting | Value |
|---|---|
| dialog | demo02.weapons |
Dialogs.demo02.weapons =
{
s:
{
base:speakerBase,
winex: [ Windows.face ],
r:{i:[ ['i','we', '==0'] ]} // requirement for showing the dialog, blocking if weapons are already enabled
},
sa:
[
{ // without any specific requirements the main state will be defaulted to each time the dialog is shown
n:'main',
t:"Do you want weapons enabled before you take the big jump?",
o:
[
{
t:"Yes!",
a:{sv:[ ['i','we', 1] ], k:true} // enable weapons and kill the Showdialog entity
},
{
t:"Nope!",
ns:'confirm'
}
]
},
{
n:'confirm',
t:"Are you sure you don't want weapons enabled before you take the big jump?",
o:
[
{
t:"Yes!",
a:{k:true} // just kill the Showdialog entity
},
{
t:"Nope!",
ns:'main'
}
]
}
]
}
For fun there are a couple of time adjust entities to make the jump at the start of the level more dramatic/cinematic. Timeadjust is not a very complex entity but fun to have around... Each of the given Timeadjust entities sets the time rate to a value based on the required state of the game.
| Setting | Value |
|---|---|
| timerate | 1 |
The 3 Laps activity requires a number of logic checks across all 4 flags and the Showdialog settings. In conjuction the player repeats the same sequence with a goal of completing the sequence 3 times.
The core of the logic centers around two save flags for tracking the player's actions.
| Flag | Partition | Description |
|---|---|---|
| llap | t | Tracks which lap the player is on (0 based) |
| lflag | t | Tracks which flag needs to be next collected |
The use of the t partition indicates that the Save flags will be discarded on level load automatically.
Each of the flag is a basic Thing entity using a slightly different definition.
Sample:
| Setting | Value |
|---|---|
| thing | demo02.redFlagOne |
The flag data is configured to take action under very specific conditions. Below is the first flag (four are defined in the actual data). It is important to note that the names of the states are not important. They only need to be unique. The animation system associated with a Thing entity automatically determines the state based on requirements. Any time the Save system is updated the animation state is evaluated. This way the flags change states based on the value of the llap and lflag values.
Things.demo02.redFlagOne =
{
ao:
{
i:'redflag',
w:16,
h:16,
a:
[
{ // highlighted state to indicate the item should be collected
n:'collect',
r:{i:[ ['t','lflag','==1'],['t','llap','<3'] ]},
a:{sv:[ ['t','lflag',2] ]},
ft:1,
seq:[0]
},
{ // default state
n:'idle',
ft:1,
seq:[1],
d:true // special flag for things to indicate that no further collision checks are required
}
]
}
}
The associated dialog is used throughout the lap run to indicate status and control the state of the lap. The inclusion of the sid is one approach to disabling the re-use of the Dialog. The collection of the fourth flag actually resets the value so the last state of the dialog can be shown. After all the laps are completed the entire process cannot be started again due to save flags.
| Setting | Value |
|---|---|
| dialog | demo02.lap |
| sid | dlg.lap |
The lap Dialog has a variety of very specific states to control what is shown when (if at all).
Dialogs.demo02.lap =
{
s:
{
base:speakerBase,
winex: [ Windows.face ]
},
sa:
[
{ // first state when no laps have been run or any flags have been collected
t:"Let's have you run 3 laps. Follow the flags (red indicates the next to collect).",
r:{i:[ ['t','llap','==0'],['t','lflag','==0'] ]},
a:{sv:[ ['t','lflag',1] ]}
},
{
t:"Nice Lap! Let's make this more fun! LASERS!",
r:{i:[ ['t','llap','==1'],['t','lflag','==0'] ]},
a:{sv:[ ['t','lflag',1]]}
},
{
t:"One more to go!",
r:{i:[ ['t','llap','==2'],['t','lflag','==0'] ]},
a:{sv:[ ['t','lflag',1] ]}
},
{
t:"Way to go! I'll open the door and give you 100 points for fun!",
r:{i:[ ['t','llap','==3'],['t','lflag','==0'] ]},
a:{sv:[ ['t','lflag',1], ['i', 'pt', 100], ['demo02', 'gate', 1] ], k:true}
}
]
}
The blasters are configured to fire based on a Requirements object.
Sample:
| Setting | Value |
|---|---|
| projectile | greenLaser |
| reqs | lapBlaster |
| face | l |
Note: face only applies to the left facing blaster.
The blasters are configured to only fire on certain laps. There are various possible approaches but this one used the existing variables for lap tracking.
Requirements.lapBlaster =
{
l:'or',
i:[ ['t','llap','==1'],['t','llap','==2'] ]
}
The locked door is tied heavily to entities written specifically for the purpose of toggling a door via a switch. In Demo 03 there is an example of a less rigid approach allowing for a bit more flexibility in controlling the state of an entity.
The door is just a basic animation object that uses a sid value to manage the state of the door. Internally a door is driven by the values of a switch entity. The door entity manages its own collision based on active animation state name.
| Setting | Value |
|---|---|
| thing | door.generic |
| sid | gate |
Things.door.generic =
{
ao: // animation object
{
i:'gate', // image name ('media/' is prepended)
w:16,
h:32,
a: // array of animation states
[
{
n:'closed',
b: { x:2, y: 32},
ft:1, // frametime
seq:[1] // sequence
},
{
n:'open',
ft:1, // frametime
seq:[0] // sequence
}
]
}
}
The switch is an entity that manages the toggling of Save flags via state/value. Its own state is also managed by the given sid value. The Interact component is primarily an animation object with the addition of the v property to indicate what the current value of the Save flag is in the given state.
| Setting | Value |
|---|---|
| interact | switch.generic |
| sid | gate |
Interacts.switch.generic =
{
ao:
{
i:'switch',
w:16,
h:16,
a:
[
{
n:'off',
ft:1,
seq:[0],
v:0 // extra property used by switch entities
},
{
n:'on',
ft:1,
seq:[1],
v:1 // extra property used by switch entities
}
]
}
}