Create a Flash game like Metro Siberia Underground - Part 5

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

This tutorial reached the 5th part, and it's time to add some new feature... something that wasn't included in the original game.

Always remember to add something to a game you are about to clone, or people will get bored very soon of your game.

In this tutorial we will make the ship fire. "Oh, well", you may say, "thanks for the millionth tutorial about firing spaceships".

Wait... do you remember Metro Siberia Underground is a one button game? And that the one an only button you can press in this game is already used to give thrust?

That's where my gameplay idea comes and shines... your ship is always firing... and it's up to you firing only at the rocks, avoiding to blow off fuel tanks.

Read parts 1 to 4 before continuing, then take this actionscript:

ACTIONSCRIPT:
  1. import flash.filters.GlowFilter;
  2. var ship_filter:GlowFilter = new GlowFilter(0x00ff00, 0.8, 4, 4, 2, 3, false, false);
  3. var smoke_filter:GlowFilter = new GlowFilter(0xff0000, 0.8, 4, 4, 2, 3, false, false);
  4. var tunnel_filter:GlowFilter = new GlowFilter(0xffff00, 0.8, 4, 4, 2, 3, false, false);
  5. var fuel_filter:GlowFilter = new GlowFilter(0x00ffff, 0.8, 4, 4, 2, 3, false, false);
  6. var rock_filter:GlowFilter = new GlowFilter(0xffffff, 0.8, 4, 4, 2, 3, false, false);
  7. var score_filter:GlowFilter = new GlowFilter(0xff00ff, 0.8, 2, 4, 2, 3, false, false);
  8. gravity = 0.1;
  9. thrust = 0.25;
  10. yspeed = 0;
  11. xspeed = 5;
  12. distance = 0;
  13. smoke_interval = 10000;
  14. frames_passed = 0;
  15. tunnel_height = 150;
  16. fuel_freq = 10;
  17. gasoline = 500;
  18. rock_freq = 50;
  19. engines = false;
  20. _root.attachMovie("ship", "ship", _root.getNextHighestDepth(), {_x:150, _y:200});
  21. _root.createEmptyMovieClip("beam", _root.getNextHighestDepth());
  22. _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
  23. _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
  24. _root.attachMovie("score", "score", _root.getNextHighestDepth());
  25. _root.attachMovie("beam_spot", "beam_spot", _root.getNextHighestDepth());
  26. beam.filters = new Array(smoke_filter);
  27. beam_spot.filters = new Array(smoke_filter);
  28. ship.filters = new Array(ship_filter);
  29. score.filters = new Array(score_filter);
  30. ship.onEnterFrame = function() {
  31.     score.sc.text = "Distance: "+distance+" - "+"Fuel: "+gasoline;
  32.     if ((gasoline>0) and (engines)) {
  33.         yspeed -= thrust;
  34.         smoke_interval -= 0.25;
  35.         gasoline -= 1;
  36.     }
  37.     if (Math.random()*1000<fuel_freq) {
  38.         fuel = fuel_movie.attachMovie("fuel", "fuel"+fuel_movie.getNextHighestDepth(), fuel_movie.getNextHighestDepth(), {_x:510, _y:Math.random()*400+50});
  39.         fuel.filters = new Array(fuel_filter);
  40.         fuel.onEnterFrame = function() {
  41.             this._x -= (xspeed*1.2);
  42.             if (this.hitTest(beam_spot)) {
  43.                 this._alpha -=5;
  44.                 if (this._alpha<0) {
  45.                     this.removeMovieClip();
  46.                 }
  47.             }
  48.             dist_x = ship._x+28*Math.cos(angle)-this._x;
  49.             dist_y = ship._y+28*Math.sin(angle)-this._y;
  50.             dist = Math.sqrt(dist_x*dist_x+dist_y*dist_y);
  51.             if (dist<10) {
  52.                 gasoline += 100;
  53.                 this.removeMovieClip();
  54.             }
  55.             if (this._x<-10) {
  56.                 this.removeMovieClip();
  57.             }
  58.         };
  59.     }
  60.     if (Math.random()*1000<rock_freq) {
  61.         rock = deadly_movie.attachMovie("rock", "rock"+deadly_movie.getNextHighestDepth(), deadly_movie.getNextHighestDepth(), {_x:510, _y:Math.random()*400+50, _rotation:Math.random()*360});
  62.         rock.filters = new Array(rock_filter);
  63.         rock.onEnterFrame = function() {
  64.             this._x -= xspeed;
  65.             if (this.hitTest(beam_spot)) {
  66.                 this._alpha -=3;
  67.                 if (this._alpha<0) {
  68.                     this.removeMovieClip();
  69.                 }
  70.             }
  71.             if (this._x<-10) {
  72.                 this.removeMovieClip();
  73.             }
  74.         };
  75.     }
  76.     yspeed += gravity;
  77.     this._y += yspeed;
  78.     angle = Math.atan2(yspeed, xspeed);
  79.     this._rotation = angle*180/Math.PI;
  80.     beam.clear();
  81.     beam.lineStyle(1, 0xffff00, 10+40*Math.random());
  82.     beam.moveTo(this._x+30*Math.cos(angle), this._y+30*Math.sin(angle));
  83.     for (x=1; x<=250; x++) {
  84.         to_x = this._x+(30+x)*Math.cos(angle);
  85.         to_y = this._y+(30+x)*Math.sin(angle);
  86.         if ((deadly_movie.hitTest(to_x, to_y, true))or(fuel_movie.hitTest(to_x, to_y, true))) {
  87.             break;
  88.         }
  89.     }
  90.     beam.lineTo(to_x, to_y);
  91.     beam_spot._x = to_x;
  92.     beam_spot._y = to_y;
  93.     frames_passed++;
  94.     distance += xspeed;
  95.     if (frames_passed>=smoke_interval) {
  96.         sm = _root.attachMovie("smoke", "smoke"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:this._x-2, _y:this._y});
  97.         sm.filters = new Array(smoke_filter);
  98.         sm.onEnterFrame = function() {
  99.             this._x -= xspeed;
  100.             this._width += 0.2;
  101.             this._height += 0.2;
  102.             this._alpha -= 2;
  103.             if (this._alpha<=0) {
  104.                 this.removeMovieClip();
  105.             }
  106.         };
  107.         frames_passed = 0;
  108.     }
  109.     if ((this._y>400) or (this._y<0) or deadly_movie.hitTest(this._x+28*Math.cos(angle), this._y+28*Math.sin(angle), true) or deadly_movie.hitTest(this._x+8*Math.cos(angle+Math.PI/2), this._y+8*Math.sin(angle+Math.PI/2), true) or deadly_movie.hitTest(this._x+8*Math.cos(angle-Math.PI/2), this._y+8*Math.sin(angle-Math.PI/2), true)) {
  110.         yspeed = 0;
  111.         this._y = 200;
  112.         gasoline = 500;
  113.         distance = 0;
  114.         deadly_movie.removeMovieClip();
  115.         fuel_movie.removeMovieClip();
  116.         _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
  117.         _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
  118.     }
  119. };
  120. _root.onMouseDown = function() {
  121.     engines = true;
  122.     smoke_interval = 10;
  123. };
  124. _root.onMouseUp = function() {
  125.     engines = false;
  126.     smoke_interval = 100000;
  127. };

And let's see what do new lines make:

Line 21: Creating an empty movie clip that will represent the laser beam. It will be a simple line, but, hey, we have to use a bit of imagination...

Line 25: Attaching the beam_spot movieclip... it's a red 2x2 pixels dot, and it's the spot where you are going to fire

Lines 26-27: Attaching filters to laser beam and laser spot. I want them to have a red glow, so I am using the same filters used for the smoke

Line 80: Clearing beam movieclip

Line 81: Setting the drawing style for the laser beam. For more information about drawing styles refer to Create a flash draw game like Line Rider or others - part 1

Line 82: Moving the pen that will draw the laser beam in front of the spaceship using trigonometry. More information about Flash and trigonometry at Create a flash draw game like Line Rider or others - part 3

Line 83: Beginning of a loop to be executed 250 times... because my laser beam will be 250 pixels wide

Lines 84-85: Using trigonometry, I determine when will be the x-th pixel of the laser beam according to spaceship rotation

Lines 86-88: If the x-th pixel hits a rock or a fuel can, then exit the for loop

Line 90: Drawing the line until the pixel that gave a positive hit test with rock or fuel, or draw all 250 pixels if there wasn't any collision. This method reminds the one to draw the cone of light in Create a survival horror game in Flash - part 1

Lines 91-92: Moving the beam red spot at the end of the laser beam.

Now I can know when the laser hits a rock or a fuel can, but I can't determine which rock or which can did I hit...

I mean... I know that at coordinates (x,y) there is a rock or a fuel can, but now I have to see which one touches the (x,y) pixel according to its rotation, size and position.

... unless I perform an hit test between any rock (or fuel) and the beam spot... and that what I am doing at:

Line 42: Performing an hit test between the fuel can and the beam spot

Line 43: If true, then make the fuel can a bit more transparent

Lines 44-46: If the fuel can is completely transparent, then remove it from the game. BOOOM... you hitted a fuel can... you will run out of gasoline very soon if you don't pay attention to fuel cans...
unless I perform a standard hit test between the red spot and rocks and cans.

Lines 65-70: Same thing with rocks, but they are a bit more difficult to destroy.

And here it is the result... only one button needed to play, ladies and gentlemen...

Download the source code and enjoy

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

Improve the blog rating this post
Tell me what do you think about this post. I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

» 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.

15 Responses to “Create a Flash game like Metro Siberia Underground - Part 5”

  1. David on February 12th, 2008 10:49 pm

    brilliant! i already created a version of this, but using the space bar as the firing weapon!

    i must say that you are a complete genius!
    i can never be able to create anything like this!

    keep up the good tutorials
    after all, this is the only site that i have to go to now to learn about flash!

  2. Gabriel on February 12th, 2008 11:40 pm

    very good…

    emanuele, your rss feed isnt working

  3. Graham Kaemmer on February 13th, 2008 12:30 am

    That’s sweet.

    It would require another button, but you should show how to make a weapon that fires when you want it to.

  4. Graham Kaemmer on February 13th, 2008 12:32 am

    Alright, maybe I sounded really stupid, but actionscript isn’t really my strong point. I know more about web design.

    What other of your tuts shows how to do the firing thing.

  5. Eblup on February 13th, 2008 5:21 am

    Hey can you help me make a platform version of super mario galaxy. I will send you the flash of what i have so far but i dont have youre email. PLEASE HELP ASAP!!!!!!!

  6. Bigcortex on February 13th, 2008 5:32 am

    This is really a coincidence! I just finished implementing a similar feature using the spacebar to fire (just like David) and I see this tutorial!

    Your code is so much cleaner than my “spaghetti code” ;)

  7. Suely (Snakesue) on February 13th, 2008 10:00 pm

    Hi, I agree to David:keep up the good tutorials
    after all, this is the better site that i have to go to now to learn about flash!
    I DO NOT WANT TO BE A PROTOTYPE LIKE VISITOR COPY AND PASTE. I WANT TO BE A REGISTER MEMBER AND GAME MAKER.

  8. brart on February 14th, 2008 9:25 pm

    weapon is kind of anoying because it also destroys the fuel things.

    It’s possible to make a larger game from this. With save points and not a “see how far you come” game.

    anyway nice glowfilters and good tut

  9. H35 on February 15th, 2008 3:12 pm

    Hi,
    How can i make this, im totally new in action script world, but i really like to learn.
    Can someone please help?
    lot’s of thnx…..

  10. David on February 17th, 2008 4:57 pm

    Can’t wait for the nect tut!!!

  11. Volte6 on February 21st, 2008 9:30 am

    I used your tutorial in a complete game… with original art, music, etc.. .check it out!

    http://www.mrtiki.com/games/play/Wootropolis_Flyby.php

  12. Shiv on February 21st, 2008 3:09 pm

    I tried and failed to make the code.
    Anyways gr8!

  13. Goinginsane on February 26th, 2008 9:25 pm

    What exactly does “unexpected file format” mean
    Flash mx says it everytime I try to downlod the file………

  14. Ahmed on April 20th, 2008 9:38 pm

    that mean you must probably right ckick in the folder and extract all

Leave a Reply




Trackbacks

  1. Create a Flash game like Metro Siberia Underground - Part 3 : Emanuele Feronato - italian geek and PROgrammer on February 13th, 2008 6:57 pm

    [...] Multipart tutorial: available parts 1, 2, 3, 4 ,5 [...]