New tile based platform engine – part 6 – ladders

It’s time to introduce ladders.

Ladders are quite hard to do for one reason: there is a lot of ways of intending ladders.

Can the player jump when on a ladder?

Should a ladder act as a hole if the player walks on it?

These are only two of the many questions you may ask about ladders.

So I have to made some rules:

1) Player climbs the ladder up and down using UP and DOWN arrows

2) Player can jump when on a ladder

3) If the player is falling and encounters a ladder, he will keep falling until he presses UP or DOWN

4) Player can climb a ladder if at least one of its corners is in the ladder

This is the actionscript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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;
treadmill_speed = 2;
max_speed = 3;
xspeed = 0;
yspeed = 0;
falling = false;
gravity = 0.5;
jump_speed = 6;
climbing = false;
climb_speed = 0.8;
level = 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[4] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[5] = [1, 0, 0, 0, 0, 0, 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, 0, 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, 0, 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, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1];
level[9] = [1, 1, 1, 1, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 1, 1];
player = [5, 1];
function create_level(l) {
	_root.createEmptyMovieClip("level_container", 1);
	level_height = l.length;
	level_width = l[0].length;
	for (y=0; y<level_height; y++) {
		for (x=0; x<level_width; x++) {
			if (l[y][x] != 0) {
				t = level_container.attachMovie("tile", "t"+y+"_"+x, _root.level_container.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
				t.gotoAndStop(l[y][x]);
			}
		}
	}
	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});
}
create_level(level);
_root.onEnterFrame = function() {
	ground_under_feet();
	walking = false;
	climbing = false;
	if (Key.isDown(Key.LEFT)) {
		xspeed -= speed;
		walking = true;
	}
	if (Key.isDown(Key.RIGHT)) {
		xspeed += speed;
		walking = true;
	}
	if (Key.isDown(Key.UP)) {
		get_edges();
		if (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6) {
			jumping = false;
			falling = false;
			climbing = true;
			climbdir = -1;
		}
	}
	if (Key.isDown(Key.DOWN)) {
		get_edges();
		if (over == "ladder") {
			jumping = false;
			falling = false;
			climbing = true;
			climbdir = 1;
		}
	}
	if (Key.isDown(Key.SPACE)) {
		get_edges();
		if (!falling and !jumping) {
			jumping = true;
			yspeed = -jump_speed;
		}
	}
	if (!walking) {
		xspeed *= friction;
		if (Math.abs(xspeed)<0.5) {
			xspeed = 0;
		}
	}
	if (xspeed>max_speed) {
		xspeed = max_speed;
	}
	if (xspeed<max_speed*-1) {
		xspeed = max_speed*-1;
	}
	if (falling or jumping) {
		yspeed += gravity;
	}
	if (climbing) {
		yspeed = climb_speed*climbdir;
	}
	if (!falling and !jumping and !climbing) {
		yspeed = 0;
	}
	xspeed += bonus_speed;
	check_collisions();
	level_container.hero._x = x_pos;
	level_container.hero._y = y_pos;
	xspeed -= bonus_speed;
};
function ground_under_feet() {
	bonus_speed = 0;
	left_foot_x = Math.floor((x_pos-6)/tile_size);
	right_foot_x = Math.floor((x_pos+5)/tile_size);
	foot_y = Math.floor((y_pos+9)/tile_size);
	left_foot = level[foot_y][left_foot_x];
	right_foot = level[foot_y][right_foot_x];
	if (left_foot != 0) {
		current_tile = left_foot;
	} else {
		current_tile = right_foot;
	}
	switch (current_tile) {
	case 0 :
		speed = air_acceleration;
		friction = air_friction;
		falling = true;
		break;
	case 1 :
		over = "ground";
		speed = ground_acceleration;
		friction = ground_friction;
		break;
	case 2 :
		over = "ice";
		speed = ice_acceleration;
		friction = ice_friction;
		break;
	case 3 :
		over = "treadmill";
		speed = ground_acceleration;
		friction = ground_friction;
		bonus_speed = -treadmill_speed;
		break;
	case 4 :
		over = "treadmill";
		speed = ground_acceleration;
		friction = ground_friction;
		bonus_speed = treadmill_speed;
		break;
	case 5 :
		over = "cloud";
		speed = ground_acceleration;
		friction = ground_friction;
		break;
	case 6 :
		over = "ladder";
		speed = ground_acceleration;
		friction = ground_friction;
		break;
	}
}
function check_collisions() {
	y_pos += yspeed;
	get_edges();
	// collision to the bottom 
	if (yspeed>0) {
		if ((bottom_right != 0 and bottom_right != 6) or (bottom_left != 0 and bottom_left != 6)) {
			if (bottom_right != 5 and bottom_left != 5) {
				y_pos = bottom*tile_size-9;
				yspeed = 0;
				falling = false;
				jumping = false;
			} else {
				if (prev_bottom<bottom) {
					y_pos = bottom*tile_size-9;
					yspeed = 0;
					falling = false;
					jumping = false;
				}
			}
		}
	}
	// collision to the top                           
	if (yspeed<0) {
		if ((top_right != 0 and top_right != 5 and top_right != 6) or (top_left != 0 and top_left != 5 and top_left != 6)) {
			y_pos = bottom*tile_size+1+8;
			yspeed = 0;
			falling = false;
			jumping = false;
		}
	}
	x_pos += xspeed;
	get_edges();
	// collision to the left           
	if (xspeed<0) {
		if ((top_left != 0 and top_left != 5 and top_left != 6) or (bottom_left != 0 and bottom_left != 5 and bottom_left != 6)) {
			x_pos = (left+1)*tile_size+6;
			xspeed = 0;
		}
	}
	// collision to the right                                                  
	if (xspeed>0) {
		if ((top_right != 0 and top_right != 5 and top_right != 6) or (bottom_right != 0 and bottom_right != 5 and bottom_right != 6)) {
			x_pos = right*tile_size-6;
			xspeed = 0;
		}
	}
	x_pos = Math.round(x_pos);
	y_pos = Math.round(y_pos);
	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);
	// adjacent tiles
	top_right = level[top][right];
	top_left = level[top][left];
	bottom_left = level[bottom][left];
	bottom_right = level[bottom][right];
}

and this is the result

Any game on the horizon? I am making one…

Download the source code and enjoy.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (24 votes, average: 4.75 out of 5)
Loading ... Loading ...
If you found this post useful, please consider a small donation.
» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

25 Responses

  1. David D says:

    This is awesome! But is this the last part? You should add some spikes or something that would kill the player. And maybe comment on the code?

  2. dix huit says:

    Top banana! Any news on the WordPress plugin Emanuele?

  3. Dean Watts says:

    Is this the last one?
    Its awesome but we need enemies!

  4. Prankard says:

    Looks really impressive. A good engine so far in only 6 steps with lots of possibility.

    Found a small glitch, when you run off the edge (where the ladders are) you can easily get back up on the ledge even when your falling off by running back towards it in mid-air.
    I guess this could be fixed by having another side hitTest nearer his feet.

  5. Good job!!!!!
    But…I’m waiting in actionscript 3.0!!!!

  6. sam says:

    i think this is a great engine and just what i need for my next game. this will be my first attempt at a tile based game but this tutorial will help me greatly.

    things that could possibly be added…
    spikes,enemys(plus kill, maybe by jumping on them.),left/right/jump animations,scrolling background.

    with those added it will be an absoloutly brillantant game.

    please reply if your do plan to add any of these features.

  7. Kevin says:

    Found another glitch. While climbing down the ladder it’s possible to move left or right and still be climbing downwards as long as you continue to hold the down button.

    Still, amazing work, it’s looking great so far. :)

  8. Enrique David says:

    Hi, i sugest you… that check collision in ladder when the player jumo and going down… isn’t ?

  9. Justin says:

    Yes, please do another step where the player dies…

    IE: Spikes

  10. JL says:

    This series of tutorials is fantastic.
    I see so many possibilities.
    Thank you!!!

  11. bigbill says:

    Great stuff but I’m having issues, I you move to the right hand side of the screen and jump, you seem to get stuck on the wall. Any idea to fix this? Thnaks

  12. Bob says:

    From one game developer to another I’ll thank you again for doing this. You are an incredible coder and I’ve been following your work for a long time. Thanks a ton and get some sleep!

  13. faaa says:

    i don’t know if its a bug but you can walk on top of the ladder without falling,but if you jump the ladder become a “hole” and you’ll fall

  14. matt says:

    One glitch is that you can float slowly downwards if you hold down and the last tile you touched is a ladder tile.

  15. Questo says:

    Another glitch If you jump and the top of your character hits a grey tile while still touching a ladder you float in midair until you aren’t touching ladder anymore. By the way this engine is awsome but for some reason if I make a square who is center aligned the hittests are way off. Do I need to make it to the exact dimensions of the one you have?

  16. martin says:

    many thanks, it’s very useful

  17. Jai says:

    maybe, when going up ladders, it would be a good idea that you could only stay suspended on a ladder for a certain amount of time, or you fall down…?
    Good tutorial :)

  18. Andrius says:

    One of the best tutorials here! I have looked ~75% of your flash tutorials and I like the most of ‘em’. I’m making a little game for this. I made now exit and falling function (when you fall out from level). And I know i can make enemies and something like pipes so you only hit them from left and right so you can go downwards trough them. But yea, ladders have some bugs.

  19. CoryMathews says:

    Looking great man. This is one of your best sets of tutorials. Really enjoying reading these keep em up.

  20. [...] the AS3 translation of AS2 part 6, it’s time to introduce [...]

  21. Andrius says:

    My spike code:

    where you add tile add this:

    case 1 :
    over = “ground”;
    x_pos = 40
    y_pos = 40
    break;

    It’s exaple, change x and y of player by detecting em using variables. That’s how I also do falling:

    if(y_pos >140 ){
    y_pos = 40
    x_pos = 40
    }

    It’s easy.

    • Evan says:

      I can’t find the AS3 code where the “ladder bug” was fixed. I thought that maybe all I would have to do is make the:

      if (Key.isDown(Key.DOWN)) {
      get_edges();
      if (over == “ladder”) {
      jumping = false;
      falling = false;
      climbing = true;
      climbdir = 1;
      }
      }

      Turn into:

      if (press_down)
      {
      get_edges();
      if ((over == “ladder”) || (top_right == 6 || bottom_right == 6 || top_left == 6 || bottom_left == 6))
      {
      jumping = false;
      falling = false;
      climbing = true;
      climbdir = 1;
      }
      }
      this does not work either. :( I really want to use this tile based idea but being able to make different tile images for the ladder is very important for what I am making. Thanks for responding before!

      Evan

  22. [...] bug appeared in part 6 and was fixed in part [...]

    • Evan says:

      I am trying to add a second type of ladder. This ladder is the exact same thing but the image is of a different color of ladder. I simply made it on frame 8 of the block movie clip and added the case 8 code that is the exact same as the case 7 code in the as file. It does not work. With trace statements all the code is running right but the character does not move up or down when it hits the new ladder block any ideas?

Leave a Reply