# New tile based platform engine – part 10 – optimization, doors n’ keys

Here we are with some optimization, as well as a feature some people requested: doors and keys.

Optimization

See how does the script at step 9 determine if a tile is walkable (player can pass through it):

`if ((top_right != 0 and top_right != 5 and top_right != 6 and top_right != 7) or (bottom_right != 0 and bottom_right != 5 and bottom_right != 6 and bottom_right != 7)) {`

I have to check if all values are different from `0`, `5`, `6` and `7` because 0 = empty, 5 = cloud, 6 = ladder and 7 = trampoline.

Nothing difficult at this point, but let’s imagine I am going to add another walkable tile… I should update the `and` formula by adding the new tile type.

The more walkable tiles I add, the more the probability of making errors or forgetting something.

So I created an array with all walkable tiles this way:

`walkable_tiles = Array(0, 5, 6, 7);`

Then the old code becomes

`if (!is_walkable(top_right) or !is_walkable(bottom_right)) {`

Where `is_walkable` is basically an `in_array` function (not included in AS2!!)

```function is_walkable(tile) {
walkable = false;
for (x=0; x
Doors and keys
A door is a unwalkable tile that becomes a walkable one when the player takes its key.
Every key is an array made this way:
`[key x pos, key y pos, door x pos, door y pos]`
Meaning that the key is located at (`key x pos`, `key y pos`) and once collected opens the door at (`door x pos`, `door y pos`).
Let's see the source:
walkable_tiles = Array(0, 5, 6, 7);
tile_size = 20;
ground_acceleration = 1;
ground_friction = 0.8;
air_acceleration = 0.5;
air_friction = 0.7;
ice_acceleration = 0.15;
ice_friction = 0.95;
max_speed = 3;
xspeed = 0;
yspeed = 0;
falling = false;
gravity = 0.5;
jump_speed = 6;
climbing = false;
climb_speed = 0.8;
level = new Array();
enemy = new Array();
coin = new Array();
key = new Array();
level[0] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
level[1] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
level[2] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 1];
level[3] = [1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[4] = [1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[5] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[6] = [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 0, 1];
level[7] = [1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1];
level[8] = [1, 1, 1, 1, 0, 9, 0, 0, 0, 5, 5, 0, 0, 0, 7, 0, 0, 6, 0, 0, 0, 0, 7, 0, 1];
level[9] = [1, 1, 1, 1, 1, 1, 1, 2, 2, 8, 8, 8, 8, 1, 1, 3, 3, 1, 4, 4, 1, 8, 1, 8, 1];
player = [4, 8];
enemy[0] = [10, 3, -2];
enemy[1] = [3, 3, -2];
coin[0] = [2, 2];
coin[1] = [23, 4];
key[0] = [1, 5, 5, 8];
function create_level(l) {
_root.createEmptyMovieClip("level_container", 1);
level_height = l.length;
level_width = l[0].length;
for (y=0; ymax_speed) {
xspeed = max_speed;
}
if (xspeed0) {
if ((bottom_right != 0 and bottom_right != 6) or (bottom_left != 0 and bottom_left != 6)) {
// not a cloud...
if (bottom_right != 5 and bottom_left != 5) {
// a trampoline
if ((bottom_right == 7 or bottom_left == 7) and (Math.abs(yspeed)>1)) {
yspeed = yspeed*-1;
jumping = true;
falling = true;
} else {
y_pos = bottom*tile_size-9;
yspeed = 0;
falling = false;
jumping = false;
}
} else {
//cloud
if (prev_bottom0) {
if (!is_walkable(top_right) or !is_walkable(bottom_right)) {
x_pos = right*tile_size-6;
xspeed = 0;
}
}
prev_bottom = bottom;
}
function get_edges() {
// right edge
right = Math.floor((x_pos+5)/tile_size);
// left edge
left = Math.floor((x_pos-6)/tile_size);
// bottom edge
bottom = Math.floor((y_pos+8)/tile_size);
// top edge
top = Math.floor((y_pos-9)/tile_size);
top_right = level[top][right];
top_left = level[top][left];
bottom_left = level[bottom][left];
bottom_right = level[bottom][right];
}
function place_player() {
level_container.hero.removeMovieClip();
x_pos = player[0]*tile_size+tile_size/2;
y_pos = player[1]*tile_size+tile_size/2+1;
level_container.attachMovie("hero", "hero", _root.level_container.getNextHighestDepth(), {_x:x_pos, _y:y_pos});
}
function is_walkable(tile) {
walkable = false;
for (x=0; x
And this is the game:

```
215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 10000000
// 2 Cars
// 2048
// Avoider
// Ballz
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Breakout
// Bricks
// Columns
// CubesOut
// Dots
// DROP'd
// Dudeski
// Eskiv
// Filler
// Fling
// Globe
// HookPod
// Hundreds
// InkTd
// Iromeku
// Lumines
// Magick
// MagOrMin
// Maze
// Memdot
// Nano War
// Nodes
// o:anquan
// Ononmin
// Pacco
// Phyballs
// Platform
// Poker
// Pool
// Poux
// Pudi
// qomp
// Racing
// Renju
// SameGame
// Security
// Sling
// Slingy
// Sokoban
// Splitter
// Sproing
// Stack
// Stairs
// Stringy
// Sudoku
// Tetris
// Threes
// Toony
// Turn
// TwinSpin
// vvvvvv
// Wordle
// Worms
// Yanga
// Zhed
// zNumbers