Questions from the forum |
Top Previous Next |
Q: I'm looking for an auto game save snippet; when the player reaches a certain point in the level, the game saves, and if the player dies, he starts again at the save point, and not at the beginning of the level. A: Here's a fully functional example.
var players_health = 100; VECTOR player_position; ANGLE player_angle;
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; 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); 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; while (players_health <= 0) // the player is dead? { camera.roll = 70; // then let's make the camera look weird camera.z = player.z - 30; // this while loop will prevent the player from moving wait (1); } wait (1); } }
action checkpoint() // attach this to your autosave model (a portal, a gate, etc) { while (!player) {wait (1);} // wait until the player model is loaded in the level // wait until the player comes closer than 200 quants to the autosave model while (vec_dist (player.x, my.x) > 200) {wait (1);} vec_set (player_position, player.x); // store player's position vec_set (player_angle, player.pan); // store player's angles // put a nice "Game Saved!" panel here, make it visible for a few seconds, and then remove it }
function restore_startup() // restores player's health and angles { while (1) { while (players_health > 0) // wait until the player is dead { wait (1); } // now let's restore player's health players_health = 100; vec_set (player.x, player_position); // and its autosave position vec_set (player.pan, player_angle); // and angles camera.roll = 0; // restore camera's roll angle as well wait (1); } }
function take_health() { if (you == player) // collided with the player? players_health = 0; // then make it die! }
action health_taker() // run into this entity to make the player lose its health { my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // this entity is sensitive to impact with entities my.event = take_health; // and runs this function when it is hit }
Q: I want to check if a video is still being played. Is there any way to do this? A: There you go.
var movie_handle;
function movie_playing_startup() { movie_handle = media_play("mymovie.avi", NULL, 70); while (media_playing (movie_handle)) {wait (1);} beep(); beep(); // the movie has stopped here, so do what you need }
Q: I used ent_create to attach a flare to a key model, so that player can find the key easier in the level. Now I want to remove the flare as soon as the key model is removed. Is there any way to do this? A: Here's an example.
var got_key = 0;
function attach_flare() { set (my, PASSABLE); while (you) // this loop will run for as long as the key model exists { my.x = you.x; // place the flare at the same position with the origin of the key model wait (1); } ent_remove (my); // the key is gone now, so let's remove the flare sprite as well }
action glowing_key() { set (my, PASSABLE); ent_create ("flare.tga", my.x, attach_flare); while (!player) {wait (1);} while (vec_dist (player.x, my.x) > 70) // wait until the player comes close to the key { my.pan += 3 * time_step; wait (1); } got_key = 1; // set the got_key variable, we will use it later in the game to open the corresponding door ent_remove (my); // and then remove it }
Q: I am working at a racing game based on the car template and I'd like to have my cars rotate (change their pan) in a car selection screen, but only do that while they are touched by the mouse. Can you help? A: Here's a simple example that does what you want.
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 rotate_me() { proc_kill(1); while (event_type != EVENT_RELEASE) { my.pan += 3 * time_step; wait (1); } }
action rotating_car() { my.emask |= ENABLE_TOUCH | ENABLE_RELEASE; my.event = rotate_me; }
Q: I'd like my camera to follow the player at all times, changing to a camera that rotates around slowly, showing the nearby areas, if the player doesn't move at all for 10 seconds. How can I do this? A: Here's a fully functional player / camera action.
action player_and_camera() // attach this action to your player model { var camera_time = 10; // the camera starts rotating around after 10 seconds var camera_increments = 0; var movement_speed = 20; VECTOR temp; set (my, INVISIBLE); player = my; while (1) { if (key_any) // the player has pressed one of the keys? Then let's reset camera_increments! { camera_increments = 0; } else // no key is being pressed? Then let's increase camera_increments! { camera_increments += time_step / 16; // add 1 to camera_increments each second } my.pan -= 7 * mouse_force.x * time_step; temp.z = 0; 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; if (camera_increments > 10) // the player didn't touch any of the keys for at least 10 seconds? { camera.pan += 0.8 * time_step; } else { camera.pan = my.pan; } camera.tilt += 5 * mouse_force.y * time_step; wait (1); } }
Q: Do you have an example for a door that opens automatically (sliding vertically) when the player approaches it and closes automatically when the player has moved away from it? A: Sure thing.
var trigger_range = 100;
SOUND* sliding_wav = "sliding.wav";
action my_door() { var initial_z; // make sure to include a "player = my;" line of code to your player action while (!player) {wait (1);} initial_z = my.z; while (1) { // wait until the player comes closer than 100 quants to the door, play with trigger_range while (vec_dist (player.x, my.x) > 100) {wait (1);} snd_play (sliding_wav, 100, 0); // slide the door upwards by 200 quants, play with this value while (my.z < (initial_z + 200)) { my.z += 5 * time_step; // 5 gives the upwards sliding speed wait (1); } // wait until the player moves away 500 quants from the door (5 * trigger_range) while (vec_dist (player.x, my.x) < (5 * trigger_range)) {wait (1);} snd_play (sliding_wav, 100, 0); while (my.z > initial_z) // slide the door downwards, until it reaches the initial height { my.z -= 5 * time_step; // 5 gives the downwards sliding speed wait (1); } // make sure that the door returns to the exact initial position regardless of the frame rate value my.z = initial_z; wait (1); } }
Q: I'd like to have a weapon which fires bullets that don't disappear, but bounce from wall to wall indefinitely. A: Use the snippet below; don't forget that each new bullet is a new entity that will stay in the level, so if you're going to fire thousands of bullets the frame rate will decrease.
var front_offset = 30; // animates player's weapon while it is firing by moving it backwards var init_offset = 30; // stores front_offset's value
ENTITY* weapon1;
STRING* bullet_mdl = "bullet.mdl";
SOUND* bullet_wav = "bullet.wav";
function fire_bullets(); function move_bullets(); function redirect_bullets();
action players_weapon() // place your weapon model in the level and attach it this action { weapon1 = my; // I'm weapon1 VECTOR player1_pos; // stores the initial position of the player VECTOR player2_pos; // stores the position of the player after a frame VECTOR weapon_offset; var weapon_height; set (my, PASSABLE); // the weapon model is passable while (!player) {wait (1);} // wait until the player is created while (vec_dist (player.x, my.x) > 50) {wait (1);} // wait until the player comes close to pick up the weapon my.roll = 0; while (1) { vec_set (player1_pos.x, player.x); // store the initial player position // place the weapon 30 quants in front, 18 quants to the right and 20 quants below camera's origin vec_set (weapon_offset.x, vector (front_offset, -18, -20)); if (vec_dist (player1_pos.x, player2_pos.x) != 0) // the player has moved during the last frame? { weapon_height += 30 * time_step; // then offset weapon_height (30 = weapon waving speed) weapon_offset.z += 0.3 * sin(weapon_height); // (0.3 = weapon waving amplitude) } // rotate weapon_offset according to the camera angles vec_rotate (weapon_offset.x, vector (camera.pan, camera.tilt, 0)); vec_add (weapon_offset.x, camera.x); // add the camera position to weapon_offset vec_set (my.x, weapon_offset.x); // set weapon's coords to weapon_offset my.pan = camera.pan; // use the same camera angles for the weapon my.tilt = camera.tilt; vec_set (player2_pos.x, player.x); // store the new player coordinates after 1 frame wait (1); } }
function weapon_startup() { on_mouse_left = fire_bullets; // call function fire_bullets() when the left mouse button is pressed }
function fire_bullets() // includes the code that animates the weapon as well { var temp_seconds = 0; VECTOR temp; proc_kill(4); // don't allow more than 1 copy of this function to run while (mouse_left) // this loop runs for as long as the left mouse button is pressed { front_offset -= 1; // move the weapon backwards a bit vec_for_vertex (temp.x, weapon1, 29); // get the coordinates for the bullets' origin // create the bullet at camera's position and attach it the "move_bullets" function ent_create (bullet_mdl, temp.x, move_bullets); temp_seconds = 0; snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100 while (temp_seconds < 0.5) { temp_seconds += time_step / 16; // adds 0.5 to temp_seconds in 0.5 seconds) front_offset -= 0.1; // restore the position of the weapon wait (1); } while (front_offset < init_offset) { front_offset += 0.1; // restore the position of the weapon wait (1); } front_offset = init_offset; } }
function move_bullets() { VECTOR bullet_speed; // stores the speed of the bullet my.skill30 = 1; // I'm a bullet my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK); my.event = redirect_bullets; // when it collides with something, its event function (redirect_bullets) will run my.pan = camera.pan; // the bullet has the same pan my.tilt = camera.tilt; // and tilt with the camera bullet_speed.x = 200 * time_step; // adjust the speed of the bullet here bullet_speed.y = 0; // the bullet doesn't move sideways bullet_speed.z = 0; // then don't allow the gravity to have its ways with the bullet while (my) // this loop will run for as long as the bullet exists (it isn't "null") { // move the bullet ignoring the passable entities and store the result in distance_covered c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE); wait (1); } }
function redirect_bullets() // this function runs when the bullet collides with something { vec_to_angle(my.pan, bounce); // change the angle of the bullet }
Q: In my game, the users have profiles to write their data; what should I do with these profiles when I publish my game? If I put them in the wrs file I can't change them anymore, and if i put them out of the wrs file, the users can change them to anything that they want to. Is there any way to solve this problem? A: You can save the profiles to regular txt file, encrypting the information before writing it to the file and decrypting it before using it. Check out the Ncrypt article from Aum53 to see an example.
Q: I need a piece of code that will display a sphere made out of particles for my Star Wars clone. What is an easy method to create that? A: The easiest method would be to use a sphere model and generate a particle from each one of its vertices - here's an example.
BMAP* particle_tga = "particle.tga";
function keep_particle(PARTICLE *p) { p.lifespan = 99999; // use a big value here }
function particle_effect(PARTICLE *p) { p.bmap = particle_tga; p.size = 2; // gives the size of the particles p.flags |= BRIGHT; p.event = keep_particle; }
action sphere() // attach this action to a sphere model { set (my, PASSABLE | INVISIBLE); var particle_pos[3]; while (my.skill1 < ent_vertices (my)) { my.skill1 += 1; vec_for_vertex(particle_pos, my, my.skill1); effect(particle_effect, 1, particle_pos, nullvector); } }
Q: I'd like an example of code that starts playing a soundtrack and after a specified interval fades it out, while at the same time fading in a new soundtrack, just the way they do it at radio stations. A: Here's an example that does what you want.
var track1_volume = 100; var track2_volume = 1;
function music_startup() { var track1_handle, track2_handle; track1_handle = media_play("track1.wav", NULL, track1_volume); wait (-20); // play the first track for 20 seconds track2_handle = media_play("track2.wav", NULL, track2_volume); // now start the second track at a tiny volume (1) while (track1_volume > 0) // now change the volume - decrease it gently { media_tune(track1_handle, track1_volume, 100, 0); media_tune(track2_handle, track2_volume, 100, 0); track1_volume -= 0.6 * time_step; // 0.6 gives the fade-out speed track1_volume = maxv(track1_volume, 0); track2_volume += 0.8 * time_step; // 0.8 gives the fade-in speed track2_volume = minv(track2_volume, 100); wait (1); } wait (-20); // play the second track for 20 seconds media_stop (track1_handle); // now stop the sound tracks for good media_stop (track2_handle); }
|