Questions from the forum

Top  Previous  Next

Q: I am trying to find a simple example of a working health bar code for the player and an enemy

A: There you go.

 

var players_health = 100;

var enemy_health = 100;

 

BMAP* health_pcx = "health.pcx";

 

PANEL* health_pan =

{

       pos_x = 10;

  pos_y = 20;

  layer = 10;

       window(50, 0, 40, 20, health_pcx, players_health, 0);

  flags = SHOW;

}

 

PANEL* enemy_pan =

{

       pos_x = 10;

  pos_y = 20;

  layer = 10;

       window(500, 0, 40, 20, health_pcx, enemy_health, 0);

  flags = SHOW;

}

 

// just for testing, use the 1... 4 keys to increase / decrease the health for the player and for the enemy

function health_startup()

{

       while (1)

       {

               if (key_1) players_health += 2 * time_step;

               if (key_2) players_health -= 2 * time_step;

               if (key_3) enemy_health += 2 * time_step;

               if (key_4) enemy_health -= 2 * time_step;

               wait (1);

       }        

}

 

 

Q: I would need a teleport, an entity that teleports you to another place in the level when you walk on it.

A: Here's a fully working example.

 

action my_teleport()

{

       set(my, POLYGON); // use polygon-based collision detection

       // your player action or function should include a "player = my;" line of code

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

       while (1)

       {

               if (vec_dist(player.x, my.x) < 100) // trigger distance, play with 100

               {

                       while (key_any) {wait (1);} // wait until the player releases all the keys

                       // now teleport the player to its new position (choose the vector coordinates properly)        

                       vec_set (player.x, vector (400, 700, -150));

               }

               wait (1);

       }

}

 

 

Q: I am writing variables to a file via file_var_write and need to play them back in real time the exact same way they were recorded. The problem is that every time I try to do this it always seems to be a little faster on the playback; is there any way to fix this?

A: Your computer records the data at a smaller frame rate, and then it plays it back at a higher frame rate, thus accelerating the action. A simple solution would be to set fps_max to a smaller value (40... 60); this will allow you to get rid of the problem for good.

 

 

Q: What is the best way to display a dynamic text in 3D?

A: Use a character set created out of models and the snippet below as a base for your code.

 

STRING* display_str = "#40"; // backup string

STRING* temp_str = "#40"; // backup string

 

var str_count;

var string_index = 0;

var position_y = 500;

 

function letter_function()

{

       set(my, PASSABLE);

       my.pan = 270; // orient the letters according to your needs        

}

 

function letters_startup()

{

       str_cpy (display_str, "great graphics");

       while (!player) {wait (1);} // wait until the player is loaded (if needed)

       position_y = 800;

       str_count = str_len(display_str);

       while (string_index < str_count)

       {

               str_cpy (temp_str, display_str); // copy display_str to temp_str (we don't want to destroy it)

               str_clip(temp_str, string_index); // cut the needed number of characters from the beginning of the string

               str_trunc(temp_str, str_count - string_index - 1); // and cut from the end as well

               // here we've got the letters that create our string, one by one

               // in this example we create them along the y axis (the value of y is decreased at all times until all the letters are in place)

               if (str_cmpi(temp_str, "a"))

                       ent_create("a.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "b"))

                       ent_create("b.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "c"))

                       ent_create("c.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "d"))

                       ent_create("d.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "e"))

                       ent_create("e.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "f"))

                       ent_create("f.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "g"))

                       ent_create("g.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "h"))

                       ent_create("h.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "i"))

                       ent_create("i.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "j"))

                       ent_create("j.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "k"))

                       ent_create("k.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "l"))

                       ent_create("l.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "m"))

                       ent_create("m.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "n"))

                       ent_create("n.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "o"))

                       ent_create("o.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "p"))

                       ent_create("p.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "q"))

                       ent_create("q.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "r"))

                       ent_create("r.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "s"))

                       ent_create("s.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "t"))

                       ent_create("t.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "u"))

                       ent_create("u.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "v"))

                       ent_create("v.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "w"))

                       ent_create("w.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "x"))

                       ent_create("x.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "y"))

                       ent_create("y.mdl", vector(-100, position_y, -100), letter_function);

               if (str_cmpi(temp_str, "z"))

                       ent_create("z.mdl", vector(-100, position_y, -150), letter_function);

                                       position_y -= 120; // set an offset of 120 quants between 2 consecutive letters

               string_index += 1; // increase string_index

       }        

}

 

aum104_faq1

 

 

Q: How can I control a robot by reading the movement instructions from a text file?

A: There you go.

 

var string_handle;

var eof_reached = 0; // will be set to -1 when the end of the file (eof) is reached

var temp_coords;

 

STRING* direction_str = "#10";

 

ENTITY* robot;

 

action my_robot()

{

       robot = my;

}

 

function read_startup()

{

       while (!robot) {wait (1);} // wait until the robot model is loaded

       wait (-5); // give the player some time to prepare for the show (some monitors need a lot of time to switch to the proper resolution)

       string_handle = file_open_read("commands.txt"); // open the commands.txt file

       while (eof_reached != -1) // the end of the file wasn't reached yet?

       {

               eof_reached = file_str_read(string_handle, direction_str); // read a string from the file

               if (str_cmpi(direction_str, "left")) // read a "left" command? Then let's increase the y coordinate

               {

                       temp_coords = robot.y;                                                

                       while (robot.y < temp_coords + 50)

                       {

                               c_move(robot, nullvector, vector(0, 5 * time_step, 0), IGNORE_PASSABLE);

                               wait (1);

                       }

               }

               if (str_cmpi(direction_str, "right")) // read a "right" command? Then let's decrease the y coordinate

               {

                       temp_coords = robot.y;                                                

                       while (robot.y > temp_coords - 50)

                       {

                               c_move(robot, nullvector, vector(0, -5 * time_step, 0), IGNORE_PASSABLE);

                               wait (1);

                       }

               }

               if (str_cmpi(direction_str, "forward")) // read a "forward" command? Then let's increase the x coordinate

               {

                       temp_coords = robot.x;                                                

                       while (robot.x < temp_coords + 50)

                       {

                               c_move(robot, nullvector, vector(5 * time_step, 0, 0), IGNORE_PASSABLE);

                               wait (1);

                       }

               }

               if (str_cmpi(direction_str, "back")) // read a "back" command? Then let's decrease the x coordinate

               {

                       temp_coords = robot.x;                                                

                       while (robot.x > temp_coords - 50)

                       {

                               c_move(robot, nullvector, vector(-5 * time_step, 0, 0), IGNORE_PASSABLE);

                               wait (1);

                       }

               }

               wait (-1); // wait a second after each command

       }

       file_close (string_handle); // all the strings are read here, so close the file

}

 

aum104_faq2

 

 

Q: I would like to know how I can stitch 2 grounds together.

A: Check out function terrain_tile, which can be found in Gamestudio's \include\level.c script file or the terrain sewer project from Aum84.

 

 

Q: What is the best way to make an NPC disappear at the end of his path and go back at the beginning over and over? I want to create a dynamic city street scene.

A: Here's an example.

 

var entity_speed = 3;

var movement_enabled = 0;

var dist_to_node;

var current_node = 1;

var angle_difference = 0;

 

ANGLE temp_angle, pos_node;

 

function move_target()

{

       while(1)

       {

               if(movement_enabled)

               {

                       entity_speed = minv(5, entity_speed + 0.5 * time_step);

                       c_move(my, vector(entity_speed * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

                       vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x));

               }

               wait(1);

       }

}

 

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

{       

       VECTOR init_pos;

       vec_set (init_pos.x, my.x); // store the initial coordinates

       move_target();

       result = path_scan(me, my.x, my.pan, vector(360, 180, 1000));

       if (result) {movement_enabled = 1;}

       path_getnode (my, 1, pos_node, NULL);

       vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x)); // rotate towards the node

       while(1)

       {

               dist_to_node = vec_dist(my.x, pos_node);

               if(dist_to_node < 50) // close to the node?

               {

                       current_node = path_nextnode(my, current_node, 1);

                       if (!current_node) // reached the end of the path? Then start over!

                       {

                               current_node = 1; // reset the node

                               vec_set (my.x, init_pos.x); // and then teleport the player at its initial position in the level

                       }

                       path_getnode (my, current_node, pos_node, NULL);

               }

               wait(1);

       }

}

 

 

Q: I'd like the player to shoot fireballs that get destroyed when they collide with other entities.

A: Use the snippet below.

 

BMAP* fire_tga = "fire.tga";

 

STRING* fireball_mdl = "fireball.mdl";

 

SOUND* fireball_wav = "fireball.wav";

SOUND* destroyed_wav = "destroyed.wav";

 

function fire_fireball();

function shoot_fireball();

function remove_fireball();

function fade_fire(PARTICLE *p);

function fire_effect(PARTICLE *p);

 

function init_startup()

{

       on_mouse_left = fire_fireball;        

}

 

function fire_fireball()

{

       ent_create (fireball_mdl, player.x, shoot_fireball);

       snd_play (fireball_wav, 50, 0);

}

 

function shoot_fireball()

{

       VECTOR fireball_speed, temp;

       my.emask |= (ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_fireball;

       set (my, PASSABLE);

       my.pan = camera.pan;

       my.tilt = camera.tilt;

       my.skill20 = 0;

       vec_set(fireball_speed.x, nullvector);

       fireball_speed.x = 100 * time_step;

       my.skill10 = 0;

       while (my.skill20 < 500)

       {

               effect(fire_effect, 10, my.x, nullvector);                

               if (vec_dist (player.x, my.x) > 100)

                       reset (my, PASSABLE);

               if ((my.skill10 == 0) && (vec_dist (my.x, player.x) > 100))

               {

                       // play with 500, sets the damage range

                       c_scan(my.x, my.pan, vector(40, 60, 500), IGNORE_ME | SCAN_ENTS);

               }

               my.skill20 += 1 * time_step;

               c_move (my, fireball_speed.x, nullvector, IGNORE_FLAG2 | IGNORE_PASSABLE);

               wait (1);

       }

       remove_fireball();

}

 

function remove_fireball()

{

       wait (1);

       my.event = NULL;

       ent_playsound (my, destroyed_wav, 1000); // play the explosion sound

       set (my, INVISIBLE); // hide the fireball, keep ent_playsound playing

       wait (-1.5); // wait for 1.5 seconds

       ent_remove(me); // now remove it

}

 

function fade_fire(PARTICLE *p)

{

       p.alpha -= 4 * time_step; // fade out the fire particles

  if (p.alpha < 0)

         p.lifespan = 0;

}

 

function fire_effect(PARTICLE *p)

{

       set (my, PASSABLE);

       p->vel_x = 1 - random(2);

       p->vel_y = 1 - random(2);

       p->vel_z = 3 - random(6);

       p.alpha = 20 + random(50);

       p.bmap = fire_tga;

       p.size = 10 + random(5); // gives the size of the flame particles

       p.flags |= (BRIGHT | MOVE);

       p.event = fade_fire;

}

 

 

Q: I want to create an entity that follows the player. Can anyone help?

A: Here's the code that does what you want.

 

function player_follower();

 

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

{        

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       ent_create("guard.mdl", nullvector, player_follower);

       while (1)

       {

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

               vec_set (temp.x, my.x);

               temp.z -= 10000;

               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;

               camera.pan = my.pan;

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

               wait (1);

       }

}

 

function player_follower()

{

       var walk_percentage;

       while (1)

       {

               // play with the numerical values; they give the xyz offset of the follower in relation with the player

               vec_set(my.x, vector(150, -60, 0));

               vec_rotate(my.x, you.pan);

               vec_add(my.x, you.x);

               my.pan = you.pan;

                 ent_animate(my, "walk", walk_percentage, ANM_CYCLE); // play the "stand" aka idle animation

            walk_percentage += 5 * (key_w - key_s) * time_step; // increase walk_percentage only if the player is moving

               wait (1);

       }

}

 

 

Q: How can I make certain entities in my level to be visible even if they are behind walls?

A: Here's a simple example.

 

action hidden_entities()

{

       while (1)

       {

               // press the "v" key to make the entities visible

               if (key_v)

                       set(my, ZNEAR);

               else

                       reset(my, ZNEAR);

               wait (1);

       }        

}

 

aum104_faq3