Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Metro Siberia Underground game, Flash and Game development.

Multipart tutorial: available parts 1, 2, 3, 4 ,5

Now it’s time to create a random tunnel

Read Create a Flash game like Metro Siberia Underground if you don’t know what I am talking about and look what I made:

1) There is a random tunnel with collision detection

2) Smoke clouds get bigger when they are released

I just created a new symbol linked as tunnel that represents the… tunnel, as said.

The tunnel is made by two rectanges on the same x axis with a y gap between the higher and the lower

The gap between the rectangles is the tunnel itself, while the rectangles are the rock

Let’s take a look to the actionscript

import flash.filters.GlowFilter;
var ship_filter:GlowFilter = new GlowFilter(0x00ff00, 0.8, 4, 4, 2, 3, false, false);
var smoke_filter:GlowFilter = new GlowFilter(0xff0000, 0.8, 4, 4, 2, 3, false, false);
var tunnel_filter:GlowFilter = new GlowFilter(0xffff00, 0.8, 4, 4, 2, 3, false, false);
gravity = 0.1;
thrust = 0.25;
yspeed = 0;
xspeed = 5;
distance = 0;
smoke_interval = 10000;
frames_passed = 0;
tunnel_height = 150;
engines = false;
_root.attachMovie("ship", "ship", _root.getNextHighestDepth(), {_x:150, _y:200});
_root.createEmptyMovieClip("tunnel_movie", _root.getNextHighestDepth());
ship.filters = new Array(ship_filter);
ship.onEnterFrame = function() {
	if (engines) {
		yspeed -= thrust;
		smoke_interval -= 0.25;
	}
	yspeed += gravity;
	this._y += yspeed;
	angle = Math.atan2(yspeed, xspeed);
	this._rotation = angle*180/Math.PI;
	frames_passed++;
	distance += xspeed;
	if (distance>50) {
		step = distance-50;
		wall = tunnel_movie.attachMovie("tunnel", "tunnel"+tunnel_movie.getNextHighestDepth(), tunnel_movie.getNextHighestDepth(), {_x:525-step, _y:tunnel_height});
		wall.filters = new Array(tunnel_filter);
		wall.onEnterFrame = function() {
			this._x -= xspeed;
			if (this._x<-25) {
				this.removeMovieClip();
			}
		};
		tunnel_height += Math.floor(Math.random()*40)-19;
		distance = step;
	}
	if (frames_passed>=smoke_interval) {
		sm = _root.attachMovie("smoke", "smoke"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:this._x-2, _y:this._y});
		sm.filters = new Array(smoke_filter);
		sm.onEnterFrame = function() {
			this._x -= xspeed;
			this._width += 0.2;
			this._height += 0.2;
			this._alpha -= 2;
			if (this._alpha<=0) {
				this.removeMovieClip();
			}
		};
		frames_passed = 0;
	}
	if ((this._y > 400) or tunnel_movie.hitTest(this._x+28*Math.cos(angle), this._y+28*Math.sin(angle), true) or tunnel_movie.hitTest(this._x+8*Math.cos(angle+Math.PI/2), this._y+8*Math.sin(angle+Math.PI/2), true) or tunnel_movie.hitTest(this._x+8*Math.cos(angle-Math.PI/2), this._y+8*Math.sin(angle-Math.PI/2), true)) {
		yspeed = 0;
		this._y = 200;
		tunnel_movie.removeMovieClip();
		_root.createEmptyMovieClip("tunnel_movie", _root.getNextHighestDepth());
	}
};
_root.onMouseDown = function() {
	engines = true;
	smoke_interval = 10;
};
_root.onMouseUp = function() {
	engines = false;
	smoke_interval = 100000;
};

Let’s comment the new actionscript

Line 4: Filter to apply to the tunnel

Line 9: Distance traveled by the spaceship

Line 12: Variable to store the tunnel height

Line 15: Creating an empty movie clip that will contain the tunnel

Line 27: Updating the distance traveled according to ship speed

Line 28: Checking if the distance is greater than 50 (50 is the width of the tunnel rectangle)

Line 29: In a step variable I store the difference between distance and 50, to know exactly where to place the tunnel

Line 30: Placing the tunnel. Notice the x and y coordinates, based upon step and tunnel_height

Line 31: Apllying the filter to the tunnel

Line 32: Function to be executed at every frame for the tunnel

Line 33: Decrease its x position according to ship speed

Lines 34-36: If the tunnel left the stage to the left, then remove it

Line 38: Setting a new tunnel height, that will be 20 pixels higher or lower than the previous one. This will make the tunnel have a serpentine shape

Line 39: Setting the distance traveled equal to step variable. distance variable does not count the entire distance, but only the distance from the last added tunnel

Lines 46-47: Increasing smoke size line in “real life”

Line 55: Checking if the ship leaves the stage to the bottom (falls down) or if one of the tree points making the triangle (the ship itself) hit the tunnel. To know the position of the points, I call some trigonometry functions. More information about trigonometry at Create a flash draw game like Line Rider or others – part 3

Line 56: Reset y speed

Line 57: Place the ship in the middle of the stage

Lines 58-59: Removing the old tunnel (the one where the ship crashed) and creating a new one

And here it is the result

Sometimes the tunnel messes up because the “game over” is not optimized at the moment… just reload the page if it happens

What should I add now… sure… more elements… powerups… and a laser the ship can fire… only using one button of course…

Meanwhile download the source code and experiment a bit

Multipart tutorial: available parts 1, 2, 3, 4 ,5

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.