Questions from the forum

Top  Previous  Next

Q: I'm looking for an auto game save snippet; when the player reaches a certain point in the level, the game saves, and if the player dies, he starts again at the save point, and not at the beginning of the level.

A: Here's a fully functional example.

 

var players_health = 100;

VECTOR player_position;

ANGLE player_angle;

 

action players_code() // attach this action to your player model

{        

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               temp.x = movement_speed * (key_w - key_s) * time_step;

               temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step;

               temp.z = 0;

               c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE);

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50;

               camera.pan = my.pan;

               camera.tilt += 5 * mouse_force.y * time_step;

               while (players_health <= 0) // the player is dead?

               {

                       camera.roll = 70; // then let's make the camera look weird

                       camera.z = player.z - 30; // this while loop will prevent the player from moving

                       wait (1);

               }

               wait (1);

       }

}

 

action checkpoint() // attach this to your autosave model (a portal, a gate, etc)

{

       while (!player) {wait (1);} // wait until the player model is loaded in the level

       // wait until the player comes closer than 200 quants to the autosave model

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

       vec_set (player_position, player.x); // store player's position                

       vec_set (player_angle, player.pan); // store player's angles

       // put a nice "Game Saved!" panel here, make it visible for a few seconds, and then remove it

}

 

function restore_startup() // restores player's health and angles

{

       while (1)

       {

               while (players_health > 0) // wait until the player is dead

               {

                       wait (1);        

               }

               // now let's restore player's health

               players_health = 100;

               vec_set (player.x, player_position); // and its autosave position

               vec_set (player.pan, player_angle); // and angles        

               camera.roll = 0; // restore camera's roll angle as well

               wait (1);

       }

}

 

function take_health()

{

       if (you == player) // collided with the player?

               players_health = 0; // then make it die!

}

 

action health_taker() // run into this entity to make the player lose its health

{

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // this entity is sensitive to impact with entities

       my.event = take_health; // and runs this function when it is hit

}

 

 

Q: I want to check if a video is still being played. Is there any way to do this?

A: There you go.

 

var movie_handle;

 

function movie_playing_startup()

{

       movie_handle = media_play("mymovie.avi", NULL, 70);

       while (media_playing (movie_handle)) {wait (1);}

       beep(); beep(); // the movie has stopped here, so do what you need

}

 

 

Q: I used ent_create to attach a flare to a key model, so that player can find the key easier in the level. Now I want to remove the flare as soon as the key model is removed. Is there any way to do this?

A: Here's an example.

 

var got_key = 0;

 

function attach_flare()

{

       set (my, PASSABLE);

       while (you) // this loop will run for as long as the key model exists

       {

               my.x = you.x; // place the flare at the same position with the origin of the key model

               wait (1);

       }        

       ent_remove (my); // the key is gone now, so let's remove the flare sprite as well

}

 

action glowing_key()

{

       set (my, PASSABLE);

       ent_create ("flare.tga", my.x, attach_flare);

       while (!player) {wait (1);}

       while (vec_dist (player.x, my.x) > 70) // wait until the player comes close to the key

       {

               my.pan += 3 * time_step;

               wait (1);

       }

       got_key = 1; // set the got_key variable, we will use it later in the game to open the corresponding door

       ent_remove (my); // and then remove it

}

 

 

Q: I am working at a racing game based on the car template and I'd like to have my cars rotate (change their pan) in a car selection screen, but only do that while they are touched by the mouse. Can you help?

A: Here's a simple example that does what you want.

 

BMAP* arrow_pcx = "arrow.pcx";

 

function mouse_startup()

  mouse_mode = 2;

  mouse_map = arrow_pcx;

  while (1)

  { 

       vec_set(mouse_pos, mouse_cursor);

       wait(1);

  }

}

 

function rotate_me()

{

       proc_kill(1);

       while (event_type != EVENT_RELEASE)

       {

               my.pan += 3 * time_step;

               wait (1);

       }

}

 

action rotating_car()

{

  my.emask |= ENABLE_TOUCH | ENABLE_RELEASE;

  my.event = rotate_me;

}

 

 

Q: I'd like my camera to follow the player at all times, changing to a camera that rotates around slowly, showing the nearby areas, if the player doesn't move at all for 10 seconds. How can I do this?

A: Here's a fully functional player / camera action.

 

action player_and_camera() // attach this action to your player model

{        

       var camera_time = 10; // the camera starts rotating around after 10 seconds

       var camera_increments = 0;

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       while (1)

       {

               if (key_any) // the player has pressed one of the keys? Then let's reset camera_increments!

               {

                       camera_increments = 0;        

               }

               else // no key is being pressed? Then let's increase camera_increments!

               {

                       camera_increments += time_step / 16; // add 1 to camera_increments each second

               }                

               my.pan -= 7 * mouse_force.x * time_step;

               temp.z = 0;

               temp.x = movement_speed * (key_w - key_s) * time_step;

               temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step;

               c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE);

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50;

               if (camera_increments > 10) // the player didn't touch any of the keys for at least 10 seconds?

               {

                       camera.pan += 0.8 * time_step;

               }

               else

               {

                       camera.pan = my.pan;

               }

               camera.tilt += 5 * mouse_force.y * time_step;

               wait (1);

       }

}

 

 

Q: Do you have an example for a door that opens automatically (sliding vertically) when the player approaches it and closes automatically when the player has moved away from it?

A: Sure thing.

 

var trigger_range = 100;

 

SOUND* sliding_wav = "sliding.wav";

 

action my_door()

{

       var initial_z;

       // make sure to include a "player = my;" line of code to your player action

       while (!player) {wait (1);}

       initial_z = my.z;

  while (1)

  {

         // wait until the player comes closer than 100 quants to the door, play with trigger_range

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

               snd_play (sliding_wav, 100, 0);

               // slide the door upwards by 200 quants, play with this value

               while (my.z < (initial_z + 200))

               {

            my.z += 5 * time_step; // 5 gives the upwards sliding speed

        wait (1);

               }

               // wait until the player moves away 500 quants from the door (5 * trigger_range)

               while (vec_dist (player.x, my.x) < (5 * trigger_range)) {wait (1);}

               snd_play (sliding_wav, 100, 0);

               while (my.z > initial_z) // slide the door downwards, until it reaches the initial height

               {

            my.z -= 5 * time_step; // 5 gives the downwards sliding speed

        wait (1);

               }

               // make sure that the door returns to the exact initial position regardless of the frame rate value

               my.z = initial_z;

     wait (1);

       }

}

 

 

Q: I'd like to have a weapon which fires bullets that don't disappear, but bounce from wall to wall indefinitely.

A: Use the snippet below; don't forget that each new bullet is a new entity that will stay in the level, so if you're going to fire thousands of bullets the frame rate will decrease.

 

var front_offset = 30; // animates player's weapon while it is firing by moving it backwards

var init_offset = 30; // stores front_offset's value

 

ENTITY* weapon1;

 

STRING* bullet_mdl = "bullet.mdl";

 

SOUND* bullet_wav = "bullet.wav";

 

function fire_bullets();

function move_bullets();

function redirect_bullets();

 

action players_weapon() // place your weapon model in the level and attach it this action

{

  weapon1 = my; // I'm weapon1

  VECTOR player1_pos; // stores the initial position of the player

  VECTOR player2_pos; // stores the position of the player after a frame

  VECTOR weapon_offset;

  var weapon_height;

  set (my, PASSABLE); // the weapon model is passable

  while (!player) {wait (1);} // wait until the player is created

  while (vec_dist (player.x, my.x) > 50) {wait (1);} // wait until the player comes close to pick up the weapon

  my.roll = 0;

  while (1)

  {

         vec_set (player1_pos.x, player.x); // store the initial player position

     // place the weapon 30 quants in front, 18 quants to the right and 20 quants below camera's origin

     vec_set (weapon_offset.x, vector (front_offset, -18, -20));

     if (vec_dist (player1_pos.x, player2_pos.x) != 0) // the player has moved during the last frame?

     {

            weapon_height += 30 * time_step; // then offset weapon_height (30 = weapon waving speed)

        weapon_offset.z += 0.3 * sin(weapon_height); // (0.3 = weapon waving amplitude)

               }

     // rotate weapon_offset according to the camera angles

     vec_rotate (weapon_offset.x, vector (camera.pan, camera.tilt, 0));

     vec_add (weapon_offset.x, camera.x); // add the camera position to weapon_offset

     vec_set (my.x, weapon_offset.x); // set weapon's coords to weapon_offset

     my.pan = camera.pan; // use the same camera angles for the weapon

     my.tilt = camera.tilt;

     vec_set (player2_pos.x, player.x); // store the new player coordinates after 1 frame

     wait (1);

       }

}

 

function weapon_startup()

{

       on_mouse_left = fire_bullets; // call function fire_bullets() when the left mouse button is pressed

}

 

function fire_bullets() // includes the code that animates the weapon as well

{

  var temp_seconds = 0;

  VECTOR temp;

  proc_kill(4); // don't allow more than 1 copy of this function to run

  while (mouse_left) // this loop runs for as long as the left mouse button is pressed

  {

               front_offset -= 1; // move the weapon backwards a bit

               vec_for_vertex (temp.x, weapon1, 29); // get the coordinates for the bullets' origin

               // create the bullet at camera's position and attach it the "move_bullets" function

     ent_create (bullet_mdl, temp.x, move_bullets);

     temp_seconds = 0;

     snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100

     while (temp_seconds < 0.5)

     {

            temp_seconds += time_step / 16; // adds 0.5 to temp_seconds in 0.5 seconds)

        front_offset -= 0.1; // restore the position of the weapon

        wait (1);

     }

     while (front_offset < init_offset)

     {

            front_offset += 0.1; // restore the position of the weapon

        wait (1);

     }

     front_offset = init_offset;

       }

}

 

function move_bullets()

{

  VECTOR bullet_speed; // stores the speed of the bullet

  my.skill30 = 1; // I'm a bullet

  my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK);

  my.event = redirect_bullets; // when it collides with something, its event function (redirect_bullets) will run

  my.pan = camera.pan; // the bullet has the same pan

  my.tilt = camera.tilt; // and tilt with the camera

  bullet_speed.x = 200 * time_step; // adjust the speed of the bullet here

  bullet_speed.y = 0; // the bullet doesn't move sideways

  bullet_speed.z = 0; // then don't allow the gravity to have its ways with the bullet

  while (my) // this loop will run for as long as the bullet exists (it isn't "null")

  {

         // move the bullet ignoring the passable entities and store the result in distance_covered

     c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE);

     wait (1);

  }

}

 

function redirect_bullets() // this function runs when the bullet collides with something

{

       vec_to_angle(my.pan, bounce); // change the angle of the bullet

}

 

 

Q: In my game, the users have profiles to write their data; what should I do with these profiles when I publish my game? If I put them in the wrs file I can't change them anymore, and if i put them out of the wrs file, the users can change them to anything that they want to. Is there any way to solve this problem?

A: You can save the profiles to regular txt file, encrypting the information before writing it to the file and decrypting it before using it. Check out the Ncrypt article from Aum53 to see an example.

 

 

Q: I need a piece of code that will display a sphere made out of particles for my Star Wars clone. What is an easy method to create that?

A: The easiest method would be to use a sphere model and generate a particle from each one of its vertices - here's an example.

 

BMAP* particle_tga = "particle.tga";

 

function keep_particle(PARTICLE *p)

{

       p.lifespan = 99999; // use a big value here

}

 

function particle_effect(PARTICLE *p)

{

  p.bmap = particle_tga;

  p.size = 2; // gives the size of the particles

  p.flags |= BRIGHT;

  p.event = keep_particle;

}

 

action sphere() // attach this action to a sphere model

{

       set (my, PASSABLE | INVISIBLE);

       var particle_pos[3];

       while (my.skill1 < ent_vertices (my))

         {

                   my.skill1 += 1;

             vec_for_vertex(particle_pos, my, my.skill1);

                 effect(particle_effect, 1, particle_pos, nullvector);

       }

}

 

aum99_faq

 

 

Q: I'd like an example of code that starts playing a soundtrack and after a specified interval fades it out, while at the same time fading in a new soundtrack, just the way they do it at radio stations.

A: Here's an example that does what you want.

 

var track1_volume = 100;

var track2_volume = 1;

 

function music_startup()

{

       var track1_handle, track2_handle;

       track1_handle = media_play("track1.wav", NULL, track1_volume);

       wait (-20); // play the first track for 20 seconds

       track2_handle = media_play("track2.wav", NULL, track2_volume); // now start the second track at a tiny volume (1)

       while (track1_volume > 0) // now change the volume - decrease it gently

       {

                 media_tune(track1_handle, track1_volume, 100, 0);

                 media_tune(track2_handle, track2_volume, 100, 0);          

            track1_volume -= 0.6 * time_step; // 0.6 gives the fade-out speed

             track1_volume = maxv(track1_volume, 0);

            track2_volume += 0.8 * time_step; // 0.8 gives the fade-in speed

             track2_volume = minv(track2_volume, 100);     

            wait (1);

       }

       wait (-20); // play the second track for 20 seconds        

       media_stop (track1_handle); // now stop the sound tracks for good

       media_stop (track2_handle);

}