Questions from the forum |
Top Previous Next |
Q: I am trying to build a rocket that increases its speed until it reaches a certain value. Then, it should stop doing that and continue to fly at its current speed. A: Here's a good example: a weapon that tracks the speed using the distance covered during the last frame (a value returned by c_move).
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 var distance_covered; // global variable, so that we can display it using a digit on a panel var got_weapon1 = 0;
ENTITY* weapon1;
STRING* bullet_mdl = "bullet.mdl";
SOUND* bullet_wav = "bullet.wav";
function fire_bullets(); function move_bullets(); function remove_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 got_weapon1 = 1; 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 { if (!got_weapon1) return; // didn't get the weapon? Then don't allow the player to fire bullets! 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 = remove_bullets; // when it collides with something, its event function (remove_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 = 2 * time_step; // set the initial 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") { if (distance_covered < 100 * time_step) // increase bullet's speed until it reaches 100 * time_step; bullet_speed.x += 3 * time_step; // 3 gives the speed growth / frame // move the bullet ignoring the passable entities and store the result in distance_covered distance_covered = c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE); 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 }
PANEL* distance_pan = { layer = 15; digits(600, 20, 4.3 ,* , 1, distance_covered); flags = SHOW; }
Q: Could you please fix "Booker" from Aum72? It doesn't work fine with A8; I get an empty pointer error and the books' info isn't saved to the disk. A: Try it again with the latest A8 version - I just did that and it works fine now. The data can't be saved to the disk under Windows Vista and Windows 7 if you don't have the proper rights. Run secpol.msc at the command prompt to bring on the "Local Security Policy" window and set the needed permissions.
Q: Can you show me how I can create a mini map of a level? I'd like to have a circular view that shows the player in the center of the mini map. When an NPC comes into view the NPC shows up on the mini map as well. A: There you go.
VIEW* minimap_view;
ENTITY* minimap_model = { x = 100; // tweak these values until you set the desired position and size of the minimap view y = -40; z = 20; tilt = -90; type = "teler.mdl"; // use your own model here layer = 20; flags2 = SHOW; // show the model }
function minimap_startup() { while (!minimap_model) {wait (1);} minimap_view = view_create(10); // set the layer value for the view to 10 wait (2); set (minimap_view, SHOW); // the view will have 256x256 pixels; increase these values and the skin of the minimap model if you need a higher resolution minimap_view.size_x = 256; minimap_view.size_y = 256; minimap_view.bmap = bmap_for_entity(minimap_model, 0); minimap_view.arc = 90; // play with this value vec_set(minimap_view.pan, vector(0, -90, 0)); // make the minimap view point downwards (tilt = -90) while (1) { // set the position of the minimap 300 quants above the player - use a bigger value here if you'd like to see a bigger area around the player vec_set(minimap_view.x, vector(player.x, player.y, player.z + 300)); wait (1); } }
Q: I'd like to have an enemy with a sword that damages the player when the sword gets in contact with player's body. A: Check out my "Kung Fu Master" plug and play snippet from Aum93; the enemies damage the player by tracing from two vertices of their bodies, legs, etc. Simply replace those vertices with the base / tips vertices of the enemy sword and you'll be set.
Q: I'd like to have two panels that stay in the left / right upper corners of the screen regardless of the video resolution. A: Here's a simple, and yet fully working example.
BMAP* left_pcx = "left.pcx"; BMAP* right_pcx = "right.pcx";
PANEL* left_pan = { bmap = left_pcx; layer = 15; pos_x = 0; pos_y = 0; flags = SHOW; }
PANEL* right_pan = { bmap = right_pcx; layer = 15; flags = SHOW; }
function panels_startup() { while (1) { right_pan.pos_x = screen_size.x - bmap_width(right_pcx); wait (1); } }
Q: How do I make the player collide with the walls and not pass through them? I'm not sure where to start. A: You can move objects either by changing their coordinates directly, as in "player.x += 1;" or by using the proper way - the "c_move" instruction. Here's a simple example that can be attached to your player model.
action players_code() // attach this action to your player model { var movement_speed = 20; VECTOR temp; set (my, INVISIBLE); player = my; while (1) { // simple player movement code with gravity - use WSAD to move the player and the mouse to look around / rotate my.pan -= 7 * mouse_force.x * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 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);
// bonus - simple camera code! ;) 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); } }
Q: How can I attach a weapon to one of my soldiers? A: Animate the weapon together with the player, and then save them as separate models. If you have named your animated weapon "solgun.mdl", all you need to do is to attach the action below to your soldier model.
STRING* soldiergun_mdl = "solgun.mdl";
function attach_weapon() { proc_mode = PROC_LATE; set (my, PASSABLE); while(you) { vec_set(my.x, you.x); vec_set(my.pan, you.pan); my.frame = you.frame; my.next_frame = you.next_frame; wait(1); } ent_remove(my); }
action my_soldier() { var anim_percentage; ent_create(soldiergun_mdl, nullvector, attach_weapon); // give the soldier a gun while (1) { ent_animate(my, "walk", anim_percentage, ANM_CYCLE); anim_percentage += 4 * time_step; // "1" controls the "stand" animation speed c_move (my, vector(3 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); my.pan += 2 * time_step; // "2" controls the rotation speed wait (1); } }
Q: I want to have my player leaving a trail behind everywhere he changes direction. How can I accomplish this using the particle system? A: Here's a fully functional example that generates dust particles 30 quants below the origin of player's model whenever it rotates.
BMAP* dust_tga = "dust.tga";
function fade_dust(PARTICLE *p) { p.alpha -= 2 * time_step; // dust fading speed = 2 if (p.alpha < 0) {p.lifespan = 0;} }
function dust_particle(PARTICLE *p) { p->vel_x = 0; // slightly random p->vel_y = 0; // horizontal speed p->vel_z = random(1); // small vertical speed p.alpha = 70; // initial transparency, play with this value p.bmap = dust_tga; p.size = 10; p.flags |= (BRIGHT | MOVE); p.event = fade_dust; }
action players_code() // attach this action to your player model { var movement_speed = 4; var anim_percentage; VECTOR temp; player = my; while (1) { vec_set (temp.x, my.x); temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; temp.x = movement_speed * (key_cuu - key_cud) * time_step; my.pan -= movement_speed * (key_cur - key_cul) * 0.3 * time_step; temp.y = 0; c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE); camera.x = my.x; camera.y = my.y; camera.z = my.z + 500; camera.pan = my.pan; camera.tilt = -90; if (key_cuu + key_cud) // one of the movement keys is being pressed? ent_animate(my, "walk", anim_percentage, ANM_CYCLE); anim_percentage += 4 * time_step; // "1" controls the "stand" animation speed if (key_cul + key_cur) // one of the rotation keys is being pressed? effect (dust_particle, 3, vector(my.x, my.y, my.z - 30), normal); // generate dust particles 30 quants below the origin of the model wait (1); } }
Q: I need to know how to open a door if the player has got the security card. A: There you go.
var got_card = 0;
SOUND* gotcard_wav = "gotcard.wav";
action my_card() // attach this action to your card model { set (my, PASSABLE); while (!player) {wait (1);} while (vec_dist (player.x, my.x) > 100) // wait until the player comes close to the card { my.pan += 4 * time_step; // rotate the card around its pan angle until the player gets it wait (1); } snd_play(gotcard_wav, 60, 0); set (my, INVISIBLE); // the player has picked up the card, so hide it got_card = 1; }
action my_door() // attach this action to your door entity { VECTOR door_coords; vec_set (door_coords.x, my.x); // store the initial door position while (!got_card) {wait (1);} // wait until the player picks up the card while (vec_dist (player.x, my.x) > 150) {wait (1);} // wait until the player comes closer than 150 quants to the door while (my.x < door_coords.x + 80) // 80 gives the sideway movement (door offset) - play with this value { my.x += 3 * time_step; // 3 gives the door sliding speed - play with it wait (1); } }
Q: Please help me make a panel fade in and out. I have a main menu and buttons; when I press a certain button, I'd like the main menu to fade out and another panel to fade in. A: Here's a snippet that does what you want.
var main_alpha = 100; // stores the transparency value for the "main" panel var options_alpha = 0; // stores the transparency value for the "options" panel
BMAP* pointer_tga = "pointer.tga";
function new_game(); function exit_game();
PANEL* main_pan = { layer = 10; bmap = "main.jpg"; pos_x = 0; pos_y = 0; button (250, 100, "newgame2.pcx", "newgame1.pcx", "newgame2.pcx", new_game, NULL, NULL); button (250, 150, "exit2.pcx", "exit1.pcx", "exit2.pcx", exit_game, NULL, NULL); alpha = 100; flags = SHOW; }
PANEL* options_pan = { layer = 15; bmap = "options.pcx"; pos_x = 0; pos_y = 0; alpha = 0; flags = TRANSLUCENT; }
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function new_game() { main_pan.flags |= TRANSLUCENT; // the player has clicked the "options" button, so let's make the main panel transparent options_pan.flags |= SHOW; // show the options panel while (main_alpha > 5) // decrease main panel's alpha value, making it less and less visible { main_alpha -= 4 * time_step; // 4 gives main pan's fade out fading speed main_pan.alpha = main_alpha; options_alpha += 4 * time_step; // 4 gives option pan's fade in speed options_pan.alpha = options_alpha; wait (1); } main_pan.flags &= ~SHOW; // options_pan is visible, so let's hide the main panel options_pan.alpha = 100; // and then let's make options_pan fully visible by setting its alpha value to 100 }
function exit_game() { sys_exit(NULL); }
|