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