Questions from the forum |
Top Previous Next |
Q: I want to make a bullet destroy itself when it hits a wall. It sounds easy but I didn't manage to make it work. A: Use the code below.
SOUND* bullet_wav = "bullet.wav";
function remove_bullets() // this function runs when the bullet collides with the wall { wait (1); // wait a frame to be sure (don't trigger engine warnings) my.event = NULL; // don't trigger bullet events (for this bullet) anymore ent_playsound(my, bullet_wav, 2000); set (my, INVISIBLE); // hide the bullet wait (-1); // give the sound enough time to be played ent_remove (my); // and then remove the bullet }
function move_bullets() { VECTOR bullet_speed[3]; // stores the speed of the bullet // the bullet is sensitive to impacts with entities and 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 and tilt angles with its creator my.tilt = you.tilt; 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 while (my) // this loop will run for as long as the bullet exists (it isn't "NULL") { // move the bullet ignoring its creator (the bullet generator) c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU); wait (1); } }
action bullet_generator() { VECTOR bullet_pos[3]; while (1) { // generate bullets from the 108th vertex of the weapon (get the vertex number from Med) vec_for_vertex(bullet_pos, my, 108); ent_create("bullet.mdl", bullet_pos, move_bullets); wait (-2); // fire a bullet every 2 seconds } }
Q: I have made a platform (wmb) and the script to drive it, but the player falls through it. Is there any code which I can add to the lift script so that the player will stay on the lift and move with it? A: Your player code needs changes as well; here's an example of player and lift code that works fine:
ENTITY* lift1;
action players_code() // attach this action to your player { player = my; // I'm the player while (!lift1) {wait (1);} // wait until the lift entity is loaded var movement_speed = 20; // movement speed var distance_to_ground; VECTOR temp; set (my, INVISIBLE); // 1st person player while (1) { my.pan -= 7 * mouse_force.x * time_step; camera.x = my.x; camera.y = my.y; camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1 camera.pan = my.pan; camera.tilt += 5 * mouse_force.y * time_step; vec_set (temp.x, my.x); // trace 10,000 quants below the player temp.z -= 10000; distance_to_ground = c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | SCAN_TEXTURE); // replace "elevator1" with the name of the texture that is used by your lift if (str_cmpi(tex_name, "elevator1")) // the player is using the lift? { my.z = lift1.z + 100; // play with 100 } else // the player isn't using the lift? Then keep its feet on the ground { temp.z = -distance_to_ground + 20; // play with 20 } 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); wait (1); } }
action my_lift() // attach this action to your lift { lift1 = my; while (!player) {wait (1);} // wait until the player entity is loaded var init_z; var max_height = 200; // the lift can move upwards for up to 200 quants init_z = my.z; // store the initial height of the lift while (1) { while (my.z < init_z + max_height) { my.z += 5 * time_step; wait (1); } wait (-3); // wait 3 seconds at the top while (my.z > init_z) { my.z -= 5 * time_step; wait (1); } wait (-5); // wait 5 seconds at the bottom } }
Q: How can I make player's pan angle change depending on the position of the mouse? 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); } }
action players_code() { VECTOR temp, temp2; player = my; // I'm the player while (1) { temp.x = mouse_pos.x; temp.y = mouse_pos.y; temp.z = 2000; // create a position 2000 quants below the camera (not a critical value) vec_for_screen(temp, camera); vec_set(temp2, temp.x); vec_sub(temp2, my.x); vec_to_angle(my.pan, temp2); // player's pan points towards the mouse pointer here my.tilt = 0; // don't change player's tilt angle, though // put your own player movement code here wait (1); } }
Q: I have been trying to make a background picture that doesn't move. The camera is fixed; how can I use a picture that is 512 x 256 pixels so that it's behind everything all the times, stretched from 0,0 to 1024,768. A: Place the picture behind all the entities from your level, just like you'd place a regular sprite, and then play with its position and scale until it fills the entire screen.
action background_picture() { // the background picture is passable and doesn't get blurred set (my, PASSABLE | NOFILTER); my.pan = 0.1; // don't allow the sprite to rotate with the camera my.scale_x = 2; // play with this value, it sets the scale on the x axis my.scale_y = 3.5; // play with this value, it sets the scale on the y axis }
Q: I'd like to have my entities stop their animations if they aren't visible on the screen. A: Use this example.
action my_cow() { var anim_percentage = 0; set(my, POLYGON); while(1) { // the cow is visible on the screen? Then play its animation! if (!(my.eflags & CLIPPED)) { ent_animate(my, "eatgrass", anim_percentage, NULL); anim_percentage += 2 * time_step; anim_percentage %= 100; } else // the cow isn't visible on the screen here, so do something else if needed { // beep(); } wait (1); } }
Q: I am trying to create a weapon that fires bullets when I click the left mouse button, but doesn't allow the player to fire a new bullet until the "shoot" animation is 100% completed. A: Use the code below.
var gun_firing = 0;
ENTITY* weapon1;
SOUND* fire_wav = "fire.wav";
function attach_weapon1() { weapon1 = my; // I'm the gun set(my, PASSABLE); while (1) { vec_set (my.x, vector (20, -10, 35)); // set the proper gun offset in relation to the player vec_rotate (my.x, you.pan); vec_add (my.x, you.x); my.pan = you.pan; my.tilt = camera.tilt; wait (1); } }
action players_code() // simple player and 1st person camera code { player = my; // I'm the player ent_create ("gun1.mdl", nullvector, attach_weapon1); 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); vec_set (camera.x, player.x); // use player's x and y for the camera as well camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level) camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis player.pan = camera.pan; // the camera and the player have the same pan angle 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 }
function move_bullets() { VECTOR bullet_speed[3]; // stores the speed of the bullet // the bullet is sensitive to impacts with entities and 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 = weapon1.pan; my.tilt = weapon1.tilt; bullet_speed.x = 150 * 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 while (my) // this loop will run for as long as the bullet exists (it isn't "NULL") { // move the bullet ignoring its creator (weapon1) c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU); wait (1); } }
function fire_bullets() { if (gun_firing) return; // don't allow the player to fire until the previous "shot" animation has finished snd_play(fire_wav, 100, 0); gun_firing = 1; VECTOR bullet_pos[3]; var anim_factor = 0; // generate bullets from the 952th vertex of the weapon (get the vertex number from Med) vec_for_vertex(bullet_pos, weapon1, 952); while (anim_factor < 70) // the gun fires the bullet at 70% of its animation - play with 70 { ent_animate(weapon1, "shot", anim_factor, NULL); anim_factor += 7 * time_step; wait (1); } ent_create("bullet.mdl", bullet_pos, move_bullets); while (anim_factor < 100) // continue with the rest of the "shot" animation { ent_animate(weapon1, "shot", anim_factor, NULL); anim_factor += 6 * time_step; wait (1); } gun_firing = 0; // allow the gun to fire again }
function bullets_startup() { on_mouse_left = fire_bullets; }
Q: In the A5 templates there was a function called msg_show( ) that shows a message when it is called like this: msg_show("I AM AWESOME"); I was wondering if someone could create a new version that uses bitmapped fonts. A: There you go:
STRING* message_str = "#100"; // the message can have up to 100 characters
FONT* cool_font = "antique.tga";
SOUND* message_wav = "message.wav";
function msg_show(STRING* message, duration);
TEXT* message_txt = { pos_x = 200; pos_y = 20; string(message_str); font(cool_font); flags = SHOW; }
function msg_show(STRING* message, duration) { str_cpy((message_txt.pstring)[0], message); message_txt.flags |= SHOW; // display the message snd_play(message_wav, 70, 0); wait (-duration); // for the specified number of seconds message_txt.flags &= ~SHOW; // and then hide the message }
function messages_startup() { wait (-7); msg_show("I AM AWESOME", 3); wait (-5); msg_show("or at least cool", 2); wait (-4); msg_show("or maybe just a regular guy", 4); wait (-6); msg_show("OK, OK, I'm a bit dumb...", 5); }
Q: I need help with creating a countdown timer that will work while the player is running, and if the timer <= 0 the player is not able to run any more. Also, the timer must recharge so that the player can run again. A: Use this example.
var countdown_timer = 10;
SOUND* gottime_wav = "gottime.wav";
action players_code() // attach this action to your player { var movement_speed = 20; // movement speed VECTOR temp; set (my, INVISIBLE); // 1st person player player = my; // I'm the player while (1) { my.pan -= 7 * mouse_force.x * time_step; camera.x = my.x; camera.y = my.y; camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1 camera.pan = my.pan; camera.tilt = player.tilt; //5 * mouse_force.y * time_step; vec_set (temp.x, my.x); // trace 10,000 quants below the player temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 2 temp.x = movement_speed * (key_w - key_s) * time_step; temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step; if (countdown_timer > 0) // the countdown time didn't reach zero? { temp.x *= 2; // increase the forward movement speed with 100% temp.y *= 1.5; // increase the sideway movement speed with 50% } c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE); wait (1); } }
action get_time() // attach this action to the time powerups that can be picked up by the player { set (my, PASSABLE); while (!player) {wait (1);} // wait until the player model is loaded while (vec_dist (player.x, my.x) > 50) {wait (1);} snd_play(gottime_wav, 100, 0); set (my, INVISIBLE); countdown_timer += 10; wait (-2); ent_remove(my); }
function countdown_startup() { while (1) { countdown_timer -= time_step / 16; countdown_timer = maxv(countdown_timer, 0); // don't allow the timer to go below zero wait (1); } }
PANEL* time_pan = { layer = 15; digits(20, 20, 4 ,* , 1, countdown_timer); flags = SHOW; }
Q: Does anyone know how I can make props that only animate when they get destroyed? A: Use the following snippet; the crates / barrels only get destroyed and explode after being shot 3 times.
var gun_firing = 0;
ENTITY* weapon1;
SOUND* fire_wav = "fire.wav";
function attach_weapon1() { weapon1 = my; // I'm the gun set(my, PASSABLE); while (1) { vec_set (my.x, vector (20, -10, 35)); // set the proper gun offset in relation to the player vec_rotate (my.x, you.pan); vec_add (my.x, you.x); my.pan = you.pan; my.tilt = camera.tilt; wait (1); } }
action players_code() // simple player and 1st person camera code { player = my; // I'm the player ent_create ("gun1.mdl", nullvector, attach_weapon1); 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); vec_set (camera.x, player.x); // use player's x and y for the camera as well camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level) camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis player.pan = camera.pan; // the camera and the player have the same pan angle 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 }
function move_bullets() { my.skill99 = 1357; // uniquely identify a bullet VECTOR bullet_speed[3]; // stores the speed of the bullet // the bullet is sensitive to impacts with entities and 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 = weapon1.pan; my.tilt = weapon1.tilt; bullet_speed.x = 150 * 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 while (my) // this loop will run for as long as the bullet exists (it isn't "NULL") { // move the bullet ignoring its creator (weapon1) c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU); wait (1); } }
function fire_bullets() { if (gun_firing) return; // don't allow the player to fire until the previous "shot" animation has finished snd_play(fire_wav, 100, 0); gun_firing = 1; VECTOR bullet_pos[3]; var anim_factor = 0; // generate bullets from the 952th vertex of the weapon (get the vertex number from Med) vec_for_vertex(bullet_pos, weapon1, 952); while (anim_factor < 70) // the gun fires the bullet at 70% of its animation - play with 70 { ent_animate(weapon1, "shot", anim_factor, NULL); anim_factor += 7 * time_step; wait (1); } ent_create("bullet.mdl", bullet_pos, move_bullets); while (anim_factor < 100) // continue with the rest of the "shot" animation { ent_animate(weapon1, "shot", anim_factor, NULL); anim_factor += 6 * time_step; wait (1); } gun_firing = 0; // allow the gun to fire again }
function bullets_startup() { on_mouse_left = fire_bullets; }
// destroyable crate / barrel code from here on
function explo_sprite() { set(my, BRIGHT); my.alpha = 100; my.scale_x = 3; // this value gives the scale of the explosion sprite my.scale_y = my.scale_x; my.frame = 1; while (my.frame < 5) { my.frame += 0.5 * time_step; wait (1); } while (my.alpha > 0) { my.alpha -= 3 * time_step; wait (1); } ent_remove (my); }
function destroy_crate() { // don't do anything if the crate wasn't destroyed by one of player's bullets // we have set skill99 to 1357 for each bullet inside function move_bullets() - above if (you.skill99 != 1357) return; my.skill1 -= 1; }
action my_crate() { my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); my.event = destroy_crate; my.skill1 = 3; // allow the while (my.skill1 > 1) {wait (1);} // the crate was shot 3 times here ent_create("explo+5.pcx", my.x, explo_sprite); my.alpha = 100; set (my, TRANSLUCENT); while (my.alpha > 0) { my.alpha -= 7 * time_step; wait (1); } ent_remove (my); // and then remove the crate }
Q: Does anyone has an idea in implementing an entity passing through a tunnel and exiting on another tunnel? It's like a portal in Quake 3; when the player enters the portal, it'll exit somewhere else in the map. A: Use this example as a base for your code:
ENTITY* beamer1; ENTITY* beamer2;
action players_code() // attach this action to your player { var movement_speed = 20; // movement speed VECTOR temp; set (my, INVISIBLE); // 1st person player player = my; // I'm the player while (1) { my.pan -= 7 * mouse_force.x * time_step; camera.x = my.x; camera.y = my.y; camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1 camera.pan = my.pan; camera.tilt = player.tilt; //5 * mouse_force.y * time_step; vec_set (temp.x, my.x); // trace 10,000 quants below the player temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 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); wait (1); } }
function beam_me1() { my.event = NULL; // don't trigger several events wait (1); set (beamer2, PASSABLE); // don't allow beamer2 to teleport the player back to beamer1 vec_set(player.x, beamer2.x); my.event = beam_me1; }
action portal1() // attach this action to the first portal { beamer1 = my; while (!player) {wait (1);} my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); while (1) { if (vec_dist(player.x, my.x) < 10) // the player was just beamed here? { set (my, PASSABLE); my.event = NULL; // then don't allow this beamer to teleport it back // wait until the player has moved away from this beamer while (vec_dist (my.x, player.x) < 100) {wait (1);} } else { reset (my, PASSABLE); my.event = beam_me1; } wait (1); } }
function beam_me2() { my.event = NULL; // don't trigger several events wait (1); set (beamer1, PASSABLE); // don't allow beamer1 to teleport the player back to beamer2 vec_set(player.x, beamer1.x); my.event = beam_me2; }
action portal2() // attach this action to the second portal { beamer2 = my; while (!player) {wait (1);} my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); while (1) { if (vec_dist(player.x, my.x) < 10) // the player was just beamed here? { set (my, PASSABLE); my.event = NULL; // then don't allow this beamer to teleport it back // wait until the player has moved away from this beamer while (vec_dist (my.x, player.x) < 100) {wait (1);} } else { reset (my, PASSABLE); my.event = beam_me2; } wait (1); } }
|