Questions from the forum |
Top Previous Next |
Q: I need the code for a mouse that runs out of a hole, follows a path, and then returns to its home. Then, everything repeats over and over. Can you help? A: Sure. Create a path in Wed and name it "mouse_path". Then, add your mouse model to the level and attach it the "my_mouse" action.
ENTITY* dummy1;
action my_mouse() { var run_frames; var distance = 0; var previous_pan; var following_pan; var min_speed = 1; var max_speed = 3; var mouse_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, "mouse_path"); while(1) { previous_pan = my.pan; // place the dummy entity on the path path_spline(dummy1, my.x, distance); distance += mouse_speed * time_step; // let the mouse 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 mouse! if (abs(following_pan - previous_pan) > 1) { mouse_speed -= 4 * time_step; } else { mouse_speed += 2 * time_step; } // don't allow the running speed to exceed the specified min / max limits mouse_speed = clamp(mouse_speed, min_speed, max_speed); // keep mouse_speed in the 1...3 interval ent_animate(my, "run", run_frames, ANM_CYCLE); // play the "run" animation - make sure that your mouse includes it run_frames += 3 * time_step; // "3" controls the run animation speed } }
Q: I use a water bitmap in my level. I can pass through it, but if it is placed horizontally, it is a barrier. 'Passable' is ticked, and I have tried using 'my.passable=on'. Please help! A: You will also need a player movement snippet that ignores passable entities. Here's a good player movement snippet that does the job.
var t_player_speed = 25; // player's movement speed var t_fwdbk_accel = 7; // player's forward / backward acceleration var t_side_accel = 3; // player's sideway (strafe) acceleration var t_friction = 1.5; // player's friction - this value should always be greater than 1 var t_fallspeed = 1; // player's fall down speed var t_jump = 20; // player's jumping force var t_resilience = 4; // pushes the player upwards a bit if it sinks too much in the floor var t_disttoground = 64; // distance between the origin of player's model and the ground (used by the camera as well) var t_camera_h = 12; // horizontal camera acceleration var t_camera_h_frict = 0.95; // always use a value below 1 here var t_camera_v = 8; // vertical camera acceleration var t_camera_v_frict = 0.8; // always use a value below 1 here var t_players_health = 100; // the player starts with 100 health points var camera_h_speed = 0; var camera_v_speed = 0;
action players_code() { player = my; set (my, INVISIBLE); // using a 1st person player set (my, FLAG2); // will be used by enemies' c_scan instructions to detect the player var forward_on, backward_on, right_on, left_on, jump_on, run_on; var current_height = 0, jump_handle; VECTOR horizontal_speed, vertical_speed, temp; vec_set(horizontal_speed.x, nullvector); // initialize this vector vec_set(vertical_speed.x, nullvector); // initialize this vector while(t_players_health > 0) { // key input start forward_on = 0; // reset all the key values at the beginning of each frame backward_on = 0; right_on = 0; left_on = 0; jump_on = 0; run_on = 0; // set the proper variables if their corresponding keys are pressed if(key_w) forward_on = 1; if(key_s) backward_on = 1; if(key_a) left_on = 1; if(key_d) right_on = 1; if(key_space) jump_on = 1; if(key_shift) run_on = 1; // key input end
vec_set(camera.x, my.x); // accelerate camera's pan and tilt angles depending on mouse_force.x and mouse_force.y in order to create a smooth camera camera.pan -= accelerate (camera_h_speed, t_camera_h * (mouse_force.x), t_camera_h_frict); camera.tilt += accelerate (camera_v_speed, t_camera_v * (mouse_force.y), t_camera_v_frict); camera.tilt = clamp(camera.tilt, -90, 90); // limit the tilt angle of the camera to -90... 90 degrees my.pan = camera.pan;
// player's horizontal speed (forward / backward / sideways) movement uses acceleration and friction as well horizontal_speed.x = (horizontal_speed.x > 0) * maxv(horizontal_speed.x - time_step * t_friction, 0) + (horizontal_speed.x < 0) * minv(horizontal_speed.x + time_step * t_friction, 0); if(forward_on) { horizontal_speed.x += time_step * t_fwdbk_accel; horizontal_speed.x = minv(horizontal_speed.x, time_step * t_player_speed * (1 + run_on)); } if(backward_on) { horizontal_speed.x -= time_step * t_fwdbk_accel; horizontal_speed.x = maxv(horizontal_speed.x, -(time_step * t_player_speed * (1 + run_on))); } horizontal_speed.y = (horizontal_speed.y > 0) * maxv(horizontal_speed.y - time_step * t_friction, 0) + (horizontal_speed.y < 0) * minv(horizontal_speed.y + time_step * t_friction, 0); if(left_on) { horizontal_speed.y += time_step * t_side_accel; horizontal_speed.y = minv(horizontal_speed.y, time_step * t_player_speed * (1 + run_on)); } if(right_on) { horizontal_speed.y -= time_step * t_side_accel; horizontal_speed.y = maxv(horizontal_speed.y, -(time_step * t_player_speed * (1 + run_on))); } // disable the friction, allow smooth gliding along the surfaces move_friction = 0; vec_set(temp.x, my.x); temp.z -= 10000; current_height = c_trace(my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX | GLIDE); // compute the distance between player's origin and the floor below its feet if(current_height < (t_disttoground * 0.97)) // if it is smaller than the default value (64 quants) push the player upwards a bit (resilience) - 0.97 gives the hysteresis { vertical_speed.z = t_resilience * time_step; } else { if(current_height > t_disttoground) // if it is bigger than the default value (64 quants), move the player downwards { vertical_speed.z -= t_fallspeed * time_step; } else // sitting properly on the floor? { vertical_speed.z = 0; // then don't do anything on the z axis } } if((jump_on) && (current_height < t_disttoground)) // jumping while player's feet are placed on the floor? { vertical_speed.z = t_jump * 0.25; // push the player upwards } // this c_move instruction does all the job, moving the player in the direction given by horizontal_speed (forward, backward, sideways) and vertical_speed (on the z axis) c_move (my, horizontal_speed.x , vertical_speed.x, IGNORE_PASSABLE | USE_BOX | GLIDE); // player movement end wait(1); } camera.z -= 30; // bring the camera closer to the floor camera.roll = 40; // and rotate its view (the player is dead here) }
Q: I have a lamp over a desk. How can I turn it on and off by clicking it with the mouse? A: Here's an example:
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 toggle_light() { if (my.lightrange == 100) my.lightrange = 0; else my.lightrange = 100; }
action my_lamp() { set (my, PASSABLE); my.emask |= ENABLE_CLICK; my.event = toggle_light; }
Q: I would like a fade-in & fade-out snippet for my music. It is designed to fade in a tense music loop if the enemy can see you, and then stop where it was and fade back out if the enemy can't see you anymore. A: There you go:
var loop_handle; var loop_volume = 1; var fade_count = 0;
function turn_music_on() { fade_count += 1; if (fade_count == 1) { loop_handle = media_loop("tense.wav", NULL, loop_volume); while (loop_volume < 90) { media_tune(loop_handle, loop_volume, 0, 0); loop_volume += 1 * time_step; // 1 = fade in speed wait (1); } } }
function turn_music_off() { fade_count += 1; if (fade_count == 1) { while (loop_volume > 3) { media_tune(loop_handle, loop_volume, 0, 0); loop_volume -= 0.05 * time_step; // 0.05 = fade out speed wait (1); } snd_stop (loop_handle); fade_count = 0; } }
action my_enemy() { 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? { // make sure that your player action includes a "player = my;" line of code if (you == player) // the player has been detected { turn_music_on(); } } else // didn't detect the player here { fade_count = 0; turn_music_off(); } wait (1); } }
Q: A local Computer retailer has agreed to allow me to test run some of my project on his stores different gaming PCs. However I am not allowed to move the .exe or program folder on to the HDD, instead I must run it from a USB flash drive. Since there is a difference between read speeds of high end HDDs and USB flash drives, can I expect a slowdown in game execution and/or level load times? A: Loading times will definitely be longer, but your game should run fine as long as it doesn't need a lot of memory. The good news is that you can use a fast SSD drive in an enclosure, connecting it to the USB port. Drives like Samsung's PRO and even EVO SSDs have reading and writing speeds that can exceed 500 MB/s. With a setup like this your game will run faster than what you'd hope to achieve by copying it to the gaming PCs.
Q: Is there a simple way in Gamestudio to receive an event when a mouse button is released? A: There you go:
var mouse_released = 0;
function check_release() { while (mouse_left) {wait (1);} // wait until the player releases the left mouse button mouse_released = 1; wait (-1); mouse_released = 0; }
function release_startup() { on_mouse_left = check_release; }
PANEL* test_pan = { layer = 15; digits(200, 20, 1.0 ,* , 1, mouse_released); flags = SHOW; }
Q: Where can I change the height of the eyes of the player (camera) in the shooter template code? A: You need to change "var t_disttoground = 64;" in the t_player.c script.
Q: I need a door that opens when a bullet is fired at it, not just when the player runs into it. Can you help? A: Here's a quick example:
function open_door() { if (event_type == EVENT_IMPACT) { my.event = NULL; // don't trigger other events from now on // make sure to add "player = my;" in player's action while (my.z < 300) // play with this value { my.z += 2 * time_step; wait (1); } } }
action my_door() { my.emask |= ENABLE_IMPACT; my.event = open_door; }
Q: How can I make a flying camera that can go anywhere in the level, but doesn't pass through other entities? A: Here's a smooth camera code snippet that uses the shooter template camera as a base:
var camera_speed = 5; // camera movement speed var fwdbk_accel = 3; // camera forward / backward acceleration var side_accel = 2; // camera sideway (strafe) acceleration var friction = 1.5; // camera friction - this value should always be greater than 1 var camera_h = 8; // horizontal camera acceleration var camera_h_frict = 0.95; // always use a value below 1 here var camera_v = 8; // vertical camera acceleration var camera_v_frict = 0.8; // always use a value below 1 here var camera_h_speed = 0; var camera_v_speed = 0;
action flying_camera() { set (my, INVISIBLE); // using a 1st person player var forward_on, backward_on, right_on, left_on, jump_on, run_on; VECTOR horizontal_speed, vertical_speed, temp; vec_set(horizontal_speed.x, nullvector); // initialize this vector vec_set(vertical_speed.x, nullvector); // initialize this vector while(1) { // accelerate camera's pan and tilt angles depending on mouse_force.x and mouse_force.y in order to create a smooth camera my.pan -= accelerate (camera_h_speed, camera_h * (mouse_force.x), camera_h_frict); my.tilt += accelerate (camera_v_speed, camera_v * (mouse_force.y), camera_v_frict); my.tilt = clamp(my.tilt, -90, 90); // limit the tilt angle of the camera to -90... 90 degrees vec_set(camera.x, my.x); camera.pan = my.pan; camera.tilt = my.tilt; // player's horizontal speed (forward / backward / sideways) movement uses acceleration and friction as well horizontal_speed.x = (horizontal_speed.x > 0) * maxv(horizontal_speed.x - time_step * friction, 0) + (horizontal_speed.x < 0) * minv(horizontal_speed.x + time_step * friction, 0); if(key_w) { horizontal_speed.x += time_step * fwdbk_accel; horizontal_speed.x = minv(horizontal_speed.x, time_step * camera_speed * (1 + run_on)); } if(key_s) { horizontal_speed.x -= time_step * fwdbk_accel; horizontal_speed.x = maxv(horizontal_speed.x, -(time_step * camera_speed * (1 + run_on))); } horizontal_speed.y = (horizontal_speed.y > 0) * maxv(horizontal_speed.y - time_step * friction, 0) + (horizontal_speed.y < 0) * minv(horizontal_speed.y + time_step * friction, 0); if(key_s) { horizontal_speed.y += time_step * side_accel; horizontal_speed.y = minv(horizontal_speed.y, time_step * camera_speed * (1 + run_on)); } if(key_d) { horizontal_speed.y -= time_step * side_accel; horizontal_speed.y = maxv(horizontal_speed.y, -(time_step * camera_speed * (1 + run_on))); } // disable the friction, allow smooth gliding along the surfaces move_friction = 0; vec_set(temp.x, my.x); c_move (my, horizontal_speed.x , NULLVECTOR, IGNORE_PASSABLE | GLIDE); wait(1); } }
Q: How can I check if the enemy can see the player? I have tried to use c_trace, but it always returns a positive number, even if there are no obstacles between the player and the enemy. A: You can also use c_scan to detect the player; in fact, due to the cone vision scan, this is an even better solution, because it is similar with the way in which a real opponent would react.
var temp_bullets = 0;
VECTOR temp_angle;
STRING* bullet_mdl = "bullet.mdl";
function init_startup() { fps_max = 100; // limit the frame rate to 100 frames per second }
function remove_bullets() // this function runs when the bullet collides with something { set(my, PASSABLE); 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; // 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); } }
function fire_bullets() { temp_bullets += 1; if ((temp_bullets % 100) == 1) // create the bullet at the enemy's position and attach it the "move_bullets" function ent_create (bullet_mdl, my.x, move_bullets); }
action my_enemy() // attach this action to your enemies, add your enemy movement code { // make sure that the player action includes the "player = my;" line of code while (!player) {wait (1);} // wait until the player model is loaded while (1) { // the enemy will "see" the player if it is in front of it, up to 1000 quants away // 120 sets the enemy's horizontal viewing angle, 90 sets the vertical viewing angle, play with these values if ((c_scan(my.x, my.pan, vector(120, 90, 1000), IGNORE_ME) > 0) && (you == player)) { vec_set(temp_angle, player.x); vec_sub(temp_angle, my.x); vec_to_angle(my.pan, temp_angle); my.tilt = 0; // the enemy has rotated towards the player here fire_bullets(); } wait (1); } }
|