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.

 

aum115_faq1

 

 

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);

       }

}