Questions from the forum

Top  Previous  Next

Q: How can I make a simple AI which triggers an event when it is near a specific model or the player?

A: Here's a quick example.

 

// make sure that player's action includes the "player = my;" line of code

// set skill1 to 1234 for all the entities that should be detected (besides the player)

action enemy_detector()

{

       while (1)

       {

               // scan for any entities that are closer than 200 quants to this entity

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

               if (you) // a target was detected?

               {

                       if ((you == player) || (you.skill1 == 1234))

                       {

                               // an entity that verifies the conditions was detected, so do what you want here        

                               my.scale_z = 3; // I'll just make this entity 3 times taller while it has detected something

                       }

               }

               else // didn't detect any entity here, so let's restore the initial scale

               {

                       my.scale_z = 1;        

               }

               wait (1);

       }

}

 

 

Q: I am trying to create a virtual dice. I got 6 pictures resembling the numbers of the dice; how can I show them in a random way for 5 seconds, and then stop at one picture?

A: There you go.

 

var dice_rolling = 0;

var rolling_time = 0;

var random_value;

 

PANEL* one_pan =

{

       bmap = "01.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

PANEL* two_pan =

{

       bmap = "02.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

PANEL* three_pan =

{

       bmap = "03.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

PANEL* four_pan =

{

       bmap = "04.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

PANEL* five_pan =

{

       bmap = "05.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

PANEL* six_pan =

{

       bmap = "06.tga";

       layer = 15;

       pos_x = 300;

       pos_y = 200;

}

 

function roll_dice()

{

       if (dice_rolling) return; // don't allow the dice to roll again before ending the current roll

       dice_rolling = 1;

       rolling_time = 0;

       while (rolling_time < 5) // this loop runs for 5 seconds

       {

               rolling_time += time_step / 1.6; // add a value of 1 to rolling_time each second

               random_value = integer(random(6)) + 1; // generate an integer number that ranges from 1 to 6

               if (random_value == 1)

               {

                       set(one_pan, SHOW); // display the 01.tga bitmap

                       reset(two_pan, SHOW); // hide the other bitmaps

                       reset(three_pan, SHOW); // hide the other bitmaps

                       reset(four_pan, SHOW); // hide the other bitmaps

                       reset(five_pan, SHOW); // hide the other bitmaps

                       reset(six_pan, SHOW); // hide the other bitmaps

               }

               if (random_value == 2)

               {

                       set(two_pan, SHOW); // display the 01.tga bitmap

                       reset(one_pan, SHOW); // hide the other bitmaps

                       reset(three_pan, SHOW); // hide the other bitmaps

                       reset(four_pan, SHOW); // hide the other bitmaps

                       reset(five_pan, SHOW); // hide the other bitmaps

                       reset(six_pan, SHOW); // hide the other bitmaps

               }

               if (random_value == 3)

               {

                       set(three_pan, SHOW); // display the 01.tga bitmap

                       reset(two_pan, SHOW); // hide the other bitmaps

                       reset(one_pan, SHOW); // hide the other bitmaps

                       reset(four_pan, SHOW); // hide the other bitmaps

                       reset(five_pan, SHOW); // hide the other bitmaps

                       reset(six_pan, SHOW); // hide the other bitmaps

               }

               if (random_value == 4)

               {

                       set(four_pan, SHOW); // display the 01.tga bitmap

                       reset(two_pan, SHOW); // hide the other bitmaps

                       reset(three_pan, SHOW); // hide the other bitmaps

                       reset(one_pan, SHOW); // hide the other bitmaps

                       reset(five_pan, SHOW); // hide the other bitmaps

                       reset(six_pan, SHOW); // hide the other bitmaps

               }

               if (random_value == 5)

               {

                       set(five_pan, SHOW); // display the 01.tga bitmap

                       reset(two_pan, SHOW); // hide the other bitmaps

                       reset(three_pan, SHOW); // hide the other bitmaps

                       reset(four_pan, SHOW); // hide the other bitmaps

                       reset(one_pan, SHOW); // hide the other bitmaps

                       reset(six_pan, SHOW); // hide the other bitmaps

               }

               if (random_value == 6)

               {

                       set(six_pan, SHOW); // display the 01.tga bitmap

                       reset(two_pan, SHOW); // hide the other bitmaps

                       reset(three_pan, SHOW); // hide the other bitmaps

                       reset(four_pan, SHOW); // hide the other bitmaps

                       reset(five_pan, SHOW); // hide the other bitmaps

                       reset(one_pan, SHOW); // hide the other bitmaps

               }

               wait (10); // generate 6 random numbers per second (this loop running at 60 frames per second, see below)

       }

       // the dice have rolled for 5 seconds here; the loop has stopped

       dice_rolling = 0; // the dice can be rolled again

}

 

function dice_startup()

{

       fps_max = 60; // limit the frame rate to 60

       random_seed(0); // generate random number sequences each time

       on_d = roll_dice; // press the "D" key to roll the dice

}

 

 

Q: How do I randomize questions in Gamestudio? I've got 5 different questions and want them to be randomly displayed when a button is clicked.

A: Here's an example.

 

BMAP* generate1_pcx = "generate1.pcx";

BMAP* generate2_pcx = "generate2.pcx";

BMAP* pointer_tga = "pointer.tga";

 

function generate_questions();

 

TEXT* question1_txt =

{

       layer = 20;

       pos_x = 200;

       pos_y = 20;

       string("Is this the 1st question?");

}

 

TEXT* question2_txt =

{

       layer = 20;

       pos_x = 200;

       pos_y = 20;

       string("Is this the 2nd question?");

}

 

TEXT* question3_txt =

{

       layer = 20;

       pos_x = 200;

       pos_y = 20;

       string("Is this the 3rd question?");

}

 

TEXT* question4_txt =

{

       layer = 20;

       pos_x = 200;

       pos_y = 20;

       string("Is this the 4th question?");

}

 

TEXT* question5_txt =

{

       layer = 20;

       pos_x = 200;

       pos_y = 20;

       string("Is this the 5th question?");

}

 

PANEL* questions_pan =

{

       bmap = "mainpanel.pcx";        

       layer = 15;

       button(40, 10, generate2_pcx, generate1_pcx, generate2_pcx, generate_questions, NULL, NULL);

       flags = SHOW;

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function generate_questions()

{

       var random_value;

       random_value = integer(random(5)) + 1; // generate an integer number that ranges from 1 to 5

       if (random_value == 1)

       {

               set(question1_txt, SHOW); // display the first question

               reset(question2_txt, SHOW); // hide the other questions

               reset(question3_txt, SHOW); // hide the other questions

               reset(question4_txt, SHOW); // hide the other questions

               reset(question5_txt, SHOW); // hide the other questions

       }

       if (random_value == 2)

       {

               set(question2_txt, SHOW); // display the 2nd question

               reset(question1_txt, SHOW); // hide the other questions

               reset(question3_txt, SHOW); // hide the other questions

               reset(question4_txt, SHOW); // hide the other questions

               reset(question5_txt, SHOW); // hide the other questions

       }

       if (random_value == 3)

       {

               set(question3_txt, SHOW); // display the 3rd question

               reset(question1_txt, SHOW); // hide the other questions

               reset(question2_txt, SHOW); // hide the other questions

               reset(question4_txt, SHOW); // hide the other questions

               reset(question5_txt, SHOW); // hide the other questions

       }

       if (random_value == 4)

       {

               set(question4_txt, SHOW); // display the 4th question

               reset(question1_txt, SHOW); // hide the other questions

               reset(question2_txt, SHOW); // hide the other questions

               reset(question3_txt, SHOW); // hide the other questions

               reset(question5_txt, SHOW); // hide the other questions

       }

       if (random_value == 5)

       {

               set(question5_txt, SHOW); // display the 5th question

               reset(question1_txt, SHOW); // hide the other questions

               reset(question2_txt, SHOW); // hide the other questions

               reset(question3_txt, SHOW); // hide the other questions

               reset(question4_txt, SHOW); // hide the other questions

       }

}

 

 

Q: Can anyone tell me how I cant prevent the camera to show the inside of my model, when i use a gun in the view like a FPS?

 

ENTITY* actor_screen =

{

       type = "ak47.mdl";

       layer = 1;

       flags2 = SHOW;

       x = 30;

       y = -3;

       z = -5;

}

 

A: The camera penetrates the gun model, so change its position using the xyz values a bit until it moves outside the model.

 

 

Q: How do I set health/hitpoints for enemies? Let's say there are 3 types of enemies in my map; I want all zombies to have 75 health, all mutants to have 100 health and all terrorists to have 125 health.

A: Here's a modified version of the enemy code I've posted in Aum88's faq; simply set skill1 in Wed for each enemy to the desired health points value.

 

STRING* bullet_mdl = "bullet.mdl";

 

function fire_bullets(); // creates the bullets

function remove_bullets(); // removes the bullets after they've hit something

function got_shot();

function move_bullets();

function move_enemy_bullets();

 

#define idle 1

#define attacking 2

#define dead 3

#define status skill10

#define health skill80

 

function fire_bullets()

{

       proc_kill(4); // don't allow more than 1 instance of this function to run

       while (mouse_left) {wait (1);} // wait until the player releases the mouse button

       ent_create (bullet_mdl, camera.x, move_bullets); // create the bullet at camera's position and attach it the "move_bullets" function

}

 

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

}

 

action my_enemy() // attach this action to your enemies

{

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

       var idle_percentage = 0;

       var run_percentage = 0;

       var death_percentage = 0;

       VECTOR content_right; // tracks the content in front of the player

       VECTOR content_left; // tracks the content in front of the player

       VECTOR temp;

       set (my, POLYGON); // use accurate collision detection

       if (my.skill1 == 0)

       {

                 my.health = 100; // set skill1 to the desired value (75, 100 or 125 points) or it will default to

       }

       else

       {

               my.health = my.skill1;          

       }        

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // the enemy is sensitive to impact with player's bullets

       my.event = got_shot; // and runs this function when it is hit

       my.status = idle; // that's the same thing with my.skill10 = 1; (really!)

       while (my.status != dead) // this loop will run for as long as my.skill10 isn't equal to 3

       {

                 if (my.status == idle) // hanging around?

            {

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

                       idle_percentage += 3 * time_step; // "3" controls the animation speed

                       if (vec_dist (player.x, my.x) < 1000) // the player has come too close?

                       {

                               // scanned in the direction of the pan angle and detected the player?

                               if ((c_scan(my.x, my.pan, vector(120, 60, 1000), IGNORE_ME) > 0) && (you == player))

                               {

                                       my.status = attacking; // then attack the player even if it hasn't fired at the enemy yet

                               }

                       }

               }

               if (my.status == attacking) // shooting at the player?

               {

                    // the road is clear? then rotate the enemy towards the player

                       if (c_content (content_right.x, 0) + c_content (content_left.x, 0) == 2)

                       {

                               vec_set(temp, player.x);

                               vec_sub(temp,my.x);

                               vec_to_angle(my.pan, temp); // turn the enemy towards the player

                       }

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

                       {

                               vec_set(content_right, vector(50, -20, -15));

                               vec_rotate(content_right, my.pan);

                               vec_add(content_right.x, my.x);

                               if (c_content (content_right.x, 0) != 1) // this area isn't clear?

                               {

                                       my.pan += 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle

                               }

                               vec_set(content_left, vector(50, 20, -15));

                               vec_rotate(content_left, my.pan);

                               vec_add(content_left.x, my.x);

                               if (c_content (content_left.x, 0) != 1) // this area isn't clear?

                               {

                                       my.pan -= 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle

                               }

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

                               ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation

                               run_percentage += 6 * time_step; // "6" controls the animation speed

                       }

                       else

                       {

                               ent_animate(my, "alert", 100, NULL); // use the last frame from the "alert" animation here

                       }

                       if ((total_frames % 80) == 1) // fire a bullet each second

                       {

                               vec_for_vertex (temp, my, 8);

                               // create the bullet at enemy's position and attach it the "move_enemy_bullets" function

                               ent_create (bullet_mdl, temp, move_enemy_bullets);

                       }

                       if (vec_dist (player.x, my.x) > 1500) // the player has moved far away from the enemy?

                       {

                               my.status = idle; // then switch to "idle"

                       }

               }

               wait (1);

       }

       while (death_percentage < 100) // the loop runs until the "death" animation percentage reaches 100%       

       {

                 ent_animate(my, "deatha", death_percentage, NULL); // play the "die" animation only once

            death_percentage += 3 * time_step; // "3" controls the animation speed

            wait (1);

       }

       set (my, PASSABLE); // allow the player to pass through the corpse now

}

 

function got_shot()

{

       if (you.skill30 != 1) {return;} // didn't collide with a bullet? Then nothing should happen

       my.health -= 35;

       if (my.health <= 0) // dead?

       {

               my.status = dead; // stop the loop from "action my_enemy"

               my.event = NULL; // the enemy is dead, so it should stop reacting to other bullets from now on

               return; // end this function here

       }

       else // got shot but not (yet) dead?

       {

               my.status = attacking; // same thing with my.skill10 = 2

       }

}

 

function move_enemy_bullets()

{

       VECTOR bullet_speed; // this var will store the speed of the bullet

       my.skill30 = 1; // I'm a bullet

       // the bullet is sensitive to impact with other entities and to impact with level blocks

       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 = you.pan; // the bullet has the same pan

       my.tilt = you.tilt; // and tilt with the enemy

       bullet_speed.x = 50 * time_step; // adjust the speed of the bullet here

       bullet_speed.y = 0; // the bullet doesn't move sideways

       bullet_speed.z = 0; // or up / down on the z axis

       // the loop will run for as long as the bullet exists (it isn't "null")

       while (my)

       {

                 // move the bullet ignoring its creator (the enemy)

             c_move (my, bullet_speed, nullvector, IGNORE_YOU);

            wait (1);

       }

}

 

 

Q: I can not figure out how to stick an object to the camera so that it stays in front of a camera wherever I go.

A: You can either use an ENTITY definition (there's an example above) or, if you need an entity that must be actually present in the 3D world, a snippet like this.

 

function stick_to_camera()

{

       while (1)

       {

               // place the pot model 170 quants in front of the camera, 20 quants sideways and 25 quants below the origin on the z axis

               vec_set (my.x, vector(170, 20, -25)); // play with these values

               vec_rotate (my.x, camera.pan);

               vec_add (my.x, camera.x);

               my.pan = camera.pan;

               my.tilt = camera.tilt;

               wait (1);

       }

}

 

function object_startup()

{

       // make sure to include a "player = my;" line of code inside your player action / function

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

       ent_create("pot1.mdl", nullvector, stick_to_camera);

}

 

aum98_faq1

 

 

Q: Does anyone have a snippet for an input box with "Cancel" and "OK" buttons?

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

 

BMAP* pointer_tga = "pointer.tga";

BMAP* ok1_pcx = "ok1.pcx";

BMAP* ok2_pcx = "ok2.pcx";

BMAP* cancel1_pcx = "cancel1.pcx";

BMAP* cancel2_pcx = "cancel2.pcx";

 

STRING* name_str = "Click to input your name";

 

function input_name();

function cancel_name();

 

TEXT* name_txt =

{

       pos_x = 300;

       pos_y = 50;

       layer = 20;

       string(name_str);

       flags = SHOW;

}

 

PANEL* input_pan =

{

       bmap = "hud.tga";

       pos_x = 280;

       pos_y = 40;

       layer = 10;

       button(40, 10, ok2_pcx, ok1_pcx, ok2_pcx, input_name, NULL, NULL);

       button(40, 50, cancel2_pcx, cancel1_pcx, cancel2_pcx, cancel_name, NULL, NULL);        

       flags = SHOW;

}

 

function input_name()

{

       while (mouse_left) {wait (1);} // wait until the player releases the mouse button

       str_cpy(name_str, "#50"); // reset the input string

       inkey(name_str); // let's input player's name

       reset (input_pan, SHOW); // and then let's hide the panel

}

 

function cancel_name()

{

       printf("Name input was cancelled. System shutting down!");

       sys_exit(NULL);        

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

             wait(1);

       }

}

 

 

Q: I need a function that removes bitmaps from the video memory. I need to display many panels in my level and I'd like to free the memory after using them.

A: Here's an example that uses bmap_purge to free the video memory after hiding a panel (press F11 to display the video memory usage, and then P to purge the bitmap and compare the video memory values).

 

BMAP* panel1_pcx = "panel1.pcx";

 

PANEL* gameover_pan =

{

       layer = 15;

       pos_x = 300;

       pos_y = 200;

       bmap = "panel1_pcx";

       flags = SHOW;

}

 

function purge_startup()

{

       while (!key_p) {wait (1);} // wait until the player presses the "P" key

       while (key_p) {wait (1);} // wait until the player releases the "P" key

       reset(gameover_pan, SHOW); // hide the panel

       bmap_purge(panel1_pcx);        // purge the bitmap used by the panel

}

 

 

Q: Would you have an idea on how to make a menu that changes its size automatically depending on the resolution of the resolution using scale_x, scale_y?

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

 

BMAP* main_tga = "main.tga"; // main menu bitmap

BMAP* pointer_tga = "pointer.tga";

BMAP* ok1_pcx = "ok1.pcx";

BMAP* ok2_pcx = "ok2.pcx";

BMAP* cancel1_pcx = "cancel1.pcx";

BMAP* cancel2_pcx = "cancel2.pcx";

 

function start_game();

function exit_game();

 

PANEL* main_pan =

{

       bmap = main_tga;

  layer = 15;

       button(40, 10, ok2_pcx, ok1_pcx, ok2_pcx, start_game, NULL, NULL);

       button(40, 50, cancel2_pcx, cancel1_pcx, cancel2_pcx, exit_game, NULL, NULL);        

  flags = SHOW;

}

 

// makes the main menu panel fill the entire screen, regardless of the screen size and / or the bitmap resolution

function menu_startup()

{

       while (1)

       {

               main_pan.scale_x = screen_size.x / bmap_width(main_tga);

               main_pan.scale_y = screen_size.y / bmap_height(main_tga);

               wait (1);

       }

}

 

function start_game()

{

       beep(); // start your game here        

}

 

function exit_game()

{

       sys_exit(NULL); // shut down the engine        

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

 

Q: Is it possible to interact with a panel that's placed on top of a patrolling entity? I'd like to be able to click a boss enemy and open a menu.

A: Here's an example that does what you want.

 

BMAP* pointer_tga = "pointer.tga";

 

PANEL* temp_pan;

 

function show_value();

 

action boss_entity() // attach this action to the boss

{

       var anim_percentage;

       VECTOR temp_pos;

       temp_pan = pan_create("bmap = panel.pcx;", 10); // create a panel that uses the panel.pcx bitmap and has a layer of 10

       temp_pan.scale_x = 5 + random(10); // set a random scale value for the enemy panel each time

       temp_pan.flags |= SHOW; // and then make it visible  

       temp_pan.event = show_value; // this is the function that runs whenever the player clicks the panel

       while (1)

       {

               c_move (my, vector(3 * time_step, 0, 0), nullvector, GLIDE); // "3" controls the walking speed

               my.pan += 2 * time_step; // this line makes the entity walk in a circle

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

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

 

               vec_set (temp_pos, my.x); // copy the xyz coordinates of the entity to temp_pos

             temp_pos.z += 60; // play with this value, it sets the distance between the entity's origin and the panel

               vec_to_screen (temp_pos, camera); // convert the 3D position to 2D screen coordinates

                   temp_pan.pos_x = temp_pos.x; // then set the position of the panel

                   temp_pan.pos_y = temp_pos.y; // on x and y

             wait (1);

       }

}

 

function show_value() // open your menu here

{

       beep();        

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}