091 : Cleaning up
Balthazar:
Before we add new levels we should clean up the level creation code so that it is easy to create new levels.
You:
"Clean up" sounds like a fancy way of saying that I'm going to make a lot of changes, but I'm not going to see my game get any better.
Balthazar:
That's kinda true, but the **code** will get better and that will make it easier for you to add more interesting features to the game. And if you don't do this, the code will become harder and harder to manage and that will prevent you from adding new things to the game. So periodic cleanups like this are necessary as the code grows in size.
You:
(...)
Balthazar:
We could just copy and paste everything, but that would make future changes more difficult to make.
Balthazar:
Things that we know will be the same for every level. currently not much, but we'll be adding more here.
function init_player() {
...
}
function init_level_defaults(level) {
level.platforms = [];
level.monsters = [];
}
function init_level1() {
...
}
function init_level1() {
var level = {};
init_level_defaults(level);
level.platforms = [];
// The bottom brick platform along the bottom of the stage.
level.platforms.push(create_platform(0, 360, _game.width, 40));
// The left offstage 'wall' to keep the player on the stage.
level.platforms.push(
create_platform(-60, -_game.height, 60, 2 * _game.height));
// The right offstage 'wall' to keep the player on the stage.
level.platforms.push(
create_platform(_game.width, -_game.height, 60, 2 * _game.height));
level.platforms.push(create_platform(200, 290, 80, 20));
level.platforms.push(create_platform(300, 240, 80, 20));
level.platforms.push(create_platform(400, 170, 80, 20));
level.platforms.push(create_platform(460, 110, 40, 20));
level.monsters = [];
level.monsters.push(create_monster(350, 360, 20, 20, 60, 470, -1.0));
level.monsters.push(create_monster(400, 360, 20, 20, 60, 470, 0.8));
level.goal = create_goal(500, 360);
_levels.push(level);
}
RUN your code in a browser and verify that it loads without errors.
Balthazar:
Now let's look at the platform code. very repetitive. the only thing different are the values that we pass to create_platform each time. We can simplify by having an array of just those values and looping through them.
Balthazar:
Delete the current platform creation code:
function init_level1() {
var level = {};
init_level_defaults(level);
// The bottom brick platform along the bottom of the stage.
level.platforms.push(create_platform(0, 360, _game.width, 40));
// The left offstage 'wall' to keep the player on the stage.
level.platforms.push(
create_platform(-60, -_game.height, 60, 2 * _game.height));
// The right offstage 'wall' to keep the player on the stage.
level.platforms.push(
create_platform(_game.width, -_game.height, 60, 2 * _game.height));
level.platforms.push(create_platform(200, 290, 80, 20));
level.platforms.push(create_platform(300, 240, 80, 20));
level.platforms.push(create_platform(400, 170, 80, 20));
level.platforms.push(create_platform(460, 110, 40, 20));
...
}
Balthazar:
and replace it with:
function init_level1() {
var level = {};
init_level_defaults(level);
var platform_data = [
// The bottom brick platform along the bottom of the stage.
[0, 360, _game.width, 40],
// The left offstage 'wall' to keep the player on the stage.
[-60, -_game.height, 60, 2 * _game.height],
// The right offstage 'wall' to keep the player on the stage.
[_game.width, -_game.height, 60, 2 * _game.height],
[200, 290, 80, 20],
[300, 240, 80, 20],
[400, 170, 80, 20],
[460, 110, 40, 20],
];
for (var i = 0; i < platform_data.length; i++) {
var p = platform_data[i];
var plat = create_platform(p[0], p[1], p[2], p[3], p[4]);
level.platforms.push(plat);
}
...
}
RUN your code in a browser and verify that it loads without errors.
Balthazar:
The loop to create the platforms from the data is going to be the same for each level, so we can extract that code out into a separate function.
function init_level1() {
...
}
// platform_data: [x, y, width, height]
function add_platforms(level, platform_data) {
for (var i = 0; i < platform_data.length; i++) {
var p = platform_data[i];
var plat = create_platform(p[0], p[1], p[2], p[3]);
level.platforms.push(plat);
}
}
function create_platform(x, y, width, height) {
...
}
function init_level1() {
var level = {};
init_level_defaults(level);
var platform_data = [
// The bottom brick platform along the bottom of the stage.
[0, 360, _game.width, 40],
// The left offstage 'wall' to keep the player on the stage.
[-60, -_game.height, 60, 2 * _game.height],
// The right offstage 'wall' to keep the player on the stage.
[_game.width, -_game.height, 60, 2 * _game.height],
[200, 290, 80, 20],
[300, 240, 80, 20],
[400, 170, 80, 20],
[460, 110, 40, 20],
];
for (var i = 0; i < platform_data.length; i++) {
var p = platform_data[i];
var plat = create_platform(p[0], p[1], p[2], p[3], p[4]);
level.platforms.push(plat);
}
add_platforms(level, platform_data);
...
}
RUN your code in a browser and verify that it loads without errors.
Balthazar:
In addition, the main platform on the bottom and the ones on the left and right side are going to be the same for each level, so we can extract those out into a function as well.
function add_platforms(level, platform_data) {
...
}
function add_default_platforms(level) {
var platform_data = [
// The bottom brick platform along the bottom of the stage.
[0, 360, _game.width, 40],
// The left offstage 'wall' to keep the player on the stage.
[-60, -_game.height, 60, 2*_game.height],
// The right offstage 'wall' to keep the player on the stage.
[_game.width, -_game.height, 60, 2*_game.height],
];
add_platforms(level, platform_data);
}
function create_platform(x, y, width, height) {
...
}
function init_level1() {
var level = {};
init_level_defaults(level);
add_default_platforms(level);
var platform_data = [
// The bottom brick platform along the bottom of the stage.
[0, 360, _game.width, 40],
// The left offstage 'wall' to keep the player on the stage.
[-60, -_game.height, 60, 2 * _game.height],
// The right offstage 'wall' to keep the player on the stage.
[_game.width, -_game.height, 60, 2 * _game.height],
[200, 290, 80, 20],
[300, 240, 80, 20],
[400, 170, 80, 20],
[460, 110, 40, 20],
];
add_platforms(level, platform_data);
...
}
RUN your code in a browser and verify that it loads without errors.
Balthazar:
Now we need to do the same thing for the monsters.
Balthazar:
The current monster code should be deleted
function init_level1() {
...
add_platforms(level, platform_data);
level.monsters.push(create_monster(350, 360, 20, 20, 60, 470, -1.0));
level.monsters.push(create_monster(400, 360, 20, 20, 60, 470, 0.8));
level.goal = create_goal(500, 360);
...
}
Balthazar:
and replaced with:
function init_level1() {
...
add_platforms(level, platform_data);
var monster_data = [
[350, 360, 20, 20, 60, 470, -1.0],
[400, 360, 20, 20, 60, 470, 0.8],
];
add_monsters(level, monster_data);
level.goal = create_goal(500, 360);
...
}
Balthazar:
and we can add
function create_platform(x, y, width, height) {
...
}
// monster_data: [x, y, width, height, min_x, max_x, move_x]
function add_monsters(level, monster_data) {
for (var i = 0; i < monster_data.length; i++) {
var m = monster_data[i];
var monst = create_monster(m[0], m[1], m[2], m[3], m[4], m[5], m[6]);
level.monsters.push(monst);
}
}
function create_monster(x, y, width, height, min_x, max_x, move_x) {
...
}
Balthazar:
one last thing to add is a starting position for the player since each level may want to have the player start in a different location.
Balthazar:
You should set an appropriate default in init_level_defaults() and then set a proper value in init_level1().
function init_level_defaults(level) {
level.player_start_x = 0;
level.player_start_y = 0;
level.platforms = [];
level.monsters = [];
}
function init_level1() {
var level = {};
init_level_defaults(level);
level.player_start_x = 20;
level.player_start_y = 260;
add_default_platforms(level);
var platform_data = [
[200, 290, 80, 20],
[300, 240, 80, 20],
[400, 170, 80, 20],
[460, 110, 40, 20],
];
add_platforms(level, platform_data);
...
}
Balthazar:
We'll use these values when we connect the levels together
RUN your code in a browser and verify that it loads without errors.
GOTO 092