Questions from the forum

Top  Previous  Next

Q: How can I create the code that displays a menu when the player has clicked a building?

A: Use this example; it allows you to increase or decrease the size of your buildings using a panel with 2 buttons.

 

VECTOR* building_pos[3];

 

BMAP* arrow_pcx = "arrow.pcx";

BMAP* building_pcx = "building.pcx";

BMAP* increase1_pcx = "increase1.pcx";

BMAP* increase2_pcx = "increase2.pcx";

BMAP* decrease1_pcx = "decrease1.pcx";

BMAP* decrease2_pcx = "decrease2.pcx";

 

ENTITY* active_building;

 

function increase_size();

function decrease_size();

 

PANEL* building_pan =

{

       bmap = "building.pcx";

       button = 0, 0, increase1_pcx, increase2_pcx, increase1_pcx, increase_size, NULL, NULL;

       button = 128, 0, decrease1_pcx, decrease2_pcx, decrease1_pcx, decrease_size, NULL, NULL;

}

 

function mouse_startup()

   mouse_mode = 2;

   mouse_map = arrow_pcx;

   while (1)

   { 

        vec_set(mouse_pos, mouse_cursor);

        wait(1);

   }

}

 

function increase_size()

{

       active_building.scale_x += 0.3;

       active_building.scale_y = active_building.scale_x;

       active_building.scale_z = active_building.scale_x;

}

 

function decrease_size()

{

       active_building.scale_x -= 0.2;

       active_building.scale_y = active_building.scale_x;

       active_building.scale_z = active_building.scale_x;

}

 

function display_menu()

{

       active_building = my;

       vec_set(building_pos, my.x);

       vec_to_screen(building_pos, camera);

       building_pan.pos_x = building_pos.x;

       building_pan.pos_y = building_pos.y;

       building_pan.flags |= VISIBLE;

 

}

 

action building_with_menu()

{

   my.emask |= ENABLE_CLICK;

   my.event = display_menu;

}

 

 

Q: Is there a special way to divide numbers? If I try to divide 6 / 4 I get "1" as the result.

A: You won't have any problems if you define two variables and initialize them with 6 and 4, but if you want to hardcode numerical values into your programs make sure that at least one of the numbers has a decimal (even if it is a zero), just like in the example below.

 

var my_result;

 

void main()

{

       video_mode = 7;

       screen_color.blue = 150;

       my_result = 6.0 / 4;

}

 

PANEL* result_pan =

{

       digits (300, 200, "%f", *, 1, my_result);

       flags = VISIBLE;

}

 

 

Q: Could you please give us a snippet that's as simple as possible and includes all the needed lite-C code for a standalone 1st person player / camera combination?

A: Paste the code below into a test.c file (or any other name) and you're ready to go.

 

#include <acknex.h>

#include <default.c>

 

STRING* test_wmb = "test.wmb";

 

void main()

{

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

}

 

action players_code() // simple player and 1st person camera code

{

       player = my; // I'm the player

       set (my, INVISIBLE); // no need to see player's model in 1st person mode

       while (1)

       {

               // move the player using the "W", "S", "A" and "D" keys; "10" = movement speed, "6" = strafing speed

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x); // use player's x and y for the camera as well

               camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level)

               camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse

               camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis

               player.pan = camera.pan; // the camera and the player have the same pan angle

               wait (1);

       }

}

 

 

Q: I want to change the model when the player dies; this way,  I could use an impressive death sequence.

A: Here's an example that uses ent_morph to do what you want.

 

var players_health = 100;

 

STRING* deadbody_mdl = "deadbody.mdl";

 

action players_code()

{

       var anim_percentage;

       player = my;

       while (players_health > 0)

       {

               c_move (my, vector(10 * (key_w - key_s) * time_step, 0, 0), nullvector, GLIDE);

               my.pan += 6 * (key_a - key_d) * time_step;

               vec_set (camera.x, player.x);

               camera.z += 300;

               camera.tilt = -90;

               camera.pan = player.pan;

 

               if (key_w || key_s) // one of the movement keys is pressed?

           {

                    ent_animate(my, "walk", anim_percentage, ANM_CYCLE);

                anim_percentage += 8 * time_step; // "8" controls the "walk" animation speed

           }

           else // the player is standing still?

           {

                ent_animate(my, "stand", anim_percentage, ANM_CYCLE);

                anim_percentage += 1 * time_step; // "1" controls the "stand" animation speed

           }

               wait (1);

       }

       // make sure that the enemies decrease the "players_health" variable

       // the player is dead here, so morph it into another model

       ent_morph (my, deadbody_mdl);

       // do something else with the dead body here

       // ..........

}

 

 

Q: How do I get an entity to blink when I move the mouse over it (like fading in and out white)?

A: Attach this action to your player.

 

var entity_touched = 0;

 

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 blink_me()

{

       if (event_type == EVENT_RELEASE)

       {

               entity_touched = 0;

               my.red = 0;

               my.green = 0;

               my.blue = 0;

       }

       if (event_type == EVENT_TOUCH)

       {

               entity_touched = 1;

               // loop for as long as the mouse pointer is touching the entity

               while (entity_touched)

               {

                       my.red = 255 * sin(total_ticks % 25); // 25 = blinking speed

                       my.green = my.red;

                       my.blue = my.red;

                       wait (1);

               }

       }

}

 

action blinking_entity()

{

   set (my, LIGHT);

   my.emask |= ENABLE_TOUCH | ENABLE_RELEASE;

   my.event = blink_me;

}

 

 

Q: I have a countdown timer and I would like to put a 3D bar on the screen and connect it to the timer. As the time decreases, the bar would become smaller and smaller. Is this possible?

A: Sure; use a "view" entity and move it downwards just like in the example below.

 

var current_time = 100;

 

ENTITY* timer_bar =

{

       type = "bar.mdl"; // this is your bar model

       layer = 10;

       x = 100; // play with these values until the lower part of the bar is placed at the bottom of the screen

       y = -50;

       z = -25;

       view = camera;

       flags2 = VISIBLE;

}

 

function timer_startup()

{

       wait (3); // wait until the level is loaded

       while (current_time > 1) // this loop will run until the value of the timer reaches 1

       {

               current_time -= 1;

               wait (-1); // decrease the value of the counter every second

               timer_bar.z -= 1; // move the bar downwards every second, play with this value

       }

}

 

 

Q: I want my boat to pan / rotate when turning but only move to that new angle after a slight delay, creating a sliding effect like you would see when a car attempts to turn too fast or on a slippery surface.

A: Here's a snippet that should get you started.

 

action my_boat() // use the up, left and right arrow keys to control the boat

{

       my.skill1 = 0;

       while (1)

       {

               if (key_cuu)

               {

                       if (my.skill1 < 2)

                       {

                               my.skill1 += 0.2 * time_step;

                       }

               }

               else

               {

                       if (my.skill1 > 0)

                       {

                               my.skill1 -= 0.03 * time_step;

                       }

               }

               if (key_cul)

               {                                

                       my.pan += 4 * time_step;

               }

               if (key_cur)

               {

                       my.pan -= 4 * time_step;

               }

               clamp(my.skill1, 0, 2);

               c_move (my, my.skill1, nullvector, GLIDE);

               wait (1);

       }

}

 

 

Q: I'm trying to get a cool waving effect for my leaves

A: Take a look at this simple example.

 

action weaving_grass() // attach this action to your grass models

{

       var grass_angles;

       var grass_speed;

       set (my, PASSABLE);

       my.scale_x = 0.7 + random(2) / 3; // set different scales for the grass models

       my.scale_y = my.scale_x;

       my.scale_z = my.scale_x;

       grass_speed = 2 + random(5);

       while (1)

       {

               grass_angles += grass_speed * time_step; // allow the grass to weave

               my.roll += 0.02 * sin(grass_angles);

               wait (1);

       }

}

 

 

Q: I'm trying to make a gun fall to the floor without using physics. How can I do that?

A: You can't beat the physics engine when it comes to tasks such as this, but there you go.

 

var soldier_health = 100;

 

STRING* soldiergun_mdl = "solgun.mdl";

 

function attach_dummygun()

{

       proc_mode = PROC_LATE;

       set (my, PASSABLE);

       while(soldier_health > 0)

       {

               vec_set(my.x, you.x);

                 vec_set(my.pan, you.pan);

                 my.frame = you.frame;

                 wait(1);

       }

       wait (1);

       my.skill77 = 1;

       reset (my, PASSABLE);

       while (my.skill77) // move the weapon downwards until it can't move anymore

       {

               // using absolute world coordinates to move the gun downwards

               my.skill77 = c_move (my, nullvector, vector (0, 0, -3 * time_step), IGNORE_PASSABLE | GLIDE); // play with -3

               my.roll += 15 * time_step; // play with this value

               my.tilt += 3 * time_step; // play with this value

               wait (1);

       }

       my.tilt = 0; // restore the initial weapon angles

       my.roll = 0;

}

 

action soldier1()

{

       var anim_percentage;

       ent_create(soldiergun_mdl, nullvector, attach_dummygun); // give the soldier a gun

       while (soldier_health > 0)

       {

              ent_animate(my, "stand", anim_percentage, ANM_CYCLE);

              anim_percentage += 1 * time_step; // "1" controls the "stand" animation speed

               soldier_health -= 3 * time_step; // decrease soldier's health, make it die                

               wait (1);

       }

       set (my, PASSABLE); // the soldier is dead here, so its corpse can become passable

       anim_percentage = 0;

       while (anim_percentage < 77)

       {        

              ent_animate(my, "death", anim_percentage, ANM_CYCLE);

              anim_percentage += 4 * time_step; // "4" controls the "death" animation speed

               wait (1);

       }

}

 

 

Q: I want the camera to rotate as soon as the level is loaded, giving an overview of the level; after that it has to come back to the normal view, so that the player can move.

A: Use this piece of code.

 

var camera_loop = 0;

 

STRING* test_wmb = "test.wmb";

 

void main()

{

       video_mode = 7;

       video_depth = 32;

       video_screen = 1;

       level_load (test_wmb);

       wait (3); // wait until the level is loaded

       vec_set (camera.x, vector(-300, 200, 250)); // this will be the center of the rotation, play with the values

       camera.pan = 35; // these will be the initial camera angles, set your own values here

       camera.tilt = -20;

       wait (-2); // maybe you want to wait a bit before starting the rotation

       while (camera.pan < 395) // the camera will perform a full rotation before stopping (35 + 360 = 395, right?)

       {

               camera.pan += 2 * time_step; // 2 = rotation speed

               wait (1);

       }

       wait (-1); // maybe you want to wait a bit before giving control to the player

       camera_loop = 1; // the camera has performed its loop, so let's give the control to the player

}

 

action players_code() // simple player and 1st person camera code

{

       while (!camera_loop) {wait (1);} // add this line of code at the beginning of your own player code

       player = my;

       camera.pan = player.pan; // set the camera to player's angles at the very beginning

       camera.tilt = player.tilt;

       set (my, INVISIBLE);

       while (1)

       {

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x);

               camera.z += 30;

               camera.pan -= 5 * mouse_force.x * time_step;

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

               player.pan = camera.pan;

               wait (1);

       }

}