Questions from the forum

Top  Previous  Next

Q: I'd like to have a countdown timer that shuts down the game after 10 minutes of play. Can you help?

A: There you go.

 

var time_left = 600; // allow the player to run the game for 600 seconds (10 minutes)

var minutes_left = 0;

var seconds_left = 0;

 

STRING* time_str = "#30";

STRING* temp_str = "#10";

 

TEXT* time_txt =

{

       pos_x = 20;

       pos_y = 20;

       string(time_str);

       flags = SHOW;

}

 

function countdown_startup()

{

       while (time_left >= 0)

       {

               minutes_left = integer(time_left / 60);

               seconds_left = time_left - minutes_left * 60;

               str_cpy(time_str, "Time left to play: ");

               str_for_num(temp_str, minutes_left);

               str_cat(time_str, temp_str);

               str_cat(time_str, ":");

               str_for_num(temp_str, seconds_left);

               if (seconds_left < 10)

                       str_cat(time_str, "0");

               str_cat(time_str, temp_str);

               time_left -= 1;

               wait (-1);

       }

       sys_exit(NULL);

}

 

aum93_faq1

 

 

Q: I'd like to adjust the frame rate through a slider on a panel, thus increasing and decreasing the navigation speed in my level.

A: You don't want to do that - it will make your game run choppy at low frame rates. Use time_factor instead - here's an example that moves an entity on a path and allows you to control its speed.

 

var entity_speed = 3;

var movement_enabled = 0;

var dist_to_node;

var current_node = 1;

var angle_difference = 0;

 

VECTOR temp_angle;

VECTOR pos_node[3]; // stores the position of the node

 

BMAP* slider_tga = "slider.tga";

BMAP* pointer_tga = "pointer.tga";

 

PANEL* speed_pan =

{

       bmap = "speed_panel.tga";

       pos_x = 0;

       pos_y = 0;

       hslider(16, 24, 298, slider_tga, 0, 10, time_factor);

       flags = SHOW;

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

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 move_on_path() // attach this action to a model

{       

       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) {current_node = 1;} // reached the end of the path? Then start over!

                       path_getnode (my, current_node, pos_node, NULL);

               }

               wait(1);

       }

}

 

 

Q: Is there any chance to have a door scan its surroundings and slide horizontally when the player approaches it?

A: Sure, take a look.

 

var slide_once = 0;

 

action sliding_door()

{

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

       while (1)

         {

                 // the door scans on a range of 300 quants, trying to detect the "player" entity

               if ((c_scan(my.x, my.pan, vector(360, 180, 300), IGNORE_ME) > 0) && (you == player))

               {

                       slide_once += 1;

                       if (slide_once == 1) // do this only once

                       {

                               // this door slides along the x axis, feel free to use the y and z axis if they serve you better

                               my.skill90 = my.x;

                               while (my.x < my.skill90 + 100) // the door slides 100 quants along the x axis

                               {

                                       my.x += 3 * time_step; // 3 gives the sliding speed        

                                       wait (1);

                               }

                       }

               }

               else // the player has moved away from the door here

               {

                       slide_once = 0; // reset slide_once

                       while (my.x > my.skill90) // let's move the door back to its initial position

                       {

                               my.x -= 3 * time_step; // 3 gives the sliding speed        

                               wait (1);

                       }

                       my.x = my.skill90; // make sure that the end x position is the same with the initial x position

               }

                 wait (1);

       }

}

 

action players_code() // simple player code snippet

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       player = my; // I'm the player

       while (1)

       {

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

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1

               camera.pan = my.pan;

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

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 2

               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);

               wait (1);

       }

}

 

 

Q: I started to work at a racing game and I'd like to have a car selection screen, where the player uses two buttons to go through all the available car models.

A: Create a tiny room, place your car inside it and then use the code below.

 

var car_type = 1; // showing the first car model at game start

 

BMAP* arrowleft_pcx = "arrowleft.pcx";

BMAP* arrowright_pcx = "arrowright.pcx";

BMAP* pointer_tga = "pointer.tga";

 

STRING* tinylevel_wmb = "test.wmb";

 

ENTITY* car;

 

function cars_left();

function cars_right();

function set_current_car();

 

PANEL* leftclick_pan =

{

       bmap = "arrowleft.pcx";

       pos_x = 0;

       pos_y = 0;

       layer = 15;

       on_click = cars_left;

       flags = SHOW;

}

 

PANEL* rightclick_pan =

{

       bmap = "arrowright.pcx";

       pos_x = 750;

       pos_y = 0;

       layer = 15;

       on_click = cars_right;

       flags = SHOW;

}

 

void main()

{

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 1; // start in full screen mode

       level_load (tinylevel_wmb);

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

       // choose a proper camera position that allows you to see the cars perfectly

       vec_set (camera.x, vector(1000, 300, 200));

       // and maybe set the camera pan, tilt and roll angles as well

       vec_set (camera.pan, vector(100, -20, 5));

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function cars_left()

{

       car_type -= 1;

       car_type = maxv(1, car_type);

       set_current_car();

}

 

function cars_right()

{

       car_type += 1;

       car_type = minv(3, car_type);

       set_current_car();

}

 

function set_current_car()

{

       if(car_type == 1)

                 ent_morph(car, "car1.mdl");

       if(car_type == 2)

               ent_morph(car, "car2.mdl");

       if(car_type == 3)

               ent_morph(car, "car3.mdl");

  // add as many cars as you want here        

}

     

// attach this action to the car1.mdl model (the default car)

action my_cars()

{

       car = my;

       while (1)

       {

               my.pan += 3 * time_step;

               wait (1);

       }

}

 

aum93_faq2

 

 

Q: Did anyone use the string1 and string2 strings from within Wed? I'd like to see a simple example, if possible.

A: Here's an example that shows the content of string1 / string2 when an entity is clicked with the left / right mouse buttons.

 

BMAP* pointer_tga = "pointer.tga";

 

STRING* info_str = "#32";

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

TEXT* info_txt =

{

       pos_x = 50;

       pos_y = 20;

       string (info_str);

       flags = SHOW;

}

 

function strings_startup()

{

       while (1)

       {

               if (mouse_ent)

               {

                       if (mouse_left)

                               str_cpy(info_str, mouse_ent.string1); // put your text in entity's string1 in Wed

                       if (mouse_right)

                               str_cpy(info_str, mouse_ent.string2); // put your text in entity's string1 in Wed                                

                       set(info_txt, SHOW);

               }

               else

               {

                       reset(info_txt, SHOW);

               }

               wait (1);

       }

}

 

aum93_faq3

 

aum93_faq4

 

 

Q: I'm looking for the easiest way to make drop shadows, that you can see in various games under the characters.

A: Here's a simple, and yet fully functional example that allows you to play with several types of shadows.

 

#include <acknex.h>

#include <default.c>

#include <mtlView.c> // contains the stencil_blur() function

 

STRING* test_wmb = "test.wmb";

 

function main()

{

       camera.ambient = 70;

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 1; // start in full screen mode

       level_load (test_wmb);

       wait (2);

         ent_createlayer("skycube+6.tga", SKY | CUBE | SHOW, 1);        

       shadow_stencil = 4; // use values in the 0...4 range

       shadow_lod = 2; // use the second LOD stage for stencil shadows

       stencil_blur(1); // activate blurred shadows        (included in mtlView.c, look better)

}

 

action shadow_model() // simple action that rotates this model in a circle

{

       set(my, SHADOW);

       while (1)

       {

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

                 my.pan += 2 * time_step; // 2 sets the radius of the circle

                 wait (1);

       }

}

 

aum93_faq5

 

 

Q: I don't know if  this is covered anywhere, but how do I make the number pad keys (2, 4, 6, 8) control player's movement?

A: Here's a fully functional example.

 

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

{        

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       while (1)

       {

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

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44);

               camera.pan = my.pan;

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

               vec_set (temp.x, my.x);

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2;

               temp.x = movement_speed * (key_pressed(72) - key_pressed(80)) * time_step;

               temp.y = movement_speed * (key_pressed(75) - key_pressed(77)) * 0.6 * time_step;

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

               wait (1);

       }

}

 

 

Q: How can I create a health bar for my player character?

A: There you go.

 

var players_health;

 

PANEL* health_pan =

{

       bmap = "redbar.pcx"; // a bitmap with x = 2, y = 12 pixels

       pos_x = -10;

       pos_y = 0;

       layer = 10;

       flags = SHOW;

}

 

function health_startup()

{

       while (1)

       {

               health_pan.scale_x = maxv(0.001, players_health * 3.5); // 3.5 = experimental value

               wait (1);

       }

}                

               

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

{        

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       players_health = 100; // the player starts with 100 health points

       while (players_health > 0)

       {

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

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44);

               camera.pan = my.pan;

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

               vec_set (temp.x, my.x);

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2;

               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, GLIDE);

               wait (1);

       }

       // the player is dead here

       camera.z -= 20;

       camera.roll = -35;

}

 

action health_taker()

{

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

       while (1)

       {

               if (vec_dist(player.x, my.x) < 200)

                       players_health -= 2 * time_step;

               wait (1);

       }

}

 

aum93_faq6

 

 

Q: I'd like to have a camera that can rotate around the player whenever I want it to. Player's movement would be done using the WSAD keys and the camera rotation would be done using the OP keys.

A: There you go.

 

function camera_startup()

{

       var orbit_radius = 200; // use your own value here

       var orbit_speed = 4; // and here

       var temp_angle;

       VECTOR orbit_center, temp;

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

       vec_set (orbit_center.x, player.x); // store the orbit center position

       while(1)

       {

               camera.x = orbit_center.x + sin(temp_angle) * orbit_radius;

               camera.y = orbit_center.y + cos(temp_angle) * orbit_radius;

               camera.z = orbit_center.z + 50; // play with 50

               camera.tilt = -20; // play with -20

               // use the "O" (not zero!) and "P" keys to rotate the camera around the player

               temp_angle += 1 * (key_o - key_p) * orbit_speed * time_step; // 1 gives the camera rotation speed

               vec_set(temp, player.x);

               vec_sub(temp, camera.x);

               vec_to_angle(camera.pan, temp); // make the camera look at the player all the time

               wait(1);

       }

}

 

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

{        

       var movement_speed = 20;

       VECTOR temp;

       player = my;

       while (1)

       {

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

               vec_set (temp.x, my.x);

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) + 20; // 20 gives the distance to ground

               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);

               wait (1);

       }

}

 

aum93_faq7

 

 

Q: Is there a way to keep a particle under a moving entity? I have fire that pushes out the bottom of my entity, but when the entity moves, the particles stay were they were created, leaving a trail of fire behind.

A: The easiest solution is to create particles with a very short lifespan value - here's a fully functional example.

 

BMAP* fire_tga = "fire.tga";

 

function fade_jet(PARTICLE *p)

{

       p.alpha -= 40 * time_step; // fade out the fire particles, play with this value

       if (p.alpha < 0)

               p.lifespan = 0;

}

 

function jet_effect(PARTICLE *p)

{

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

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

       p->vel_z = 1 + random(1);

       p.lifespan = 10; // play with this value

       p.alpha = 25 + random(50);

       p.bmap = fire_tga;

       p.size = 25; // gives the size of the fire particles

       p.flags |= (BRIGHT | MOVE);

       p.event = fade_jet;

}

 

action my_player() // dummy player action

{

       VECTOR jet_offset;

       while (1)

       {

               // put your own player code here

               // the example below simply makes the player rotate in a circle

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

               my.pan += 2 * time_step; // 2 sets the radius of the circle

             

               // place the particle jet at the proper position, play with the offset values below

            vec_set(jet_offset.x, vector(-100, -10, -20));

               vec_rotate(jet_offset.x, my.pan);

             vec_add(jet_offset.x, my.x);

            effect(jet_effect, 1, jet_offset.x, nullvector); // generate a jet particles per frame

               wait (1);

       }

}