Q:
I'd like to be able to rotate the camera around a specific entity
(the target) when I press the left and right keys on my keyboard. Up
and down should take
me closer or farther to the target. Can you help?
A:
Attach the action below to the target entity.
entity* mytarget;
action my_target // attach it to the target entity
{
mytarget = my;
}
starter chase_target()
{
var distance_to_target = 300; // initial distance to target
var temp_angle = 50; // initial angle
while (mytarget == null) {wait (1);}
while (1)
{
camera.x = mytarget.x + distance_to_target *
cos(temp_angle);
camera.y = mytarget.y + distance_to_target *
sin(temp_angle);
camera.z = mytarget.z;
vec_set (temp, mytarget.x);
vec_sub (temp, camera.x);
vec_to_angle (camera.pan, temp);
if ((key_cuu == on) && (distance_to_target > 100))
{
distance_to_target -= 7 * time;
// come closer to the target
}
if ((key_cud == on) && (distance_to_target < 500))
{
distance_to_target += 7 * time; //
get away from the target
}
if (key_cul == on)
{
temp_angle -= 5 * time;
}
if (key_cur == on)
{
temp_angle += 5 * time;
}
wait (1);
}
}
Q: How
do they do the movement in games like Prince of Persia? The prince is grabbing
onto poles and swinging around; how do they make sure that the hands
are
placed perfectly
on the pole every time, even if the distance you jumped from wasn't the same
every time?
A: You can use a simple method if you want to achieve
similar results: compute the distance between the player and the pole and
adjust the jumping speed and the animation frames depending on that
distance. As an example, if the distance between the player and the pole
is 100 quants, move it with 10 * time and animate it with 5 * time. If the
distance is 70 quants, move it with 7 * time and animate it with 5 * (100
/ 70) * time.
Q:
If I would kick a box, how would I program it so that
it moves in the opposite direction without losing its original
pan and tilt
angles?
A:
Use the code below. Run into the box to move it.
function move_boxes()
{
vec_rotate (vector(2 * (my.x - player.x) * time, 0, 0), player.pan);
vec_add (my.x, vector(2 * (my.x - player.x) * time, 2 * (my.y - player.y)
* time,
0));
}
action my_box
{
while (player == null) {wait (1);}
my.enable_impact = on;
my.enable_entity = on;
my.event = move_boxes;
}
Q:
I want to create an inventory panel with four guns;
the pcx image won't show up until I have picked up the corresponding
weapon. Can you help?
A:
Take a look at the example below and expand it for as many guns as you need:
bmap
weapon1_pcx = <weapon1.pcx>;
bmap weapon2_pcx = <weapon2.pcx>;
var got_weapon1 = 0;
var got_weapon2 = 0;
panel weapon1_pan
{
bmap = weapon1_pcx;
layer = 20;
pos_x = 0;
pos_y = 0;
flags = overlay, refresh;
}
panel weapon2_pan
{
bmap = weapon2_pcx;
layer = 20;
pos_x = 50;
pos_y = 0;
flags = overlay, refresh;
}
starter check_weapon_status()
{
while (1)
{
if (got_weapon1 == 1) // got weapon1?
{
weapon1_pan.visible = on;
}
else
{
weapon1_pan.visible = off;
}
if (got_weapon2 == 1) // got weapon2?
{
weapon2_pan.visible = on;
}
else
{
weapon2_pan.visible = off;
}
wait (1);
}
}
action weapon_first // attach it to the first weapon
{
my.passable = on;
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 50)
{
my.pan += 5 * time;
wait (1);
}
got_weapon1 = 1;
my.invisible = on;
// put the rest of your weapon code here
}
action weapon_second // attach it to the second weapon
{
my.passable = on;
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 50)
{
my.pan += 5 * time;
wait (1);
}
got_weapon2 = 1;
my.invisible = on;
// put the rest of your weapon code here
}
Q:
How can I create a splash screen that pops up before loading a level
and disappears after a key is hit? The code should work for several
levels.
A: Use the code below as an example.
bmap splash_pcx = <splash.pcx>;
panel splash_pan
{
bmap = splash_pcx;
pos_x = 0;
pos_y = 0;
layer = 1;
flags = overlay, refresh;
}
action level1_level2 // attach this action to any entity placed at the end
of the first level
{
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 50) {wait (1);}
while (key_any == on) {wait (1);} // wait until all the keys are
released
my = null;
level_load(level2_wmb);
freeze_mode = 1; // stop all the entities in the level
splash_pan.visible = on;
while (key_any == off) {wait (1);}
splash_pan.visible = off;
freeze_mode = 0; // resume the gameplay
}
action level2_level3 // attach this action to any entity placed at the end
of the second level
{
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 50) {wait (1);}
while (key_any == on) {wait (1);} // wait until all the keys are
released
my = null;
level_load(level3_wmb);
splash_pan.visible = on;
while (key_any == off) {wait (1);}
splash_pan.visible = off;
}
Q:
In
some games, if there is an object that should be picked up or examined,
the player will turn its head as you move near the object. How can
we do that?
A:
Paste the code below at the end of your main script file:
entity* special;
function rotate_entity (active, passive, panspeed, tiltspeed);
function rotate_entity (active, passive, panspeed, tiltspeed)
{
var target_pan;
my = active;
you = passive;
vec_set (temp, your.x);
vec_sub (temp, my.x);
vec_to_angle (target_pan, temp);
temp.pan = ang (target_pan - my.pan);
target_pan = my.pan + temp.pan;
if( my.pan < target_pan)
{
while(my.pan < target_pan)
{
my.pan += panspeed.pan * time;
if (my.tilt > target_pan.tilt)
{
my.tilt
-= tiltspeed * time;
}
if (my.tilt < target_pan.tilt)
{
my.tilt
+= tiltspeed * time;
}
wait(1);
}
}
else
{
while(my.pan >= target_pan)
{
my.pan -= panspeed.pan * time;
if (my.tilt > target_pan.tilt)
{
my.tilt
-= tiltspeed * time;
}
if (my.tilt < target_pan.tilt)
{
my.tilt
+= tiltspeed * time;
}
wait(1);
}
}
}
action special_object
{
special = my;
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 200) {wait (1);}
while (vec_dist (player.x, my.x) <= 200)
{
rotate_entity (player, special, 0.1, 0);
wait (1);
}
}
Q:
I have a problem scripting the movement of a spacecraft that can
go forward and make turns (it's a 2D game). I need the ship to 'slide' in
turns, just like a
car riding on ice. Can you
help?
A: Use this snippet:
starter set_camera()
{
sleep (1); // wait until the level is loaded
camera.x = 0;
camera.y = 0;
camera.z = 1000;
camera.tilt = -90;
}
action asteroids_ship
{
var ship_speed;
while (1)
{
if (key_cuu == on)
{
if (ship_speed.x < 2)
{
ship_speed.x
+= 0.3 * time;
}
}
else
{
if (ship_speed.x >= 0)
{
ship_speed.x
-= 0.05 * time;
}
}
if (ship_speed.x < 0) {ship_speed.x = 0;}
if (key_cul == on)
{
my.pan += 3 * time;
}
if (key_cur == on)
{
my.pan -= 3 * time;
}
ent_move (ship_speed.x, nullvector);
wait (1);
}
}

Q:
I use your "intelligent music" snippet from Aum38. How could I
assign that action to as many entities as I want without having each
of them playing their own instance?
A: Use the example below; it
plays "gentle.wav" when the player comes closer than 500 quants,
"tense.wav" when the player is closer than 100 quants and fades the
music out when the player moves farther than 600 quants to the entity.
action music_trigger
{
// my.invisible = on; // remove the comment when you've chosen the best
position
for the entity
my.passable = on;
while (player == null) {wait (1);}
while (vec_dist (player.x, my.x) > 500) {wait (1);} // play with "500"
music_handle = snd_loop (gentle_wav, 50, 0); // play the "gentle" sound
track
while (vec_dist (player.x, my.x) > 100) {wait (1);} // play with "100"
temp_volume = 50; // put the same value that was used for snd_loop here
while (temp_volume > 5) // decrease the volume slowly
{
snd_tune (music_handle, temp_volume, 0, 0);
temp_volume -= 1 * time;
wait (1);
}
snd_stop (music_handle); // stop "gentle.wav";
music_handle = snd_loop (tense_wav, 50, 0); // play the "tense" sound
track
while (vec_dist (player.x, my.x) < 600) {wait (1);} // play with "600"
temp_volume = 50;
while (temp_volume > 5) // decrease the volume slowly
{
snd_tune (music_handle, temp_volume, 0, 0);
temp_volume -= 1 * time;
wait (1);
}
snd_stop (music_handle); // stop "tense.wav";
}
Q: Can
you attach a typing sound to inkey somehow or do you have to write a
new input function?
A: All the key_... functions
(including key_any and on_anykey) are inactive during keyboard
entry. However, you can write
a simple input function using key_pressed and str_cat.