Questions from the forum |
Top Previous Next |
Q: How can I create an object that uses c_scan to damage the player when it is nearby? A: Use the following snippet as a base for your code.
var players_health = 100;
SOUND* damage_wav = "damage.wav";
action my_player() // attach this action to your player model { var movement_speed = 20; VECTOR temp; set (my, INVISIBLE); player = my; while (players_health > 0) { my.pan -= 7 * mouse_force.x * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = 0; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE) - 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); 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); } camera.roll -= 30; // slant the camera, the player is dead here }
// attach this action to an entity that is supposed to kill the player action player_destroyer() { while (!player) {wait (1);} VECTOR temp[3]; while (1) { my.pan += 24 * time_step; // rotating damaging stuff looks scarier ;) // the player will be damaged if it comes closer than 200 quants to this entity c_scan(my.x, my.pan, vector(360, 90, 200), IGNORE_ME | SCAN_ENTS); // play with 200 if (you == player) // detected the player? { players_health -= 2 * time_step; // reduce player's health here, play with 5 if (total_frames % 50 == 1) snd_play(damage_wav, 100, 0); } wait (1); } }
Q: How do I create a totally transparent panel with visible buttons? A: Create a panel that doesn't use a bmap. Here's an example:
BMAP* pictureon_pcx = "pictureon.pcx"; BMAP* pictureoff_pcx = "pictureoff.pcx";
BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function your_function_here() { beep(); }
PANEL* invisible_pan = { layer = 15; button(40, 10, pictureon_pcx, pictureoff_pcx, pictureon_pcx, your_function_here, NULL, NULL); flags = SHOW; }
Q: How do I create a menu that opens up when I click one of my RTS units? A: Here's an example that creates a pop-up menu with two options - unit clockwise and counterclockwise rotation.
BMAP* pointer_tga = "pointer.tga";
BMAP* rotate1_jpg = "rotate1.jpg"; BMAP* rotate2_jpg = "rotate2.jpg"; BMAP* cckrotate1_jpg = "cckrotate1.jpg"; BMAP* cckrotate2_jpg = "cckrotate2.jpg";
var unit_angle;
VECTOR* unit_pos[3];
ENTITY* active_unit;
function rotate_clockwise(); function rotate_counterclockwise();
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
PANEL* unit_pan = { bmap = "rtsmenu.png"; button = 0, 0, rotate1_jpg, rotate2_jpg, rotate1_jpg, rotate_clockwise, NULL, NULL; button = 128, 0, cckrotate1_jpg, cckrotate2_jpg, cckrotate1_jpg, rotate_counterclockwise, NULL, NULL; }
function rotate_clockwise() { unit_angle = active_unit.pan; while (active_unit.pan < (unit_angle + 360)) { active_unit.pan += 5 * time_step; wait (1); } }
function rotate_counterclockwise() { unit_angle = active_unit.pan; while (active_unit.pan > (unit_angle - 360)) { active_unit.pan -= 5 * time_step; wait (1); } }
function display_menu() { active_unit = my; vec_set(unit_pos, my.x); vec_to_screen(unit_pos, camera); unit_pan.pos_x = unit_pos.x; unit_pan.pos_y = unit_pos.y; unit_pan.flags |= VISIBLE; }
action rts_unit() { my.emask |= ENABLE_CLICK; my.event = display_menu; while (1) { wait (1); // do your RTS movement, AI, etc here } }
Q: How do I make an entity "wake up" (play a lively animation) when the mouse pointer if over it? A: There you go:
BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function animate_me() { if (event_type == EVENT_RELEASE) { my.skill99 = 1; } if (event_type == EVENT_TOUCH) { my.skill99 = 0; } }
action my_npc() { var anim_speed; my.emask |= ENABLE_TOUCH | ENABLE_RELEASE; my.event = animate_me; my.skill99 = 1; // the entity is animate using its "stand" animation by default while (1) { if (my.skill99 == 1) // playing the "stand" animation? { anim_speed += 2 * time_step; ent_animate(my, "stand", anim_speed, ANM_CYCLE); } else { anim_speed += 3 * time_step; ent_animate(my, "walk", anim_speed, ANM_CYCLE); } wait (1); } }
Q: I'd like to have a camera that rotates around the player, showing its surroundings, while a key is being pressed. The camera should return to a 3rd person perspective after I release the key. A: Here's a code snippet that does what you want.
action my_player() { var movement_speed = 10; // movement speed var anim_percentage; var camangle; VECTOR temp; VECTOR temp2; player = my; // I'm the player while (1) { if((!key_w) && (!key_s) && (!key_a) && (!key_d)) // the player isn't moving at all? { ent_animate(my, "stand", anim_percentage, ANM_CYCLE); // and play the "stand" animation } else // the player is moving? { camangle = 0; // reset the camera rotation angle ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // and play the "walk" animation } anim_percentage += 5 * time_step; // 5 = animation speed if (key_r) // the "R" key has been pressed? Then let's rotate the player! { camera.x = player.x - 250 * cos(camangle); camera.y = player.y - 250 * sin(camangle); camangle += 0.5 * time_step; vec_set(temp2.x, my.x); vec_sub(temp2.x, camera.x); vec_to_angle(camera.pan, temp2); } else // the "R" key isn't pressed? { camera.x = player.x - 250 * cos(player.pan); camera.y = player.y - 250 * sin(player.pan); camera.pan = player.pan; } camera.z = player.z + 150; // place the camera above the player, play with this value camera.tilt = -25; temp.x = movement_speed * (key_w - key_s) * time_step; temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step; temp.z = 0; c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE); wait (1); } }
Q: How do I load a different level, depending on the hallway that the player chooses? A: Place entities that trigger level loading instructions in the center of the hallways, and then use a code snippet like this:
STRING* level1_wmb = "level1.wmb"; STRING* level2_wmb = "level2.wmb"; STRING* level3_wmb = "level3.wmb";
action player_code() // attach this action to your player model { var movement_speed = 20; VECTOR temp; set (my, INVISIBLE); player = my; while (1) { my.pan -= 7 * mouse_force.x * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = 0; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE) - 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); 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); } }
action hallway_entity1() { while (!player) {wait (1);} // wait until the player comes closer than 150 quants to the entity while (vec_dist (player.x, my.x) > 150) {wait (1);} level_load (level1_wmb); }
action hallway_entity2() { while (!player) {wait (1);} // wait until the player comes closer than 150 quants to the entity while (vec_dist (player.x, my.x) > 150) {wait (1);} level_load (level2_wmb); }
action hallway_entity3() { while (!player) {wait (1);} // wait until the player comes closer than 150 quants to the entity while (vec_dist (player.x, my.x) > 150) {wait (1);} level_load (level3_wmb); }
Q: How do I put a rotating siren on top of my police car? It should rotate and move with the car at all times, of course. A: Create a separate model for the siren and attach it the action below.
STRING* siren_mdl = "siren.mdl";
function attach_siren() { while (1) { // place the siren 0 quants in front of the car, 0 quants sideways and 50 quants above the car model's origin // tweak these values according to your needs vec_set (my.x, vector(0, 0, 50)); vec_rotate (my.x, you.pan); vec_add (my.x, you.x); my.pan += 25 * time_step; // rotate the siren model wait (1); } }
action my_car() // simple car action, rotates the car in a circle { ent_create (siren_mdl, my.x, attach_siren); while (1) // use your own car code here { c_move (my, vector (10 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); my.pan += 2 * time_step; // make this car rotate in a circle at all times wait (1); } }
Q: How do I complete a small puzzle for kids by simply running into its pieces? A: Here's an example that uses 4 puzzle pieces.
BMAP* puzzle1_pcx = "puzzle1.pcx"; BMAP* puzzle2_pcx = "puzzle2.pcx"; BMAP* puzzle3_pcx = "puzzle3.pcx"; BMAP* puzzle4_pcx = "puzzle4.pcx";
PANEL* puzzle1_pan = { bmap = puzzle1_pcx; pos_x = 0; pos_y = 0; }
PANEL* puzzle2_pan = { bmap = puzzle2_pcx; pos_x = 200; pos_y = 0; }
PANEL* puzzle3_pan = { bmap = puzzle3_pcx; pos_x = 0; pos_y = 200; }
PANEL* puzzle4_pan = { bmap = puzzle4_pcx; pos_x = 200; pos_y = 200; }
action players_code() // attach this action to your player model { var movement_speed = 20; VECTOR temp; set (my, INVISIBLE); player = my; while (1) { my.pan -= 7 * mouse_force.x * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = 0; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE) - 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); 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); } }
action puzzle1() // attach this to your first puzzle piece image (use the same sprite, a model, etc) { set(my, PASSABLE); while (!player) {wait (1);} // wait until the player is loaded while (vec_dist (player.x, my.x) > 70) {wait (1);} set(puzzle1_pan, SHOW); ent_remove(my); }
action puzzle2() // attach this to your second puzzle piece { set(my, PASSABLE); while (!player) {wait (1);} // wait until the player is loaded while (vec_dist (player.x, my.x) > 70) {wait (1);} set(puzzle2_pan, SHOW); ent_remove(my); }
action puzzle3() // attach this to your third puzzle piece { set(my, PASSABLE); while (!player) {wait (1);} // wait until the player is loaded while (vec_dist (player.x, my.x) > 70) {wait (1);} set(puzzle3_pan, SHOW); ent_remove(my); }
action puzzle4() // attach this to your fourth puzzle piece { set(my, PASSABLE); while (!player) {wait (1);} // wait until the player is loaded while (vec_dist (player.x, my.x) > 70) {wait (1);} set(puzzle4_pan, SHOW); ent_remove(my); }
Q: How do you create a 3D arrow that points down at a particular NPC who is moving on a path? A: Use this snippet as a base for your code:
ENTITY* dummy1;
STRING* arrow_mdl = "arrow.mdl";
function npc_arrow() { my.tilt -= 90; // if you want to convert an horizontal arrow into a vertical one, pointing downwards my.z = you.z + 130; // play with 130, it sets the vertical distance between the arrow and the npc origin set(my, PASSABLE); while (1) { // find the best combination by playing with 3 (amplitude) and 15 (speed) my.x = you.x; my.y = you.y; my.z += 3 * sin(total_ticks * 15) * time_step; wait (1); } }
action my_npc() { ent_create(arrow_mdl, nullvector, npc_arrow); var walk_percentage; var distance = 0; var previous_pan; var following_pan; var min_speed = 1; var max_speed = 3; var walking_speed; VECTOR last_pos[3]; VECTOR direction[3]; // create a dummy entity that will move on the path dummy1 = ent_create(NULL, nullvector, NULL); // make sure to name your path this way path_set(dummy1, "path_001"); while(1) { previous_pan = my.pan; // place the dummy entity on the path path_spline(dummy1, my.x, distance); distance += walking_speed * time_step; // let the npc look ahead vec_diff(direction, my.x, last_pos); vec_to_angle(my.pan, direction); vec_set(last_pos, my.x); wait(1); following_pan = my.pan; // sudden direction change during the last frame? Then lower the speed of the npc! if (abs(following_pan - previous_pan) > 1) { walking_speed -= 4 * time_step; } else { walking_speed += 2 * time_step; } // don't allow the walking speed to exceed the specified min / max limits walking_speed = clamp(walking_speed, min_speed, max_speed); ent_animate(my, "walk", walk_percentage, ANM_CYCLE); // play the "walk" animation walk_percentage += 3 * time_step; // "3" controls the animation speed } }
|