Beginner's corner

Top  Previous  Next

Sniper gun

This article will help you to create a simple sniping effect that can be used together with any other gun.

The main idea behind this piece of code is to decrease camera.arc in order to zoom in when we press "S" (comes from "sniper", of course). First of all, we define 3 panels:

panel sniper640_pan
{
   bmap = sniper640_map;
   layer = 20;
   pos_x = 0;
   pos_y = 0;
   flags = overlay, refresh, d3d;
}

panel sniper800_pan
{
   bmap = sniper800_map;
   layer = 20;
   pos_x = 0;
   pos_y = 0;
   flags = overlay, refresh, d3d;
}

panel sniper1024_pan
{
   bmap = sniper1024_map;
   layer = 20;
   pos_x = 0;
   pos_y = 0;
   flags = overlay, refresh, d3d;
}

I need 3 panels because I want to be able to use this sniper effect at all the resolutions (640x480, 800x600, 1024x768). If you want to have more video modes in your game you'll have to add more panels like these ones. The following function must be called in main:

function init_sniper()
{
   on_mouse_right = null;
   while (1)
   {
       if (key_s == 1)
       {
           if (video_mode == 6)
           {
               sniper640_pan.visible = on;
           }
           if (video_mode == 7)
           {
               sniper800_pan.visible = on;
           }
           if (video_mode == 8)
           {
               sniper1024_pan.visible = on;
           }
           while (camera.arc > 10)
           {
               camera.arc -= 5 * time; // speed
               wait (1);
           }
      }
     else
     {
           camera.arc = 60;
           sniper640_pan.visible = off;
           sniper800_pan.visible = off;
           sniper1024_pan.visible = off;
      }
     wait (1);
  }
}

On_mouse_right = null; makes sure that the default mouse pointer action is disabled. The "while" loop checks if we press "S". If this happens, the proper panels is displayed, depending on the resolution (video_mode = 6 means 640x480, video_mode = 7 means 800x600 and so on). The camera zooms (camera.arc decreases) with the speed given by 5 * time; play with this value to get different zooming speeds. If the player releases the "S" key, we're moving to the "else" branch: camera.arc is set back to its default value = 60 and the panels are made invisible. I know that only one of the panels is visible, depending on the resolution but it won't hurt anybody if we make all of them invisible at once.

Please note that the panels are transparent (RGB = 000) only in the center.

Timed bomb

Do you know the little house in office.wmp? What if on one of its walls would hang a timed bomb, anxiously waiting to be clicked on with the mouse pointer? Anxiously waiting to destroy everything in the area? What? You have loaded my office.wmp level and you've tested the bomb already? That's cheating, man!

The action attached to timer.mdl is really simple:

action timer
{
    my.skin = 2;
    my._DAMAGE = 200; // set different damage values for different timers
    my.enable_click = on;
    my.event = start_timer;
}

You can see that I'm using a model with 2 skins; its damage is set to 200 (I'll use some template stuff). The timer is sensitive on clicking; if this happens, its start_timer function is executed:

function start_timer()
{
    wait (1);
    second_counter = 10; // explodes after 10 seconds
    while (my != null)
    {
         second_counter -= 1;
         my.skin = 2;
         ent_playsound (my, timer_snd, 300);
         waitt (14);
         my.skin = 1;
         waitt (2);
         if (second_counter < 1)
         {
              range = my._DAMAGE * 2;
              damage = my._DAMAGE;
              temp.pan = 360;
              temp.tilt = 180;
              temp.z = range;
              indicator = _EXPLODE; // not a friendly scan
              scan_entity (my.x, temp);
              morph (explo_sprite, me);
              my.oriented = on;
              my.pan = 0;
              while (my.frame < 7)
              {
                   my.frame += 3 * time;
                   wait (1);
              }
              actor_explode(); // remove the explosion sprite
         }
    }
}

Second_counter holds the number of seconds before the explosion starts; I have set it to 10 seconds in my example. As long as the timer hasn't exploded (my != null) the timer will play a sound and change between its skins (1 and 2) every second because waitt (14) + waitt (2) = waitt (16) = 1 second. When the second_counter has decreased to 0, the timer will explode, morphing itself into an oriented sprite because the player needs to see a good looking explosion. The explosion sprite passes through its animation frames and then it is removed.

You can improve this timer code by allowing the player to select the number of seconds on a panel, creating timed bombs like this one as "gun" bullets and so on.