Questions from the forum

Top  Previous  Next

Q: How can I get a function to spawn particles in a circle around my character?

A: Here's an example.

 

BMAP px_tga = "px.tga";

 

function fade_p()

{

       my.alpha -= 10 * time_step;

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

}

 

function effect_x()

{

       my.alpha = 30 + random(65);

       my.flare = on;

       my.bmap = px_tga;

       my.size = 12;

       my.bright = on;

       my.move = on;

       my.function = fade_p;

}

 

function create_px()

{

       var temp_pos;

       var temp_var;

       while (1)

       {

               temp_var += 35 * time_step; // 35 = particle rotation speed

               vec_set (temp_pos.x, my.x);

               temp_pos.x += 20 * cos(temp_var); // 20 = particle radius

               temp_pos.y += 20 * sin(temp_var); // use the same value here

               temp_pos.z += 10; // play with 10

               effect(effect_x, 1, temp_pos.x, nullvector);

               wait (1);

       }

}

 

action players_code() // simple player code

{

       create_px();

       player = my; // I'm the player

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

               wait (1);

       }

}

 

aum66_questions1

 

 

Q: How can I fade out a sound that is played by snd_loop?

A: Use this example as a base for your code.

 

var loop_handle;

var loop_volume = 100;

 

sound atmosphere_wav = "atmosphere.wav";

 

function loop_startup()

{

       loop_handle = snd_loop(atmosphere_wav, 80, 0);

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

       while (loop_volume > 1)

       {

               snd_tune(loop_handle, loop_volume, 0, 0);

               loop_volume -= 0.5 * time_step; // 0.5 = fading speed

               wait (1);

       }

       snd_stop (loop_handle);

}

 

 

Q: I need a 3D "button" which gets colored to red when it is clicked and returns to its normal color after the second click.

A: Use this piece of code.

 

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

       }

}

 

var clicked_times = 0;

 

function light_me_up()

{

       clicked_times += 1;

       my.lightred = 255 * (clicked_times % 2);

}

 

action button_3d

{

       my.light = on;

       my.enable_click = on;

       my.event = light_me_up;

}

 

 

Q: I have created some pcx panels which use the overlay flag. When I run it the project, my panels still have some residual black spots around them. Has anyone found a fix to this?

A: You have to turn your pcx files into tga bitmaps. Here's a quick example that uses Paint Shop Pro

 

- Open your pcx file, and then use the magic wand to select the black areas of the panel that aren't useful.

 

aum66_questions2

 

- Invert the selection.

 

aum66_questions3

 

- Contract the selection by 1 or more pixels, as needed (Selections -> Modify -> Contract in Paint Shop Pro)

 

aum66_questions4

 

- Save the resulting selection to the alpha channel (Selections -> Save to alpha channel in Paint Shop Pro)

That's all! Save the bitmap as a tga file and you'll be able to use your panel without seeing any of the black edges.

 

 

Q: How can I change the X position of a model using the keyboard?

A: Attach this action to your player.

 

action players_code() // simple player and camera code

{

       var anim_percentage;

       player = my; // I'm the player

       camera.pan = 90;

       while (1)

       {

               // move the player using the left and right arrow keys

               c_move (my, vector(10 * (key_cur - key_cul) * time_step, 0, 0), nullvector, glide); // 10 = speed

               if (key_cur || key_cul) // 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

               }

               vec_set (camera.x, player.x);

               camera.y -= 300; // place the camera 300 quants behind the player (play with this value)

               camera.z += 40; // place the camera 40 quants above the player on the z axis (play with this value)

               wait (1);

       }

}

 

 

Q: I have an entity that should display a new string above its head every 3 seconds, reading it from a text file. Can anyone help?

A: Use the example below; it displays all the lines inside the talk.txt file for as long as the entity is visible on the screen.

 

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

var string_handle;

 

STRING talker_string = "                                        "; // the string can store up to 40 characters

 

TEXT talker_txt =

{

       pos_x = 300;

       pos_y = 200;

       string (talker_string);

       flags = VISIBLE;

}

 

action talking_entity()

{

       var text_position;

       var temp_pos;

       var n = 0;

       string_handle = file_open_read("talk.txt"); // put your lines of text inside this file

       while (1)

       {

               vec_set (text_position, my.x);

               text_position.z += 40; // play with this value

               vec_set (temp_pos.x, my.x);

               if (vec_to_screen(temp_pos.x, camera)) // if the entity is visible on the screen

               {

                       talker_txt.visible = ON;

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

                       {

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

                               n += 1; // move on to the following string

                               sleep (3); // read a new string from the file every 3 seconds

                       }

                       else

                       {

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

                       }

               }

               else // the entity isn't visible on the screen?

               {

                       talker_txt.visible = OFF;

               }

               wait (1);

       }                

}

 

 

Q: My model includes an animation named "dance". How can I call this animation when the player hits something, then restore it to "walk" when the "dance" frames end?

A: Here's an example that takes care of the dancing, walking and standing.

 

var dancing = 0;

 

function do_the_dance()

{

       var dance_percentage = 0;

       dancing = 1;

       while (dance_percentage < 100)

       {

               ent_animate(my, "dance", dance_percentage, anm_cycle);

               dance_percentage += 2 * time_step; // "2" controls the "dance" animation speed

               wait (1);

       }

       dancing = 0;

}

 

action players_code()

{

       var anim_percentage;

       player = my; // I'm the player

       camera.pan = 90;

       my.enable_impact = on;

       my.enable_entity = on;

       my.enable_block = on;

       my.event = do_the_dance;

       while (1)

       {

               if (dancing == 0)

               {

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

                       if (key_w || key_s || key_a || key_d)

                       {

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

       }

}

 

 

Q: I want to display a question on the screen, and then to accept the answer and compare it with the predefined answer in the code. If it is correct, then the code should display the next question and accept the answer, and so on.

A: There you go.

 

STRING answer1_str = "                              "; // stores up to 30 characters

STRING answer2_str = "                              "; // stores up to 30 characters

 

TEXT question1_txt =

{

       layer = 15;

       pos_x = 250;

       pos_y = 50;

       string ("2 + 2 = ?");

}

 

TEXT answer1_txt =

{

       layer = 15;

       pos_x = 330;

       pos_y = 50;

       string (answer1_str);

}

 

TEXT question2_txt =

{

       layer = 15;

       pos_x = 250;

       pos_y = 50;

       string ("3 + 3 = ?");

}

 

TEXT answer2_txt =

{

       layer = 15;

       pos_x = 330;

       pos_y = 50;

       string (answer2_str);

}

 

function answers_startup()

{

       sleep (2);

       question1_txt.visible = ON;

       while (1)

       {

               str_cpy(answer1_str, ""); // reset the string

               answer1_txt.visible = ON;

               inkey(answer1_str);

               if (str_cmpi(answer1_str, "4"))

               {

                       str_cpy(answer1_str, "Good job!");

                       sleep (2);

                       question1_txt.visible = OFF;

                       answer1_txt.visible = OFF;

                       break;  // Got the right answer? The move on to the following question!

               }

               else

               {

                       str_cpy(answer1_str, "Wrong! Please try again!");

                       sleep (3);

               }

               wait (1);

       }

       question2_txt.visible = ON;

       while (1)

       {

               str_cpy(answer2_str, ""); // reset the string

               answer2_txt.visible = ON;

               inkey(answer2_str);

               if (str_cmpi(answer2_str, "6"))

               {

                       str_cpy(answer2_str, "Good job!");

                       sleep (2);

                       question1_txt.visible = OFF;

                       answer1_txt.visible = OFF;

                       break;  // Got the right answer? The move on to the following question!

               }

               else

               {

                       str_cpy(answer2_str, "Wrong! Please try again!");

                       sleep (3);

               }

               wait (1);

       }

       // your 3rd question would go here, etc

       sys_exit(NULL); // shut down the engine

}

 

 

Q: I'd like to have a turret who can detect friends and foes. If a friendly entity comes near the turret, the turret should just follow it. On the other hand, if the player approaches, the turret should rotate towards it and fire at it.

A: Use this snippet.

 

SOUND destroyed_wav = "destroyed.wav";

 

STRING explo13_pcx = "explo+13.pcx";

STRING rocket_mdl = "rocket.mdl";

 

action my_player()

{

       my.enable_scan = ON;

       player = my; // I'm the player

       ............... // the rest of your player code would go here

}

 

function explode_rocket()

{

       var anim_speed;

       anim_speed = 0.7 + random(1.3);

       my.light = on;

       my.lightrange = 0;

       my.red = 55 + random(200);

       my.green = random(255);

       my.blue = 0;

       my.nofog = on;

       my.oriented = on;

       my.flare = on;

       my.bright = on;

       my.ambient = random(100);

       my.passable = on;

       my.roll = random(360); // pick a random orientation

       my.skill30 = you.skill10; // store skill10 quickly because "you" will be removed soon

       while (my.frame < 14)

       {

               if (my.scale_x < my.skill30) // grow until you reach the value that was stored or set in skill10

               {

                       my.scale_x += 5 * time_step;

                       my.scale_y = my.scale_x;

               }

               my.frame += anim_speed * time;

 

               vec_set (temp.x, camera.x);

               vec_sub (temp.x, my.x);

               vec_to_angle (my.pan, temp); // turn towards the player to make sure that the explo looks great

 

               wait (1);

       }

       ent_remove (me);

}

 

function remove_rocket()

{

       my.passable = ON;

       wait (1);

       my.event = NULL;

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

       ent_create (explo13_pcx, my.pos, explode_rocket);

       my.invisible = on; // hide the rocket, keep ent_playsound playing

       sleep (2); // for 2 more seconds

       ent_remove(me); // now remove it

}

 

function move_rocket()

{

       my.pan = you.pan;

       my.tilt = you.tilt;

       wait (1);

       var rocket_speed;

       var tempo_pos;

       my.enable_entity = on;

       my.enable_impact = on;

       my.enable_block = on;

       my.event = remove_rocket;

       my.skill40 = 1234; // I'm a rocket

       my.skill20 = 0;

       my.skill10 = 3; // default explosion scale for the rocket

       while (my.skill20 < 5000)

       {

               my.roll += 50 * time_step;

               rocket_speed.x = 200 * time_step;

               rocket_speed.y = 0;

               rocket_speed.z = 0;

               my.skill20 += 1 * time_step;

               c_move (my, rocket_speed, nullvector, IGNORE_PASSABLE);

               wait (1);

       }

       remove_rocket();

}

 

action turret()

{

       var bullet_offset;

       var temp_turret;

       while (1)

       {

               c_scan(my.x, my.pan, vector(360, 180, 2000), IGNORE_ME | SCAN_ENTS);

               if (you) // an entity was detected by c_scan?

               {

                       vec_set (temp_turret.x, you.x);

                       vec_sub (temp_turret.x, my.x);

                       vec_to_angle (my.pan, temp_turret); // then rotate the turret towards the entity that was detected

               }

               if (you == player) // detected the player?

               {

                       if (vec_dist (my.x, player.x) < 700) // the turret starts to fire if the player comes closer than 700 quants

                       {

                               bullet_offset.x = 100;

                               bullet_offset.y = 0;

                               bullet_offset.z = 0;

                               vec_rotate (bullet_offset, my.pan);

                               vec_add (bullet_offset.x, my.x);

                               ent_create (rocket_mdl, bullet_offset.x, move_rocket);

                               sleep (2); // fires a bullet every 2 seconds

                       }

               }

               wait (1);

       }

}

 

Q: I want to fill a test-tube with a given liquid. During runtime the test-tube has to be filled using mouse press or using arrows on the keyboard.

A: Use several "window" definitions and this piece of code as an example.

 

var red_substance = 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 subtract_red()

{

       while (mouse_left)

       {

               red_substance -= 25 * time_step;

               wait (1);

       }

}

 

function add_red()

{

       while (mouse_left)

       {

               red_substance += 25 * time_step;

               wait (1);

       }

}

 

PANEL red_pan =

{

       bmap = "red.pcx";

       window (7, 4, 81, 477, "fluidred.pcx", 0, red_substance);

       button (25, 480, "addh.pcx", "addl.pcx", "addh.pcx", add_red, NULL, NULL);

       button (60, 480, "subh.pcx", "subl.pcx", "subh.pcx", subtract_red, NULL, NULL);

       flags = VISIBLE;

}