Most asked questions

Top  Previous  Next

Q: I'd like to be able to rotate the camera around a specific entity (the target) when I press the left and right keys on my keyboard. Up and down should take me closer or farther to the target. Can you help?

A: Attach the action below to the target entity.

 

entity* mytarget;

 

action my_target // attach it to the target entity

{

  mytarget = my;

}

 

starter chase_target()

{

  var distance_to_target = 300; // initial distance to target

  var temp_angle = 50; // initial angle

  while (mytarget == null) {wait (1);}

  while (1)

  {

     camera.x = mytarget.x + distance_to_target * cos(temp_angle);

     camera.y = mytarget.y + distance_to_target * sin(temp_angle);

     camera.z = mytarget.z;

     vec_set (temp, mytarget.x);

     vec_sub (temp, camera.x);

     vec_to_angle (camera.pan, temp);

     if ((key_cuu == on) && (distance_to_target > 100))

     {

        distance_to_target -= 7 * time; // come closer to the target

     }

     if ((key_cud == on) && (distance_to_target < 500))

    {

       distance_to_target += 7 * time; // get away from the target

    }

    if (key_cul == on)

    {

       temp_angle -= 5 * time;

    }

    if (key_cur == on)

    {

        temp_angle += 5 * time;

     }

     wait (1);

  }

}

 

 

Q: How do they do the movement in games like Prince of Persia? The prince is grabbing onto poles and swinging around; how do they make sure that the hands are placed perfectly on the pole every time, even if the distance you jumped from wasn't the same every time?

A: You can use a simple method if you want to achieve similar results: compute the distance between the player and the pole and adjust the jumping speed and the animation frames depending on that distance. As an example, if the distance between the player and the pole is 100 quants, move it with 10 * time and animate it with 5 * time. If the distance is 70 quants, move it with 7 * time and animate it with 5 * (100 / 70) * time.

 

 

Q: If I would kick a box, how would I program it so that it moves in the opposite direction without losing its original pan and tilt angles?

A: Use the code below. Run into the box to move it.

 

function move_boxes()

{

   vec_rotate (vector(2 * (my.x - player.x) * time, 0, 0), player.pan);

   vec_add (my.x, vector(2 * (my.x - player.x) * time, 2 * (my.y - player.y) * time, 0));

}

 

action my_box

{

  while (player == null) {wait (1);}

  my.enable_impact = on;

  my.enable_entity = on;

  my.event = move_boxes;

}

 

 

Q: I want to create an inventory panel with four guns; the pcx image won't show up until I have picked up the corresponding weapon. Can you help?

A: Take a look at the example below and expand it for as many guns as you need:

 

bmap weapon1_pcx = <weapon1.pcx>;

bmap weapon2_pcx = <weapon2.pcx>;

 

var got_weapon1 = 0;

var got_weapon2 = 0;

 

panel weapon1_pan

{

  bmap = weapon1_pcx;

  layer = 20;

  pos_x = 0;

  pos_y = 0;

  flags = overlay, refresh;

}

 

panel weapon2_pan

{

  bmap = weapon2_pcx;

  layer = 20;

  pos_x = 50;

  pos_y = 0;

  flags = overlay, refresh;

}

 

starter check_weapon_status()

{

  while (1)

  {

     if (got_weapon1 == 1) // got weapon1?

     {

        weapon1_pan.visible = on;

     }

     else

     {

        weapon1_pan.visible = off;

     }

     if (got_weapon2 == 1) // got weapon2?

     {

        weapon2_pan.visible = on;

     }

     else

     {

        weapon2_pan.visible = off;

     }

     wait (1);

  }

}

 

action weapon_first // attach it to the first weapon

{

  my.passable = on;

  while (player == null) {wait (1);}

  while (vec_dist (player.x, my.x) > 50)

  {

     my.pan += 5 * time;

     wait (1);

  }

  got_weapon1 = 1;

  my.invisible = on;

  // put the rest of your weapon code here

}

 

action weapon_second // attach it to the second weapon

{

  my.passable = on;

  while (player == null) {wait (1);}

  while (vec_dist (player.x, my.x) > 50)

  {

     my.pan += 5 * time;

     wait (1);

  }

  got_weapon2 = 1;

  my.invisible = on;

  // put the rest of your weapon code here

}

 

 

Q: How can I create a splash screen that pops up before loading a level and disappears after a key is hit? The code should work for several levels.

A: Use the code below as an example.

 

bmap splash_pcx = <splash.pcx>;

 

panel splash_pan

{

  bmap = splash_pcx;

  pos_x = 0;

  pos_y = 0;

  layer = 1;

  flags = overlay, refresh;

}

 

action level1_level2 // attach this action to any entity placed at the end of the first level

{

  while (player == null) {wait (1);}

  while (vec_dist (player.x, my.x) > 50) {wait (1);}

  while (key_any == on) {wait (1);} // wait until all the keys are released

  my = null;

  level_load(level2_wmb);

  freeze_mode = 1; // stop all the entities in the level

  splash_pan.visible = on;

  while (key_any == off) {wait (1);}

  splash_pan.visible = off;

  freeze_mode = 0; // resume the gameplay

}

 

action level2_level3 // attach this action to any entity placed at the end of the second level

{

  while (player == null) {wait (1);}

  while (vec_dist (player.x, my.x) > 50) {wait (1);}

  while (key_any == on) {wait (1);} // wait until all the keys are released

  my = null;

  level_load(level3_wmb);

  splash_pan.visible = on;

  while (key_any == off) {wait (1);}

  splash_pan.visible = off;

}

 

 

Q: In some games, if there is an object that should be picked up or examined, the player will turn its head as you move near the object. How can we do that?

A: Paste the code below at the end of your main script file:

 

entity* special;

 

function rotate_entity (active, passive, panspeed, tiltspeed);

 

function rotate_entity (active, passive, panspeed, tiltspeed)

{

  var target_pan;

  my = active;

  you = passive;

  vec_set (temp, your.x);

  vec_sub (temp, my.x);

  vec_to_angle (target_pan, temp);

  temp.pan = ang (target_pan - my.pan);

  target_pan = my.pan + temp.pan;

  if( my.pan < target_pan)

  {

     while(my.pan < target_pan)

     {

        my.pan += panspeed.pan * time;

        if (my.tilt > target_pan.tilt)

        {

            my.tilt -= tiltspeed * time;

        }

        if (my.tilt < target_pan.tilt)

        {

            my.tilt += tiltspeed * time;

        }

        wait(1);

     }

  }

  else

  {

     while(my.pan >= target_pan)

     {

        my.pan -= panspeed.pan * time;

        if (my.tilt > target_pan.tilt)

        {

            my.tilt -= tiltspeed * time;

        }

        if (my.tilt < target_pan.tilt)

        {

            my.tilt += tiltspeed * time;

        }

        wait(1);

     }

  }

}

 

action special_object

{

  special = my;

  while (player == null) {wait (1);}

  while (vec_dist (player.x, my.x) > 200) {wait (1);}

  while (vec_dist (player.x, my.x) <= 200)

  {

     rotate_entity (player, special, 0.1, 0);

     wait (1);

  }

}

 

 

Q: I have a problem scripting the movement of a spacecraft that can go forward and make turns (it's a 2D game). I need the ship to 'slide' in turns, just like a car riding on ice. Can you help?

A: Use this snippet:

 

starter set_camera()

{

   sleep (1); // wait until the level is loaded

   camera.x = 0;

   camera.y = 0;

   camera.z = 1000;

   camera.tilt = -90;

}

 

action asteroids_ship

{

  var ship_speed;

  while (1)

  {

     if (key_cuu == on)

     {

        if (ship_speed.x < 2)

        {

            ship_speed.x += 0.3 * time;

        }

     }

     else

     {

        if (ship_speed.x >= 0)

        {

            ship_speed.x -= 0.05 * time;

        }

     }

     if (ship_speed.x < 0) {ship_speed.x = 0;}

     if (key_cul == on)

     {

        my.pan += 3 * time;

     }

     if (key_cur == on)

     {

        my.pan -= 3 * time;

     }

     ent_move (ship_speed.x, nullvector);

     wait (1);

  }

}

 

aum43_shot9

 

 

Q: I use your "intelligent music" snippet from Aum38. How could I assign that action to as many entities as I want without having each of them playing their own instance?

A: Use the example below; it plays "gentle.wav" when the player comes closer than 500 quants, "tense.wav" when the player is closer than 100 quants and fades the music out when the player moves farther than 600 quants to the entity.

 

action music_trigger

{

   // my.invisible = on; // remove the comment when you've chosen the best position for the entity

   my.passable = on;

   while (player == null) {wait (1);}

   while (vec_dist (player.x, my.x) > 500) {wait (1);} // play with "500"

   music_handle = snd_loop (gentle_wav, 50, 0); // play the "gentle" sound track

   while (vec_dist (player.x, my.x) > 100) {wait (1);} // play with "100"

   temp_volume = 50; // put the same value that was used for snd_loop here

   while (temp_volume > 5) // decrease the volume slowly

   {

      snd_tune (music_handle, temp_volume, 0, 0);

      temp_volume -= 1 * time;

      wait (1);

   }

   snd_stop (music_handle); // stop "gentle.wav";

   music_handle = snd_loop (tense_wav, 50, 0); // play the "tense" sound track

   while (vec_dist (player.x, my.x) < 600) {wait (1);} // play with "600"

   temp_volume = 50;

   while (temp_volume > 5) // decrease the volume slowly

   {

      snd_tune (music_handle, temp_volume, 0, 0);

      temp_volume -= 1 * time;

      wait (1);

   }

   snd_stop (music_handle); // stop "tense.wav";

}

 

 

Q: Can you attach a typing sound to inkey somehow or do you have to write a new input function?

A: All the key_... functions (including key_any and on_anykey) are inactive during keyboard entry. However, you can write a simple input function using key_pressed and str_cat.