Questions from the forum

Top  Previous  Next

Q: I am trying to build a rocket that increases its speed until it reaches a certain value. Then, it should stop doing that and continue to fly at its current speed.

A: Here's a good example: a weapon that tracks the speed using the distance covered during the last frame (a value returned by c_move).

 

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

var distance_covered; // global variable, so that we can display it using a digit on a panel

var got_weapon1 = 0;

 

ENTITY* weapon1;

 

STRING* bullet_mdl = "bullet.mdl";

 

SOUND* bullet_wav = "bullet.wav";

 

function fire_bullets();

function move_bullets();

function remove_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

       got_weapon1 = 1;

       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

{

       if (!got_weapon1) return; // didn't get the weapon? Then don't allow the player to fire bullets!

       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 = remove_bullets; // when it collides with something, its event function (remove_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 = 2 * time_step; // set the initial 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")

       {

               if (distance_covered < 100 * time_step) // increase bullet's speed until it reaches 100 * time_step;

                       bullet_speed.x += 3 * time_step; // 3 gives the speed growth / frame

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

               distance_covered = c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE);

               wait (1);

       }

}

 

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

{

       wait (1); // wait a frame to be sure (don't trigger engine warnings)

       ent_remove (my); // and then remove the bullet

}

 

PANEL* distance_pan =

{

       layer = 15;

       digits(600, 20, 4.3 ,* , 1, distance_covered);

       flags = SHOW;

}

 

 

Q: Could you please fix "Booker" from Aum72? It doesn't work fine with A8; I get an empty pointer error and the books' info isn't saved to the disk.

A: Try it again with the latest A8 version - I just did that and it works fine now. The data can't be saved to the disk under Windows Vista and Windows 7 if you don't have the proper rights. Run secpol.msc at the command prompt to bring on the "Local Security Policy" window and set the needed permissions.

 

 

Q: Can you show me how I can create a mini map of a level? I'd like to have a circular view that shows the player in the center of the mini map. When an NPC comes into view the NPC shows up on the mini map as well.

A: There you go.

 

VIEW* minimap_view;

 

ENTITY* minimap_model =

{

       x = 100; // tweak these values until you set the desired position and size of the minimap view

       y = -40;

       z = 20;

       tilt = -90;

       type = "teler.mdl"; // use your own model here

       layer = 20;

       flags2 = SHOW; // show the model

}

 

function minimap_startup()

{

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

       minimap_view = view_create(10); // set the layer value for the view to 10

       wait (2);

       set (minimap_view, SHOW);

       // the view will have 256x256 pixels; increase these values and the skin of the minimap model if you need a higher resolution

       minimap_view.size_x = 256;

       minimap_view.size_y = 256;

       minimap_view.bmap = bmap_for_entity(minimap_model, 0);

       minimap_view.arc = 90; // play with this value

       vec_set(minimap_view.pan, vector(0, -90, 0)); // make the minimap view point downwards (tilt = -90)

       while (1)

       {

               // set the position of the minimap 300 quants above the player - use a bigger value here if you'd like to see a bigger area around the player

               vec_set(minimap_view.x, vector(player.x, player.y, player.z + 300));

               wait (1);

       }

}

 

aum95_questions1

 

 

Q: I'd like to have an enemy with a sword that damages the player when the sword gets in contact with player's body.

A: Check out my "Kung Fu Master" plug and play snippet from Aum93; the enemies damage the player by tracing from two vertices of their bodies, legs, etc. Simply replace those vertices with the base / tips vertices of the enemy sword and you'll be set.

 

 

Q: I'd like to have two panels that stay in the left / right upper corners of the screen regardless of the video resolution.

A: Here's a simple, and yet fully working example.

 

BMAP* left_pcx = "left.pcx";

BMAP* right_pcx = "right.pcx";

 

PANEL* left_pan =

{

       bmap = left_pcx;

       layer = 15;

       pos_x = 0;

       pos_y = 0;

       flags = SHOW;

}

 

PANEL* right_pan =

{

       bmap = right_pcx;

       layer = 15;

       flags = SHOW;

}

 

function panels_startup()

{

       while (1)

       {

               right_pan.pos_x = screen_size.x - bmap_width(right_pcx);

               wait (1);

       }

}

 

 

Q: How do I make the player collide with the walls and not pass through them? I'm not sure where to start.

A: You can move objects either by changing their coordinates directly, as in "player.x += 1;" or by using the proper way - the "c_move" instruction. Here's a simple example that can be attached to your player model.

 

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

{        

       var movement_speed = 20;

       VECTOR temp;

       set (my, INVISIBLE);

       player = my;

       while (1)

       {

               // simple player movement code with gravity - use WSAD to move the player and the mouse to look around / rotate

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

 

               // bonus - simple camera code! ;)

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

       }

}

 

 

Q: How can I attach a weapon to one of my soldiers?

A: Animate the weapon together with the player, and then save them as separate models. If you have named your animated weapon "solgun.mdl", all you need to do is to attach the action below to your soldier model.

 

STRING* soldiergun_mdl = "solgun.mdl";

 

function attach_weapon()

{

       proc_mode = PROC_LATE;

       set (my, PASSABLE);

       while(you)

       {

               vec_set(my.x, you.x);

               vec_set(my.pan, you.pan);

               my.frame = you.frame;

               my.next_frame = you.next_frame;

               wait(1);

       }

       ent_remove(my);

}

 

action my_soldier()

{

       var anim_percentage;

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

       while (1)

       {

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

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

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

               my.pan += 2 * time_step; // "2" controls the rotation speed

               wait (1);

       }

}

 

aum95_questions2

 

 

Q: I want to have my player leaving a trail behind everywhere he changes direction. How can I accomplish this using the particle system?

A: Here's a fully functional example that generates dust particles 30 quants below the origin of player's model whenever it rotates.

 

BMAP* dust_tga = "dust.tga";

 

function fade_dust(PARTICLE *p)

{

       p.alpha -= 2 * time_step; // dust fading speed = 2

       if (p.alpha < 0) {p.lifespan = 0;}

}

 

function dust_particle(PARTICLE *p)

{

       p->vel_x = 0; // slightly random

       p->vel_y = 0; // horizontal speed

       p->vel_z = random(1); // small vertical speed

       p.alpha = 70; // initial transparency, play with this value

       p.bmap = dust_tga;

       p.size = 10;

       p.flags |= (BRIGHT | MOVE);

       p.event = fade_dust;

}

 

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

{        

       var movement_speed = 4;

       var anim_percentage;

       VECTOR temp;

       player = my;

       while (1)

       {

               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_cuu - key_cud) * time_step;

               my.pan -= movement_speed * (key_cur - key_cul) * 0.3 * time_step;

               temp.y = 0;

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

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 500;

               camera.pan = my.pan;

               camera.tilt = -90;

               if (key_cuu + key_cud) // one of the movement keys is being pressed?

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

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

               if (key_cul + key_cur) // one of the rotation keys is being pressed?

                       effect (dust_particle, 3, vector(my.x, my.y, my.z - 30), normal); // generate dust particles 30 quants below the origin of the model

               wait (1);

       }

}

 

aum95_questions3

 

 

Q: I need to know how to open a door if the player has got the security card.

A: There you go.

 

var got_card = 0;

 

SOUND* gotcard_wav = "gotcard.wav";

 

action my_card() // attach this action to your card model

{

       set (my, PASSABLE);

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

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

       {

               my.pan += 4 * time_step; // rotate the card around its pan angle until the player gets it

               wait (1);

       }

       snd_play(gotcard_wav, 60, 0);

       set (my, INVISIBLE); // the player has picked up the card, so hide it

       got_card = 1;

}

 

action my_door() // attach this action to your door entity

{

       VECTOR door_coords;

       vec_set (door_coords.x, my.x); // store the initial door position

       while (!got_card) {wait (1);} // wait until the player picks up the card

       while (vec_dist (player.x, my.x) > 150) {wait (1);} // wait until the player comes closer than 150 quants to the door

       while (my.x < door_coords.x + 80) // 80 gives the sideway movement (door offset) - play with this value

       {

               my.x += 3 * time_step; // 3 gives the door sliding speed - play with it

               wait (1);

       }

}

 

 

Q: Please help me make a panel fade in and out. I have a main menu and buttons; when I press a certain button, I'd like the main menu to fade out and another panel to fade in.

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

 

var main_alpha = 100; // stores the transparency value for the "main" panel

var options_alpha = 0; // stores the transparency value for the "options" panel

 

BMAP* pointer_tga = "pointer.tga";

 

function new_game();

function exit_game();

 

PANEL* main_pan =

{

       layer = 10;

       bmap = "main.jpg";

       pos_x = 0;    

       pos_y = 0;   

       button (250, 100, "newgame2.pcx", "newgame1.pcx", "newgame2.pcx", new_game, NULL, NULL);

       button (250, 150, "exit2.pcx", "exit1.pcx", "exit2.pcx", exit_game, NULL, NULL);

       alpha = 100;

       flags = SHOW;

}

 

PANEL* options_pan =

{

       layer = 15;

       bmap = "options.pcx";

       pos_x = 0;

       pos_y = 0;

       alpha = 0;

       flags = TRANSLUCENT;

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function new_game()

{

       main_pan.flags |= TRANSLUCENT; // the player has clicked the "options" button, so let's make the main panel transparent

       options_pan.flags |= SHOW;        // show the options panel

       while (main_alpha > 5) // decrease main panel's alpha value, making it less and less visible

       {

               main_alpha -= 4 * time_step; // 4 gives main pan's fade out fading speed

               main_pan.alpha = main_alpha;

               options_alpha += 4 * time_step; // 4 gives option pan's fade in speed

               options_pan.alpha = options_alpha;

               wait (1);

       }

       main_pan.flags &= ~SHOW; // options_pan is visible, so let's hide the main panel

       options_pan.alpha = 100; // and then let's make options_pan fully visible by setting its alpha value to 100

}

 

function exit_game()

{

       sys_exit(NULL);        

}