Fragen aus dem Forum

Top  Previous  Next

F: Ist es möglich, im laufenden Level einen Film einzublenden, wenn der Spieler nahe an eine gewisse Entity kommt (dem Ausgang)?

A: Sicher, sehen Sie sich den Code unten an.

 

// attach this action to a sprite that has the same size with your movie

action movie_gate()

{

       // wait until the player entity is loaded in the level

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

       // wait until the player comes close to the exit gate

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

       // now play the movie file

       media_play("mymovie.avi", bmap_for_entity (my, 0), 100); // use your own movie name here

}

 

aum80_faq1

 

 

F: Wie kann ich mit lite-C zufällige Passwörter generieren?

A: Hier ist ein Beispiel.

 

var password_length = 8; // generate passwords that contain 8 characters, play with this number

 

STRING* password_str = "#30"; // stores passwords with up to 30 characters

STRING* temp_str = " ";

 

FONT* arial_font = "Arial#20";

 

TEXT* password_txt =

{

       pos_x = 20;

       pos_y = 20;

       font = arial_font;

       string(password_str);

       flags = VISIBLE;

}

 

// press any key to generate a new password

function passwords_startup()

{

       var i, temp;

       randomize();

       while (1)

       {

               while (key_any) {wait (1);} // wait until all the keys are released

               while (!key_any) {wait (1);} // wait until a key is pressed

               str_cpy(password_str, "#30"); // reset password_str

               i = 0;

               while (i < password_length) // generate a number of 8 characters for our password

               {

                       // generate a random ascii code (visible, printable characters only)

                       temp = integer(random(95)) + 32;

                       str_for_asc(temp_str, temp); // convert the random number to its string equivalent

                       str_cat(password_str, temp_str);

                       i++;

               }

       }

}

 

 

F: Ich möchte einen 2D Arkanoid Klon schreiben, möchte aber nicht über hundert Panels definieren. Gibt es einen einfacheren Weg?

A: Verwenden Sie pan_create, um Ihre Panel einfach zu erstellen und zu plazieren.

 

PANEL* temp_pan;

 

// these numerical values work fine for a screen resolution of 800 x 600 pixels

function aliens_startup()

{

       var temp1 = 30; // temp1 gives the coordinates of the first brick on the x axis

       var temp2 = 20; // temp2 gives the coordinates of the first brick on the y axis

       // create rows of bricks until their y exceeds 300

       while (temp2 < 300)

       {

               // generate bricks until their x exceeds 760

               while (temp1 < 760)

               {

                       // block.pcx has 32 x 16 pixels in my example, but you can use any other size for the bitmap

                       temp_pan = pan_create("bmap = block.pcx; flags = overlay, visible;", 10);

                       temp_pan.pos_x = temp1;

                       temp_pan.pos_y = temp2;

                       temp1 += 50;

               }

               temp1 = 30;

               temp2 += 40;

       }

}

 

aum80_faq2

 

 

F: Mein Spieler Model hat 3 Animationen: "walk", "stand" und "look". Ich möchte, dass "walk" gezeigt wird, wenn die Bewegungstasten gedrückt sind, "stand" wenn der Spieler sich nicht bewegt und "look" nach einer längeren Phase der Inaktivität. Wie kann ich das erreichen?

A: Verwenden Sie dieses Spieler / Kamera Beispiel als Grundlage für Ihren Code.

 

action players_code()

{

       VECTOR temp[3];

       VECTOR movement_speed[3]; // player's movement speed

       var anim_percentage; // animation percentage

       var distance_to_ground;

       var time_passed = 0;

       player = my; // I'm the player

       while (1)

       {

               my.pan += 6 * (key_a - key_d) * time_step; // rotate the player using the "A" and "D" keys

               vec_set (temp.x, my.x); // copy player's position to temp

               temp.z -= 10000; // set temp.z 10000 quants below player's origin

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

               movement_speed.x = 5 * (key_w - key_s) * time_step; // move the player using "W" and "S"

               movement_speed.y = 0; // don't move sideways

               movement_speed.z = -(distance_to_ground - 20); // 20 = experimental value

               c_move (my, movement_speed.x, nullvector, GLIDE); // move the player

               if (!key_w && !key_s) // the player isn't moving?

               {

                       time_passed += time_step / 16; // add "1" to time_passed every second

                       if (time_passed >= 20) // at least 20 seconds have passed?

                       {

                               anim_percentage += 3 * time_step; // 3 = "look" animation speed

                               ent_animate(my, "look", anim_percentage, ANM_CYCLE); // then play the "look" animation

                       }

                       else // the player is standing

                       {

                               anim_percentage += 2 * time_step; // 2 = "stand" animation speed

                               ent_animate(my, "stand", anim_percentage, ANM_CYCLE);

                       }

               }

               else // the player is moving?

            {

                       time_passed = 0;

                    ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation

                       anim_percentage += 5 * time_step; // 5 = "walk" animation speed

               }

               // camera code

               camera.x = player.x - 250 * cos(player.pan);

               camera.y = player.y - 250 * sin(player.pan); // use the same value (250) here

               camera.z = player.z + 150; // place the camera above the player, play with this value

               camera.tilt = -20; // look down at the player

               camera.pan = player.pan;

               wait (1);

       }

}

 

 

F: Ich möchte, dass mein NPC sich von A nach B bewegt und dabei an gewissen Punkten des Pfades für eine festgelegte Zahl an Sekunden stehenbleibt und wartet. Wie kann ich das erreichen?

A: Plazieren Sie Ihren NPC im Level und geben Sie ihm die Action "patroller". Erstellen Sie einen virtuellen Pfad von A nach B mit kleinen Entities, geben Sie diesen die Action "target_init" und setzen Sie ggf. deren skill1 auf die Wartezeit in Sekunden.

 

ENTITY* my_target;

 

action patroller()

{

       VECTOR temp[3];

       while (1)

       {

               // scan for camera positions that are placed up to 1000 quants away from this entity

               c_scan(my.x, my.pan, vector(360, 60, 1000), IGNORE_ME | SCAN_ENTS | SCAN_LIMIT);

               if (you) // a target was detected?

               {

                       my_target = you; // the closest position to the npc is set to "you" by c_scan

                       my_target.scale_z = 4;

                       vec_set(temp, my_target.x);

                       vec_sub(temp, my.x);

                       vec_to_angle(my.pan, temp); // rotate the patroller towards the position

                       my.tilt = 0; // but don't allow it to change its tilt angle

                       // the patroller looks at its target now

                       while (vec_dist (my.x, my_target.x) > 50) // the patroller moves until it comes close to the target

                       {

                               my.skill22 += 5 * time_step; // 5 gives the "walk" animation speed

                               c_move(my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); // 5 = movement speed

                               ent_animate(my, "walk", my.skill22, ANM_CYCLE);

                               wait (1);

                       }

                       // the patroller has come close to target here

                       my.skill99 = 0;

                       while (my.skill99 < my_target.skill1)

                       {

                               my.skill99 += time_step / 16;

                               ent_animate(my, "stand", my.skill22, ANM_CYCLE);

                               my.skill22 += 3 * time_step; // 3 gives the "stand" animation speed

                               wait (1);

                       }

                       ent_remove(my_target); // remove the current target and prepare for the following target

               }

               else // reached the end of the path?

               {

                       ent_animate(my, "stand", my.skill22, ANM_CYCLE); // then default to standing

                       my.skill22 += 3 * time_step; // 3 gives the "stand" animation speed

               }

               wait (1);

       }

}

 

action target_init()

{

       set (my, PASSABLE | INVISIBLE); // player's movement code should ignore passable entities

       my.emask |= ENABLE_SCAN; // the target entity is sensitive to c_scan instructions

}

 

aum80_faq3

 

 

F: Ich brauche einige Ziele (Sprites), die sich um ihre vertikale Achse drehen, wenn auf die geschossen wird. Können Sie helfen?

A: Sicher, hier ist entsprechender Code.

 

SOUND* bullet_wav = "bullet.wav";

 

function fire_bullets()

{

       VECTOR trace_coords[3];

       vec_set(trace_coords.x, vector(5000, 0, 0)); // trace 5000 quants in front of the player

       // rotate "trace_coords"

       vec_rotate(trace_coords.x, camera.pan);

       vec_add(trace_coords.x, player.x); // add the resulting vector to player's position

       snd_play(bullet_wav, 70, 0); // play the bullet sound

       if (c_trace (player.x, trace_coords.x, IGNORE_ME + USE_BOX) > 0) // the "c_trace" ray has hit something?

       {

               if (you) // and the hit object is an entity?

               {

                       if (you.skill1 == 99) // and the hit entity has its skill1 set to 99?

                       {

                               you.skill50 = 30; // 30 = maximum rotation speed

                       }

               }

       }

}

 

action players_code()

{

       on_mouse_left = fire_bullets;

       player = my; // I'm the player

       set (my, INVISIBLE); // no need to see player's model in 1st person mode

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

       }

}

 

action shooting_target()

{

       my.skill1 = 99; // this entity will rotate around its axis

       while (1)

       {

               while (my.skill50 <= 0) {wait (1);} // the entity waits until it is shot by the player

               while (my.skill50 > 0)

               {

                       my.pan += my.skill50 * time_step; // rotate the entity around its pan angle

                       my.skill50 -= 0.5 * time_step; // decrease the rotation speed as the time passes

                       wait (1);

               }

       }

}

 

aum80_faq4

 

 

F: Wie kann ich die c_scan Reichweite meiner Entity sehen? Ich möchte sie gern auf dem Bildschirm anzeigen.

A: Speichern Sie triangle.mdl aus dem "Ressourcen" Ordner und verwenden Sie dieses Model mit dem Code unten. Dadurch wird der horizontale Scan Sektor und die Distanz angezeigt.

 

function scan_view()

{

       proc_kill(4); // follow the entity smoothly

       set(my, PASSABLE | TRANSLUCENT);

       my.alpha = 20;

       while (you)

       {

               my.x = you.x;

               my.y = you.y;

               my.z = you.z - 35; // move the triangle at the floor level

               my.pan = you.pan;

               my.tilt = you.tilt;

               my.scale_x = you.skill3 / 10; // set the proper scale_x and scale_y for the triangle model

               my.scale_y = 2 * you.skill3 * tan(you.skill1 / 2) / 10; // scale_y = 2 * d * tg (alpha / 2)

               wait (1);

       }

}

 

action my_entity() // simple entity code, makes it rotate around while scanning the area

{

       my.skill1 = 30; // horizontal angle

       my.skill2 = 20; // vertical angle

       my.skill3 = 200; // scanning range

       VECTOR temp[3];

       // create the triangular area using a triangle that has a size of 10 pixels

       ent_create("triangle.mdl", nullvector, scan_view);

       while (1)

       {

               c_scan(my.x, my.pan, my.skill1, IGNORE_ME | SCAN_ENTS | SCAN_LIMIT);

               c_move(my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); // 5 = movement speed

               my.skill22 += 5 * time_step; // 5 gives the "walk" animation speed

               my.pan += 1 * time_step;

               ent_animate(my, "walk", my.skill22, ANM_CYCLE);

               wait (1);

       }

}

 

aum80_faq5

 

 

F: Ich spiele Guild Wars und habe bemerkt, dass es dort intelligente NPCs gibt, die umher laufen, vor Wänden anhalten und dann die Richtung ändern und fortgehen. Kann etwas Ähnliches auch mit Gamestudio erreicht werden?

A: Sehen Sie sich den Code unten an, er tut exakt das, was Sie brauchen.

 

action intelligent_npc() // stops in front of the wall, and then changes its direction

{

       VECTOR front_pos;

       var distance_covered;

       while (1)

       {

               vec_set(front_pos.x, vector(50, 0, 0)); // compute a vector that's 50 quants in front of the player

               // rotate "front_pos" in the direction (angles) given by the entity

               vec_rotate(front_pos.x, my.pan);

               vec_add(front_pos.x, my.x); // add the resulting vector to entity's position

               if (c_content(front_pos.x, 0) == 1) // front_pos isn't touching any walls?

               {

                       // 5 gives the movement speed

                       distance_covered = c_move(my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

                       my.skill22 += 5 * time_step; // 5 gives the "walk" animation speed

                       ent_animate(my, "walk", my.skill22, ANM_CYCLE);

               }

               else // the player is close to a wall now?

               {

                       my.skill99 = 0;

                       while (my.skill99 < 5) // stays in front of the wall for 5 seconds

                       {

                               my.skill99 += time_step / 16;

                               ent_animate(my, "stand", my.skill22, ANM_CYCLE);

                               my.skill22 += 3 * time_step; // 3 gives the "stand" animation speed

                               wait (1);

                       }

                       my.skill99 = my.pan;

                       my.skill99 += random(180);

                       while (my.pan < my.skill99)

                       {

                               my.pan += 5 * time_step;

                               wait (1);

                       }

               }

               wait (1);

       }

}

 

aum80_faq6

 

 

F: Mein Spieler ist von Feinden umzingelt, aber ich kann nciht gut ermitteln, welchen dieser Feinde der Spieler ansieht. Können Sie bitte helfen?

A: Der folgende Code berechnet die Winkeldifferenz zwischen dem Spieler und jedem Gegner. Wenn diese zwischen 150 und 210 liegt (180 plus/minus 30 Grad), dann steht der Feind vor dem Spieler. Der Code setzt scale_z für diesen Gegner auf 1,5.

 

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

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       player = my; // I'm the player

       while (1)

       {

               temp.x = movement_speed * (key_cuu - key_cud) * time_step;

               temp.y = 0;

               temp.z = 0;

               my.pan += 4 * (key_cul - key_cur) * time_step;

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

               wait (1);

       }

}

 

// simple enemy action; surround the player with several models that have this action attached to them

action my_enemy()

{

       VECTOR temp;

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

       while (1)

       {

               vec_set(temp, player.x);

               vec_sub(temp, my.x);

               vec_to_angle(my.pan, temp); // rotate the enemy towards the player

               my.tilt = 0; // but don't allow it to change its tilt angle

               if (ang(my.pan - player.pan) > 150)

               {

                       // the angle between the enemy and the player is in the 150...210 degrees range?

                       if (ang(my.pan - player.pan) < 210)

                       {

                               // then increase the z scale of the entity that is facing the player

                               my.scale_z = 1.5;

                       }

               }

               else // the player isn't facing this enemy

               {

                       my.scale_z = 1; // so restore the initial scale_z value

               }

               wait (1);

       }

}

 

aum80_faq7

 

F: Geben Sie bitte ein Beispiel, wie man lokale Variablen als Panels über einer Entity anzeigt; darüber herrscht im Forum große Verwirrung. Als Beispiel haben Sie einige Entities mit der gleichen Action und Sie wollen ein Health Panel anzeigen.

A: Der Code unten nutzt ein grünes 4 x 4 Pixel großes Sprite für ein Health Panel über jeder Entity. Der Wert für die Gesundheit wird aus einer lokalen Variablen (skill20 der Entity) gelesen.

 

#define health skill20

 

function health_indicator()

{

       set (my, PASSABLE);

       while (you)

       {

               vec_set (my.x, you.x);

               my.z += 60;

               my.scale_x = you.health * 0.1; // skill20 aka "health" stores the health for each entity

               wait (1);

       }

}

 

action my_enemy() // simple enemy action, makes it rotate in a circle

{

       my.health = 10 + random(90);

       ent_create ("health.pcx", nullvector, health_indicator);

       while (1)

       {

               c_move(my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); // 5 = movement speed

               my.skill22 += 5 * time_step; // 5 gives the "walk" animation speed

               my.pan += 1 * time_step;

               ent_animate(my, "walk", my.skill22, ANM_CYCLE);

               wait (1);

       }

}

 

function randomize_startup()

{

       randomize();

}

 

aum80_faq8