Fragen aus dem Forum

Top  Previous  Next

Q: Ich möchte, dass sich eine Kugel selbst zerstört wenn sie auf eine Wand trifft. Das klingt leicht aber ich habe es nicht geschafft, das hinzukriegen.

A: Nehmen Sie den Code unten:

 

SOUND* bullet_wav = "bullet.wav";

 

function remove_bullets() // this function runs when the bullet collides with the wall

{

       wait (1); // wait a frame to be sure (don't trigger engine warnings)

       my.event = NULL; // don't trigger bullet events (for this bullet) anymore

       ent_playsound(my, bullet_wav, 2000);

       set (my, INVISIBLE); // hide the bullet

       wait (-1); // give the sound enough time to be played

       ent_remove (my); // and then remove the bullet

}

 

function move_bullets()

{

       VECTOR bullet_speed[3]; // stores the speed of the bullet

       // the bullet is sensitive to impacts with entities and 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 and tilt angles with its creator

       my.tilt = you.tilt;

       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

       while (my) // this loop will run for as long as the bullet exists (it isn't "NULL")

       {

               // move the bullet ignoring its creator (the bullet generator)

               c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU);

               wait (1);

       }

}

 

action bullet_generator()

{

       VECTOR bullet_pos[3];

       while (1)

       {

               // generate bullets from the 108th vertex of the weapon (get the vertex number from Med)

               vec_for_vertex(bullet_pos, my, 108);

               ent_create("bullet.mdl", bullet_pos, move_bullets);

               wait (-2); // fire a bullet every 2 seconds

       }

}

 

Q: Ich habe eine Plattform gemacht (wmb) und das Skript, das sie antreibt. Der Player fällt aber hindurch. Gibt es irgendeinen Code, den ich dem Lift-Skript hinzufügen kann, so dass der Player auf dem Lift bleibt und sich mit ihm mitbewegt?

A: Auch Ihr Player-Code muß geändert werden. Hier ein Beispiel eines Player- und Lift-Codes, der gut funktioniert.

 

ENTITY* lift1;

 

action players_code() // attach this action to your player

{

       player = my; // I'm the player

       while (!lift1) {wait (1);} // wait until the lift entity is loaded

       var movement_speed = 20; // movement speed

       var distance_to_ground;

       VECTOR temp;

       set (my, INVISIBLE); // 1st person player

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1

               camera.pan = my.pan;

               camera.tilt += 5 * mouse_force.y * time_step;

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               distance_to_ground = c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | SCAN_TEXTURE);

               // replace "elevator1" with the name of the texture that is used by your lift

               if (str_cmpi(tex_name, "elevator1")) // the player is using the lift?

               {

                       my.z = lift1.z + 100; // play with 100

               }

               else // the player isn't using the lift? Then keep its feet on the ground

               {

                       temp.z = -distance_to_ground + 20; // play with 20

               }

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

               wait (1);

       }

}

 

action my_lift() // attach this action to your lift

{

       lift1 = my;

       while (!player) {wait (1);} // wait until the player entity is loaded

       var init_z;        

       var max_height = 200; // the lift can move upwards for up to 200 quants

       init_z = my.z; // store the initial height of the lift

       while (1)

       {

               while (my.z < init_z + max_height)

               {

                       my.z += 5 * time_step;

                       wait (1);

               }

               wait (-3); // wait 3 seconds at the top

               while (my.z > init_z)

               {

                       my.z -= 5 * time_step;

                       wait (1);

               }

               wait (-5); // wait 5 seconds at the bottom

       }

}

 

 

Q: Wie kann ich den Pan-Winkel des Players in Abhängigkeit der Mausposition verändern?

A: Bitteschön:

 

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

       }

}

 

action players_code()

{

       VECTOR temp, temp2;

       player = my; // I'm the player

       while (1)

       {

               temp.x = mouse_pos.x;

               temp.y = mouse_pos.y;

               temp.z = 2000;

               // create a position 2000 quants below the camera (not a critical value)

               vec_for_screen(temp, camera);

               vec_set(temp2, temp.x);

               vec_sub(temp2, my.x);

               vec_to_angle(my.pan, temp2); // player's pan points towards the mouse pointer here

               my.tilt = 0; // don't change player's tilt angle, though

               // put your own player movement code here

               wait (1);

       }        

}

 

aum87_faq1

 

 

Q: Ich habe versucht, ein Hintergrundbild zu machen, das sich nicht bewegt. Die Kamera ist fixiert. Wie kann ich ein Bild von 512 x 256 Pixeln so verwenden, dass es die ganze Zeit hinter allem und von 0,0 auf 1024,768 gedehnt ist?

A: Platzieren Sie das Bild hinter sämtlichen Entities Ihres Levels, genauso wie Sie ein reguläres Sprite platzieren würden. Dann spielen Sie solange mit seiner Position und der Skalierung, bis es den gesamten Bildschirm füllt.

 

action background_picture()

{        

       // the background picture is passable and doesn't get blurred

       set (my, PASSABLE | NOFILTER);

       my.pan = 0.1; // don't allow the sprite to rotate with the camera

       my.scale_x = 2; // play with this value, it sets the scale on the x axis

       my.scale_y = 3.5; // play with this value, it sets the scale on the y axis

}

 

 

Q: Ich hätte gerne, dass meine Entities ihre Animationen stoppen wenn sie auf dem Bildschirm nicht sichtbar sind.

A: Nehmen Sie dieses Beispiel:

 

action my_cow()

{        

var anim_percentage = 0;

set(my, POLYGON);                

while(1)

{

               // the cow is visible on the screen? Then play its animation!

               if (!(my.eflags & CLIPPED))

               {

                       ent_animate(my, "eatgrass", anim_percentage, NULL);                                

                       anim_percentage += 2 * time_step;

                       anim_percentage %= 100;

               }

               else // the cow isn't visible on the screen here, so do something else if needed

               {

                       // beep();

               }

     wait (1);

       }        

}

 

 

Q: Ich versuche, eine Waffe zu erstellen, die, wenn ich die linke Maustaste drücke, Kugeln abschießt, es dem Player aber nicht erlaubt, eine neue Kugel abzuschießen ehe die "shoot"-Animation zu 100% abgelaufen ist.

A: Verwenden Sie den Code unten:

 

var gun_firing = 0;

 

ENTITY* weapon1;

 

SOUND* fire_wav = "fire.wav";

 

function attach_weapon1()

{

       weapon1 = my; // I'm the gun

       set(my, PASSABLE);

       while (1)

       {

               vec_set (my.x, vector (20, -10, 35)); // set the proper gun offset in relation to the player

               vec_rotate (my.x, you.pan);

               vec_add (my.x, you.x);

               my.pan = you.pan;

               my.tilt = camera.tilt;

               wait (1);

       }

}

 

action players_code() // simple player and 1st person camera code

{

       player = my; // I'm the player

       ent_create ("gun1.mdl", nullvector, attach_weapon1);

       while (1)

       {

               // move the player using the "W", "S", "A" and "D" keys; "10" = movement speed, "6" = strafing speed

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x); // use player's x and y for the camera as well

               camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level)

               camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse

               camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis

               player.pan = camera.pan; // the camera and the player have the same pan angle

               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

}

 

function move_bullets()

{

       VECTOR bullet_speed[3]; // stores the speed of the bullet

       // the bullet is sensitive to impacts with entities and 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 = weapon1.pan;

       my.tilt = weapon1.tilt;

       bullet_speed.x = 150 * 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

       while (my) // this loop will run for as long as the bullet exists (it isn't "NULL")

       {

               // move the bullet ignoring its creator (weapon1)

               c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU);

               wait (1);

       }

}

 

function fire_bullets()

{

       if (gun_firing)

               return; // don't allow the player to fire until the previous "shot" animation has finished

       snd_play(fire_wav, 100, 0);

       gun_firing = 1;

       VECTOR bullet_pos[3];

       var anim_factor = 0;

       // generate bullets from the 952th vertex of the weapon (get the vertex number from Med)

       vec_for_vertex(bullet_pos, weapon1, 952);

       while (anim_factor < 70) // the gun fires the bullet at 70% of its animation - play with 70

       {

               ent_animate(weapon1, "shot", anim_factor, NULL);                                

               anim_factor += 7 * time_step;

               wait (1);

       }

       ent_create("bullet.mdl", bullet_pos, move_bullets);

       while (anim_factor < 100) // continue with the rest of the "shot" animation

       {

               ent_animate(weapon1, "shot", anim_factor, NULL);                                

               anim_factor += 6 * time_step;

               wait (1);

       }

       gun_firing = 0; // allow the gun to fire again

}

 

function bullets_startup()

{

       on_mouse_left = fire_bullets;

}

 

 

Q: In den A5-Templates gab es eine Funktion namens msg_show(), die, wenn sie wie folgt aufgerufen wird, eine Nachricht anzeigt: msg_show("I AM AWESOME"); Ich frage mich, ob jemand eine neue Version erstellen könnte, die gebitmappte Fonts benutzt.

A: Hier ist sie:

 

STRING* message_str = "#100"; // the message can have up to 100 characters

 

FONT* cool_font = "antique.tga";

 

SOUND* message_wav = "message.wav";

 

function msg_show(STRING* message, duration);

 

TEXT* message_txt =

{

       pos_x = 200;

       pos_y = 20;

       string(message_str);

       font(cool_font);

       flags = SHOW;

}

 

function msg_show(STRING* message, duration)

{

       str_cpy((message_txt.pstring)[0], message);

       message_txt.flags |= SHOW; // display the message

       snd_play(message_wav, 70, 0);

       wait (-duration); // for the specified number of seconds

       message_txt.flags &= ~SHOW; // and then hide the message

}

 

function messages_startup()

{

       wait (-7);

       msg_show("I AM AWESOME", 3);

       wait (-5);

       msg_show("or at least cool", 2);

       wait (-4);

       msg_show("or maybe just a regular guy", 4);

       wait (-6);

       msg_show("OK, OK, I'm a bit dumb...", 5);

}

 

aum87_faq2

 

 

Q: Ich brauche Hilfe beim Erstellen eines Countdown-Timers, der läuft während er Player rennt und wenn der Timer <= 0, kann der Player nicht mehr laufen. Auch muß der Timer sich aufladen lassen, so dass der Player wieder neu rennen kann.

A: Nehmen Sie dieses Beispiel:

 

var countdown_timer = 10;

 

SOUND* gottime_wav = "gottime.wav";

 

action players_code() // attach this action to your player

{

       var movement_speed = 20; // movement speed

       VECTOR temp;

       set (my, INVISIBLE); // 1st person player

       player = my; // I'm the player

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1

               camera.pan = my.pan;

               camera.tilt = player.tilt; //5 * mouse_force.y * time_step;

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 2

               temp.x = movement_speed * (key_w - key_s) * time_step;

               temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step;

               if (countdown_timer > 0) // the countdown time didn't reach zero?

               {

                       temp.x *= 2; // increase the forward movement speed with 100%

                       temp.y *= 1.5; // increase the sideway movement speed with 50%

               }

               c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE);

               wait (1);

       }

}

 

action get_time() // attach this action to the time powerups that can be picked up by the player

{

       set (my, PASSABLE);

       while (!player) {wait (1);} // wait until the player model is loaded

       while (vec_dist (player.x, my.x) > 50) {wait (1);}

       snd_play(gottime_wav, 100, 0);

       set (my, INVISIBLE);

       countdown_timer += 10;

       wait (-2);

       ent_remove(my);

}

 

function countdown_startup()

{

       while (1)

       {

               countdown_timer -= time_step / 16;

               countdown_timer = maxv(countdown_timer, 0); // don't allow the timer to go below zero

               wait (1);

       }

}

 

PANEL* time_pan =

{

       layer = 15;

       digits(20, 20, 4 ,* , 1, countdown_timer);

       flags = SHOW;

}

 

 

Q: Weiß irgendjemand wie ich Stützen machen kann, die nur dann anmimiert sind, wenn sie zerstört werden?

A: Verwenden Sie das folgende Schnipselchen. Die Kisten / Fässer werden nur dann zerstört und explodieren, nachdem sie 3 mal angeschossen wurden.

 

var gun_firing = 0;

 

ENTITY* weapon1;

 

SOUND* fire_wav = "fire.wav";

 

function attach_weapon1()

{

       weapon1 = my; // I'm the gun

       set(my, PASSABLE);

       while (1)

       {

               vec_set (my.x, vector (20, -10, 35)); // set the proper gun offset in relation to the player

               vec_rotate (my.x, you.pan);

               vec_add (my.x, you.x);

               my.pan = you.pan;

               my.tilt = camera.tilt;

               wait (1);

       }

}

 

action players_code() // simple player and 1st person camera code

{

       player = my; // I'm the player

       ent_create ("gun1.mdl", nullvector, attach_weapon1);

       while (1)

       {

               // move the player using the "W", "S", "A" and "D" keys; "10" = movement speed, "6" = strafing speed

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x); // use player's x and y for the camera as well

               camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level)

               camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse

               camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis

               player.pan = camera.pan; // the camera and the player have the same pan angle

               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

}

 

function move_bullets()

{

       my.skill99 = 1357; // uniquely identify a bullet

       VECTOR bullet_speed[3]; // stores the speed of the bullet

       // the bullet is sensitive to impacts with entities and 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 = weapon1.pan;

       my.tilt = weapon1.tilt;

       bullet_speed.x = 150 * 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

       while (my) // this loop will run for as long as the bullet exists (it isn't "NULL")

       {

               // move the bullet ignoring its creator (weapon1)

               c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE | IGNORE_YOU);

               wait (1);

       }

}

 

function fire_bullets()

{

       if (gun_firing)

               return; // don't allow the player to fire until the previous "shot" animation has finished

       snd_play(fire_wav, 100, 0);

       gun_firing = 1;

       VECTOR bullet_pos[3];

       var anim_factor = 0;

       // generate bullets from the 952th vertex of the weapon (get the vertex number from Med)

       vec_for_vertex(bullet_pos, weapon1, 952);

       while (anim_factor < 70) // the gun fires the bullet at 70% of its animation - play with 70

       {

               ent_animate(weapon1, "shot", anim_factor, NULL);                                

               anim_factor += 7 * time_step;

               wait (1);

       }

       ent_create("bullet.mdl", bullet_pos, move_bullets);

       while (anim_factor < 100) // continue with the rest of the "shot" animation

       {

               ent_animate(weapon1, "shot", anim_factor, NULL);                                

               anim_factor += 6 * time_step;

               wait (1);

       }

       gun_firing = 0; // allow the gun to fire again

}

 

function bullets_startup()

{

       on_mouse_left = fire_bullets;

}

 

// destroyable crate / barrel code from here on

 

function explo_sprite()

{

       set(my, BRIGHT);

       my.alpha = 100;

       my.scale_x = 3; // this value gives the scale of the explosion sprite

       my.scale_y = my.scale_x;

       my.frame = 1;

       while (my.frame < 5)

       {

               my.frame += 0.5 * time_step;

               wait (1);

       }

       while (my.alpha > 0)

       {

               my.alpha -= 3 * time_step;

               wait (1);

       }

       ent_remove (my);

}

 

function destroy_crate()

{

       // don't do anything if the crate wasn't destroyed by one of player's bullets

       // we have set skill99 to 1357 for each bullet inside function move_bullets() - above

       if (you.skill99 != 1357)        

               return;

       my.skill1 -= 1;

}

 

action my_crate()

{

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY);

       my.event = destroy_crate;

       my.skill1 = 3; // allow the

       while (my.skill1 > 1) {wait (1);}

       // the crate was shot 3 times here

       ent_create("explo+5.pcx", my.x, explo_sprite);

       my.alpha = 100;

       set (my, TRANSLUCENT);

       while (my.alpha > 0)

       {

               my.alpha -= 7 * time_step;

               wait (1);

       }

       ent_remove (my); // and then remove the crate

}

 

 

Q: hat Irgendjemand eine Idee wie man eine Entity implementiert, die durch einen Tunnel geht und aus einem anderen Tunnel herauskommt? Es ist wie ein Portal in Quake 3 wenn der Player das Portal betritt, kommt er irgendwo anders in der Map wieder heraus.

A: Nehmen Sie dieses Beispiel als Grundlage für Ihren Code:

 

ENTITY* beamer1;

ENTITY* beamer2;

 

action players_code() // attach this action to your player

{

       var movement_speed = 20; // movement speed

       VECTOR temp;

       set (my, INVISIBLE); // 1st person player

       player = my; // I'm the player

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1

               camera.pan = my.pan;

               camera.tilt = player.tilt; //5 * mouse_force.y * time_step;

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 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);

               wait (1);

       }

}

 

function beam_me1()

{

       my.event = NULL; // don't trigger several events

       wait (1);

       set (beamer2, PASSABLE); // don't allow beamer2 to teleport the player back to beamer1

       vec_set(player.x, beamer2.x);

       my.event = beam_me1;

}

 

action portal1() // attach this action to the first portal

{

       beamer1 = my;

       while (!player) {wait (1);}

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY);

       while (1)

       {

               if (vec_dist(player.x, my.x) < 10) // the player was just beamed here?

               {

                       set (my, PASSABLE);

                       my.event = NULL; // then don't allow this beamer to teleport it back

                       // wait until the player has moved away from this beamer

                       while (vec_dist (my.x, player.x) < 100) {wait (1);}

               }        

               else

               {

                       reset (my, PASSABLE);

                       my.event = beam_me1;

               }

               wait (1);

       }

}

 

function beam_me2()

{

       my.event = NULL; // don't trigger several events

       wait (1);

       set (beamer1, PASSABLE); // don't allow beamer1 to teleport the player back to beamer2

       vec_set(player.x, beamer1.x);

       my.event = beam_me2;

}

 

action portal2() // attach this action to the second portal

{

       beamer2 = my;

       while (!player) {wait (1);}

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY);

       while (1)

       {

               if (vec_dist(player.x, my.x) < 10) // the player was just beamed here?

               {

                       set (my, PASSABLE);

                       my.event = NULL; // then don't allow this beamer to teleport it back

                       // wait until the player has moved away from this beamer

                       while (vec_dist (my.x, player.x) < 100) {wait (1);}

               }        

               else

               {

                       reset (my, PASSABLE);

                       my.event = beam_me2;

               }

               wait (1);

       }

}