From zero to Bombuzal – step 4
One of the biggest problems of step 3 was Bombuzal waled sooo slowly.
So I added a variable called walk_speed where I assign the walking speed in pixels per frame.
Then, in the original game you have to think fast. You can’t stay on the same tile for more than about 5 secods, or the tile where you are over will turn in a spinning tile that will spin Bombuzal in a random direction everytime it walks on it.
But it’s not over: if Bombuzal stays on a tile with a bomb for more than 5 seconds, the tile won’t become a spinning tile but the bomb will explode, killing Bombuzal.
If Bombuzal stays on a disappearing tile for more than 5 seconds, the disappearing tile will… disappear, making Bombuzal fall down.
A lot of exceptions for an old C64 game!
At the moment, I won’t make any tile change, but I will move Bombuzal in a random direction if it stays more than 5 seconds on the same tile.
I am creating a counter called does_not_move that will count all frames passed since the last time Bombuzal moved. If the counter reaches 150, then I’ll randomly move Bombuzal
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 | //create an invisible movie clip across the entire stage using API
_root.createEmptyMovieClip("base", 1);
with (base) {
lineStyle(2, 0x0000000, 0);
beginFill(0x00000000, 0);
lineTo(Stage.width, 0);
lineTo(Stage.width, Stage.height);
lineTo(0, Stage.height);
lineTo(0, 0);
}
//whether to pan or not
level_pan = false;
//tile size
tile_size = 50;
// pan variables
pan_dist = 50;
pan_speed = 5;
// tiles array generation
tiles = [[0, 1, 0, 0], [1, 1, 2, 1], [1, 2, 1, 2], [0, 0, 1, 0]];
// bombs array generation
bombs = [[0, 1, 0, 0], [0, 1, 0, 1], [1, 0, 1, 0], [0, 0, 1, 0]];
// main sprite
// xpos: bombuzal x position
// ypos: y position
// moving: bombuzal is moving or not
// facing: the side bombuzal is facing on
bombuzal_obj = {xpos:0, ypos:1, moving:false, facing:"right"};
// bombuzal walk speed, in pixels/frame
walk_speed = 5;
// time passed since bombuzal last move
does_not_move = 0;
// creating the level movieclip
_root.createEmptyMovieClip("level", _root.getNextHighestDepth());
// placing tiles
for (x=0; x<tiles.length; x++) {
for (y=0; y<tiles[x].length; y++) {
// notice as it's not [x][y] but [y][x]
if (tiles[y][x]) {
placed = level.attachMovie("tile", "tile"+level.getNextHighestDepth(), level.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
placed.gotoAndStop(tiles[y][x]);
}
}
}
// placing bombs
for (x=0; x<bombs.length; x++) {
for (y=0; y<bombs[x].length; y++) {
if (bombs[y][x]) {
level.attachMovie("bomb", "bomb"+level.getNextHighestDepth(), level.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
}
}
}
// placing bombuzal
level.attachMovie("bombuzal", "bombuzal", level.getNextHighestDepth(), {_x:bombuzal_obj.xpos*tile_size, _y:bombuzal_obj.ypos*tile_size});
level.bombuzal.onEnterFrame = function() {
// if bombuzal is not alread moving...
if (!bombuzal_obj.moving) {
// incrementing counter
does_not_move++;
// if 150 frames has passed and bombuzal did not move..
if (does_not_move == 150) {
bombuzal_obj.moving = true;
// choosing a random direction
moving_direction = Math.floor(Math.random()*4)+1;
switch (moving_direction) {
case 1 :
bombuzal_obj.facing = "left";
break;
case 2 :
bombuzal_obj.facing = "right";
break;
case 3 :
bombuzal_obj.facing = "up";
break;
case 4 :
bombuzal_obj.facing = "down";
break;
}
}
// moving left
if (Key.isDown(Key.LEFT)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "left";
}
// moving right
if (Key.isDown(Key.RIGHT)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "right";
}
// moving down
if (Key.isDown(Key.DOWN)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "down";
}
// moving up
if (Key.isDown(Key.UP)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "up";
}
// else, if it's moving...
} else {
does_not_move = 0;
switch (bombuzal_obj.facing) {
// moving left
case "left" :
dx = -1;
dy = 0;
this._x -= walk_speed;
break;
// moving right
case "right" :
dx = 1;
dy = 0;
this._x += walk_speed;
break;
// moving up
case "up" :
dx = 0;
dy = -1;
this._y -= walk_speed;
break;
// moving down
case "down" :
dx = 0;
dy = 1;
this._y += walk_speed;
break;
}
// if bombuzal walked for an entire tile...
if ((this._x%tile_size == 0) and (this._y%tile_size == 0)) {
// stop moving bombuzal
bombuzal_obj.moving = false;
// increase bombuzal x and y position according to its direction
bombuzal_obj.xpos += dx;
bombuzal_obj.ypos += dy;
update_bombuzal_position();
}
}
};
// centering level
level._x = (Stage.width-tiles.length*tile_size)/2;
level._y = (Stage.height-tiles[0].length*tile_size)/2;
level.onEnterFrame = function() {
//if mouse is on stage
if (level_pan) {
//stopping level leaving screen
//too high
if (level._y<=0) {
level._y = 0;
}
//too low
if (level._y>=Stage.height-level._height) {
level._y = Stage.height-level._height;
}
//too far to the left
if (level._x<=0) {
level._x = 0;
}
//too far to the right
if (level._x>=Stage.width-level._width) {
level._x = Stage.width-level._width;
}
// panning level
// pan right
if (_root._xmouse<pan_dist) {
level._x += pan_speed;
}
// pan left
if (_root._xmouse>Stage.width-pan_dist) {
level._x -= pan_speed;
}
// pan down
if (_root._ymouse<pan_dist) {
level._y += pan_speed;
}
// pan up
if (_root._ymouse>Stage.height-pan_dist) {
level._y -= pan_speed;
}
}
};
//when mouse is on stage pan
base.onRollOver = function() {
level_pan = true;
};
//when mouse leaves stage stop panning
base.onRollOut = function() {
level_pan = false;
};
// update bombuzal position
function update_bombuzal_position() {
// if bombuzal falls off the stage...
if ((tiles[bombuzal_obj.ypos][bombuzal_obj.xpos] == undefined) or (tiles[bombuzal_obj.ypos][bombuzal_obj.xpos]<1)) {
// reset bombuzal to its starting position
bombuzal_obj.xpos = 0;
bombuzal_obj.ypos = 1;
level.bombuzal._x = bombuzal_obj.xpos*tile_size;
level.bombuzal._y = bombuzal_obj.ypos*tile_size;
update_bombuzal_position();
}
} |
Now I want “broken” tiles to disappear after Bombuzal passed over them. To do it, when Bombuzal stops after walking for an entire tile, I check if the tile it just left is a broken tile.
In this case, I remove the tile movieclip and update the tiles array…
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 | //create an invisible movie clip across the entire stage using API
_root.createEmptyMovieClip("base", 1);
with (base) {
lineStyle(2, 0x0000000, 0);
beginFill(0x00000000, 0);
lineTo(Stage.width, 0);
lineTo(Stage.width, Stage.height);
lineTo(0, Stage.height);
lineTo(0, 0);
}
//whether to pan or not
level_pan = false;
//tile size
tile_size = 50;
// pan variables
pan_dist = 50;
pan_speed = 5;
// tiles array generation
tiles = [[0, 1, 0, 0], [1, 1, 2, 1], [1, 2, 1, 2], [0, 0, 1, 0]];
// bombs array generation
bombs = [[0, 1, 0, 0], [0, 1, 0, 1], [1, 0, 1, 0], [0, 0, 1, 0]];
// main sprite
// xpos: bombuzal x position
// ypos: y position
// moving: bombuzal is moving or not
// facing: the side bombuzal is facing on
bombuzal_obj = {xpos:0, ypos:1, moving:false, facing:"right"};
// bombuzal walk speed, in pixels/frame
walk_speed = 5;
// time passed since bombuzal last move
does_not_move = 0;
// creating the level movieclip
_root.createEmptyMovieClip("level", _root.getNextHighestDepth());
// placing tiles
for (x=0; x<tiles.length; x++) {
for (y=0; y<tiles[x].length; y++) {
// notice as it's not [x][y] but [y][x]
if (tiles[y][x]) {
placed = level.attachMovie("tile", "tile_"+(x*tiles.length+y), level.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
placed.gotoAndStop(tiles[y][x]);
}
}
}
// placing bombs
for (x=0; x<bombs.length; x++) {
for (y=0; y<bombs[x].length; y++) {
if (bombs[y][x]) {
level.attachMovie("bomb", "bomb"+level.getNextHighestDepth(), level.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
}
}
}
// placing bombuzal
level.attachMovie("bombuzal", "bombuzal", level.getNextHighestDepth(), {_x:bombuzal_obj.xpos*tile_size, _y:bombuzal_obj.ypos*tile_size});
level.bombuzal.onEnterFrame = function() {
// if bombuzal is not alread moving...
if (!bombuzal_obj.moving) {
// incrementing counter
does_not_move++;
// if 150 frames has passed and bombuzal did not move..
if (does_not_move == 150) {
bombuzal_obj.moving = true;
// choosing a random direction
moving_direction = Math.floor(Math.random()*4)+1;
switch (moving_direction) {
case 1 :
bombuzal_obj.facing = "left";
break;
case 2 :
bombuzal_obj.facing = "right";
break;
case 3 :
bombuzal_obj.facing = "up";
break;
case 4 :
bombuzal_obj.facing = "down";
break;
}
}
// moving left
if (Key.isDown(Key.LEFT)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "left";
}
// moving right
if (Key.isDown(Key.RIGHT)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "right";
}
// moving down
if (Key.isDown(Key.DOWN)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "down";
}
// moving up
if (Key.isDown(Key.UP)) {
bombuzal_obj.moving = true;
bombuzal_obj.facing = "up";
}
// else, if it's moving...
} else {
does_not_move = 0;
switch (bombuzal_obj.facing) {
// moving left
case "left" :
dx = -1;
dy = 0;
this._x -= walk_speed;
break;
// moving right
case "right" :
dx = 1;
dy = 0;
this._x += walk_speed;
break;
// moving up
case "up" :
dx = 0;
dy = -1;
this._y -= walk_speed;
break;
// moving down
case "down" :
dx = 0;
dy = 1;
this._y += walk_speed;
break;
}
// if bombuzal walked for an entire tile...
if ((this._x%tile_size == 0) and (this._y%tile_size == 0)) {
// stop moving bombuzal
bombuzal_obj.moving = false;
// checking if bombuzal just walked a disappearing tile
if (tiles[bombuzal_obj.ypos][bombuzal_obj.xpos] == 2) {
// remove tile
tiles[bombuzal_obj.ypos][bombuzal_obj.xpos] = 0;
level["tile_"+(bombuzal_obj.xpos*tiles.length+bombuzal_obj.ypos)].removeMovieClip();
}
// increase bombuzal x and y position according to its direction
bombuzal_obj.xpos += dx;
bombuzal_obj.ypos += dy;
update_bombuzal_position();
}
}
};
// centering level
level._x = (Stage.width-tiles.length*tile_size)/2;
level._y = (Stage.height-tiles[0].length*tile_size)/2;
level.onEnterFrame = function() {
//if mouse is on stage
if (level_pan) {
//stopping level leaving screen
//too high
if (level._y<=0) {
level._y = 0;
}
//too low
if (level._y>=Stage.height-level._height) {
level._y = Stage.height-level._height;
}
//too far to the left
if (level._x<=0) {
level._x = 0;
}
//too far to the right
if (level._x>=Stage.width-level._width) {
level._x = Stage.width-level._width;
}
// panning level
// pan right
if (_root._xmouse<pan_dist) {
level._x += pan_speed;
}
// pan left
if (_root._xmouse>Stage.width-pan_dist) {
level._x -= pan_speed;
}
// pan down
if (_root._ymouse<pan_dist) {
level._y += pan_speed;
}
// pan up
if (_root._ymouse>Stage.height-pan_dist) {
level._y -= pan_speed;
}
}
};
//when mouse is on stage pan
base.onRollOver = function() {
level_pan = true;
};
//when mouse leaves stage stop panning
base.onRollOut = function() {
level_pan = false;
};
// update bombuzal position
function update_bombuzal_position() {
// if bombuzal falls off the stage...
if ((tiles[bombuzal_obj.ypos][bombuzal_obj.xpos] == undefined) or (tiles[bombuzal_obj.ypos][bombuzal_obj.xpos]<1)) {
// reset bombuzal to its starting position
bombuzal_obj.xpos = 0;
bombuzal_obj.ypos = 1;
level.bombuzal._x = bombuzal_obj.xpos*tile_size;
level.bombuzal._y = bombuzal_obj.ypos*tile_size;
update_bombuzal_position();
}
} |
Last but not least, I would like to thank Grifo, the winner of this step for his Bombuzal character
Next thing I need… when Bombuzal is on a tile with a bomb on it, if SPACEBAR is pressed then Bombuzal takes/drops the bomb.
If SPACEBAR is hold for more than 2 seconds, then the bomb detonates.
Win a tutorial step to have your name/site in final game credits… and maybe something more… here they are the source files…
They can be easily customized to meet the unique requirements of your project.

























This post has 6 comments
xavi-v
hey, that’s a pretty good bombuzal character.
Way to go Grifo. If you are reading this Grifo, nice job!
souled
Go Grifo!
Also I <3 how you didn’t use intervals, my mortal enemy…
Jack Hopkisn
Awesome! the game is taking form…;)
EagleVision
WOW!
WAY TO GO GRIFO!!! My guy was a blob wwith to sticks…lol…Wow, I wish I could draw like that.
EagleVision
Just came up with an Idea!
Since Grifo made the sprite, we can name the “bombuzal” character, then we can name the character “grifo”! What do you think?
Grifo
lol you guys. Thanks a lot, but it was nothing.
You may name it Grifo if you wish, even tho it doesn’t look like Grifo to me. But that’s a matter of opinion I guess ;)
Thanks a lot for the considerations. I’m always at the blog so anything else, just let me know.