Fragen aus dem Forum

Top  Previous  Next

Q: Ich möchte, dass meine Kamera sich neigt wenn der Player an einem Berghang geht. Können Sie mir helfen?

A: Verwenden Sie den Code-Abschnitt unten:

 

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

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       ANGLE temp_angles;

       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;

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

               temp_angles.tilt = 0;

               temp_angles.roll = 0;

               temp_angles.pan = -my.pan;

               vec_rotate(normal, temp_angles);

               temp_angles.tilt = -asin(normal.x);

               temp_angles.roll = -asin(normal.y);

               my.tilt += 0.1 * ang(temp_angles.tilt - my.tilt); // play with 0.1

               my.roll += 0.1 * ang(temp_angles.roll - my.roll); // play with 0.1

               wait (1);

       }

}

 

aum85_faq1

 

 

Q: Wie kann ich den Mauszeiger in einem rechteckigen Bereich in der Bildschirmmitte einfangen?

A: Nehmen Sie dieses Beispiel:

 

// trap the mouse in an area that has 200x100 pixels and is located in the center of the screen

var area_x = 200;

var area_y = 100;

 

BMAP* pointer_tga = "pointer.tga";

 

function mouse_startup()

       VECTOR temp1_pos, temp2_pos;

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               temp1_pos.x = (screen_size.x - area_x) / 2;

               temp2_pos.x = (screen_size.x + area_x) / 2;

               mouse_pos.x = clamp(mouse_pos.x, temp1_pos.x, temp2_pos.x);

               temp1_pos.y = (screen_size.y - area_y) / 2;

               temp2_pos.y = (screen_size.y + area_y) / 2;

               mouse_pos.y = clamp(mouse_pos.y, temp1_pos.y, temp2_pos.y);

               wait(1);

       }

}

 

 

Q: Wie erreiche ich, dass sich eine Entity für eine festgelegte Anzahl von Sekunden bewegt wenn ich einen Knopf drücke?

A: Bitteschön:

 

action moving_puppet()

{

       var movement_time = 5; // move for 5 seconds when the "M" key is pressed

       var movement_speed = 2; // movement speed

       VECTOR temp;

       while (1)

       {

               while (!key_m) {wait (1);} // wait until the player presses the "M" key on the keyboard

               while (key_m) {wait (1);} // wait until the player releases the "M" key

               while (movement_time > 0)

               {

                       movement_time -= time_step / 16; // decrease 1 from movement_time each second

                       my.skill1 += 4 * time_step; // 4 gives the animation speed

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

                       temp.z -= 10000;

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

                       // move the entity with the speed given by movement_speed along the direction pointed by its pan angle

                       c_move (my, vector(movement_speed, 0, temp.z), nullvector, IGNORE_PASSABLE | GLIDE);

                       // animate the model using its "walk" animation in a loop

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

                       wait (1);

               }

               // the walking is over here, so let's switch to the "stand" animation

               ent_animate(my, "stand", 0, 0);

               movement_time = 5; // prepare for a new movement session

       }

}

 

 

Q: Wie kann ich einen Sound einmal abspielen sobald eine Vergleichsanweisung erfolgreich ist?

A: Hier ein Beispiel:

 

STRING* password_str = "iliketoeatalot";

STRING* input_str = "#20"; // this empty string can store up to 20 characters

STRING* messages_str = "30";

 

SOUND* passok_wav = "passok.wav";

 

TEXT* input_txt =

{

       pos_x = 300;

       pos_y = 400;

       string(input_str);

}

 

TEXT* messages_txt =

{

       pos_x = 300;

       pos_y = 300;

       string(messages_str);

}

 

function password_startup()

{

       wait (-3); // wait until the game starts, etc

       // the following loop will run until the correct password is typed in

       while (1)

       {

               str_cpy(messages_str, "Type in the correct password");

               messages_txt.flags |= SHOW; // show the intro message

               wait (-3); // for 3 seconds

               messages_txt.flags &= ~SHOW; // now hide the intro message

               input_txt.flags |= SHOW; // show the input

               str_cpy(input_str, "#20"); // reset the string (if needed)

               inkey(input_str);

            if (str_cmpi(input_str, password_str) == 1) // the correct password was typed in?

             {

                       snd_play(passok_wav, 90, 0);

                       break; // get out of the loop

               }

       }

       // the correct password was typed in here

       str_cpy(messages_str, "Logged into the system");

       messages_txt.flags |= SHOW; // show the outro message

       wait (-5); // for 5 seconds

       messages_txt.flags &= ~SHOW; // now hide the outro message        

       sys_exit(NULL); // shut down the engine

}

 

 

Q: Ich möchte die Kamera meines Spiels an ein Objekt hängen (Kugel etc.) so, dass die Kamera ein physikalisches Verhalten hat und nicht mehr durch Wände geht.

A: Verwenden Sie dieses Code-Stückchen:

 

VECTOR movement_force;

 

action solid_camera() // attach this action to a sphere model

{

       set (my, INVISIBLE); // no need to see the sphere model

       while (1)

       {

               // use the W and S keys to move forward / backward, 5 gives the movement speed

               movement_force.x = 5 * (key_w - key_s);

               // use the A and D keys to move sideways, 3 gives the movement speed

               movement_force.y = 3 * (key_a - key_d);

               // don't allow the z value of movement_force to change

               movement_force.z = 0;

               my.pan -= 3 * mouse_force.x * time_step; // 3 = horizontal rotation speed

               my.tilt -= 3 * mouse_force.y * time_step; // 3 = vertical rotation speed

               // now move the sphere in the direction given by its pan and tilt angles

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

               // the camera will inherit the same position and angles with the sphere

               vec_set (camera.x, my.x);

               camera.pan = my.pan;

               camera.tilt = my.tilt;

               wait(1);

       }

}

 

 

Q: Ich brauche zum Testen einen Code der die Kamerakoordinaten auf Knopfdruck in eine ini-Datei schreibt. Dann, wenn ich einen anderen Knopf drücke, soll die Kamera diese Koordinaten aus der ini-Datei laden.

A: Hier ist was Sie brauchen:

 

var file_handle;

 

VECTOR vSpeed, vAngularSpeed, vForce, vMove;

 

function camera_startup() // this camera can pass through walls

{

       while (1)

       {

               vForce.x = - 5 * (key_force.x + mouse_force.x);        // pan angle

               vForce.y = 5 * (key_force.y + mouse_force.y); // tilt angle

               vForce.z = 0; // no changes for the roll angle

               vec_accelerate (vMove, vAngularSpeed, vForce, 0.8);

               vec_add (camera.pan, vMove);

               vForce.x = 6 * (key_w - key_s); // use W and S to move forward

               vForce.y = 6 * (key_a - key_d); // use A and D to move sideways

               vForce.z = 6 * (key_home - key_end); // use Home and End to move upwards / downwards

               vec_accelerate (vMove, vSpeed, vForce, 0.5);

               vec_rotate (vMove, camera.pan);

               vec_add (camera.x, vMove);

               wait(1);

       }

}

 

function save_position()

{

       file_handle = file_open_write ("camera.ini"); // save the data to the camera.ini file

       file_var_write (file_handle, camera.x); // save x, y, z, pan, tilt, roll

       file_var_write (file_handle, camera.y);

       file_var_write (file_handle, camera.z);

       file_var_write (file_handle, camera.pan);

       file_var_write (file_handle, camera.tilt);

       file_var_write (file_handle, camera.roll);

       file_close (file_handle); // close the file, we won't be needing it from now on

}

 

function load_position()

{

       file_handle = file_open_read("camera.ini"); // try to open ini file

       if (file_handle) // the file exists? (the player could press "2" without pressing "1" first)

       {

               camera.x = file_var_read (file_handle); // then restore the x, y, z, pan, tilt, roll

               camera.y = file_var_read (file_handle);

               camera.z = file_var_read (file_handle);

               camera.pan = file_var_read (file_handle);

               camera.tilt = file_var_read (file_handle);

               camera.roll = file_var_read (file_handle);

       }

}

 

function init_startup()

{

       on_1 = save_position; // press "1" to save the camera coordinates

       on_2 = load_position; // press "2" to load the camera coordinates

}

 

 

Q: Ich möchte gerne in der Lage sein, ein Objekt unter Verwendung des Mauszeigers aufzunehmen, zu bewegen und wieder loszulassen.

A: Hier ist eine verbesserte Version meines Codes aus den FAQs von AUM 52, die gut mit A7 / lite-C funktioniert:

 

BMAP* pointer_tga = "pointer.tga";

 

VECTOR temp;

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function pick_or_drop()

{

       wait (1);

       my.skill1 += 1;

       if ((my.skill1 % 2) == 1) // clicked the object?

       {

               while (mouse_left) {wait (1);} // wait until the player releases the left mouse button

               while (!mouse_left) // move the object until the player presses the mouse button again

               {

                       temp.x = mouse_cursor.x;

                       temp.y = mouse_cursor.y;

                       temp.z = 200; // move the object 200 quants below the camera, play with this value

                       vec_for_screen(temp.x, camera);

                       vec_set (my.x, temp.x);

                       set (my, PASSABLE);

                       wait (1);

               }

       }

       else // drop the object here

       {

               vec_set (temp.x, my.x);

               temp.z -= 3000; // trace up to 5,000 quants below the player

               // make sure to drop the object on the ground

               my.z -= c_trace (my.x, temp.x, IGNORE_ME + IGNORE_SPRITES + IGNORE_MODELS + USE_BOX);

               reset (my, PASSABLE);

       }

}

 

action click_and_move()

{

       my.skill1 = 0;

       my.emask |= ENABLE_CLICK;

       my.event = pick_or_drop;

}

 

aum85_faq3

 

 

Q: Ich habe ein kleines Projekt entwickelt bei dem der Player eine Zahl von 1 bis 9 erraten muß. Ich kann den Code über die Tastaturzahlen von 1 bis 9 eingeben aber wenn ich den Zahlenblock der Tastatur benutze, passiert gar nichts. Num Lock habe ich angeschaltet. Warum funktioniert das nicht?

A: Die Tasten des Zahlenblocks haben andere Scan-Codes. Nehmen Sie den Codeschnipsel unten zum Aufspüren der Namen und Scan-Codes für die Tasten auf der Tastatur. Ich rate dazu, für Ihre Projekte immer Scan-Codes zu verwenden.

 

STRING* temp_str = "#10";

 

TEXT* header_txt =

{

       pos_x = 180;

       pos_y = 5;

       string("Key name ------- Scan code");

       flags = SHOW;

}

 

TEXT* keypressed_txt =

{

       pos_x = 200;

       pos_y = 20;

       string(temp_str);

       flags = SHOW;

}

 

PANEL* keypressed_pan =

{

       layer = 15;

       digits(300, 20, 3, * , 1, key_lastpressed);

       flags = SHOW;

}

 

function keys_startup()

{

       while (1)

       {

               if (key_any)

               {

                       beep();

                       str_for_key(temp_str, key_lastpressed); // convert the scan code to the key name

               }

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

               wait (1);

       }

}

 

 

Q: Ich möchte ein dynamisches Licht, das, wenn man nah genug dran ist, per Leertaste aufgenommen werden kann und dem Player folgt. Das Licht sollte immer an sein, auch nach einer Levelwechsel-Anweisung. Wie kann ich das machen?

A: Die Aktionen, die Entities zugewiesen sind, hören nach einer level_load-Anweisung auf zu laufen. Trotzdem behalten aber die Variablen ihre Werte und lassen sich zum Wiederherstellen von dem was gebraucht wird verwenden; und zwar wie folgt:

 

var got_flashlight = 0;

 

SOUND* gotflashlight_wav = "gotflashlight.wav";

 

ENTITY* flashlight;

 

function move_flashlight()

{

       set (my, PASSABLE | INVISIBLE | CAST);

       my.lightrange = 350;

       my.red = 200;

       my.green = 200;

       my.blue = 160;

       while (player) // this loop will run for as long as the player pointer exists

       {

               vec_set(my.x, player.x);

               wait (1);

       }

}

 

action my_flashlight()

{

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

       while (1)

       {

               if (vec_dist(player.x, my.x) < 70)

               {

                       if (key_space)

                       {

                               snd_play(gotflashlight_wav, 50, 0);

                               flashlight = ent_create("flashlight.mdl", player.x, move_flashlight);

                               got_flashlight = 1;

                               wait (2);

                               break; // get out of this loop

                       }

      }

               wait (1);

       }

       set(my, PASSABLE | INVISIBLE); // hide the flashlight model on the floor

       while (vec_dist(player.x, my.x) < 300) {wait (1);} // wait until the player moves away

       // and then remove the flashlight model from the floor (give the sound effect enough time to play)

       ent_remove (my);

}

 

action players_code() // attach this action to your player model in all the levels

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

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

       player = my; // I'm the player

 

       // this section recreates the flashlight (if needed)

       if (got_flashlight == 1) // the flashlight was picked up in a previous level?

       {

               flashlight = ent_create("flashlight.mdl", player.x, move_flashlight); // the recreate it!

       }

       // end of the section that recreates the flashlight (if needed)

 

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

       }

}

 

action lever_changer() // attach this action to your level changing entity

{

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

       // wait until the player comes closer than 100 quants to the level changing entity

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

       // now load the new level; the flashlight will be recreated if it was picked up in a previous level

       level_load("level2.wmb");

}

 

 

Q: Ich möchte ein Mini-Mathequiz erstellen und dazu soll ein Text wie etwa 5 x 2 auf dem Bildschirm erscheinen. Die Anwender geben eine Antwort ein und drücken "Eing." womit sie zur nächsten Frage weitergeleitet werden sollen. Machen sie einen Fehler, wird ihre Punktzahl vermindert.

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

 

var score = 0, number1, number2, my_result;

 

STRING* question_str = "#20";

STRING* answer_str = "#5";

STRING* temp_str = "#5";

 

SOUND* goodjob_wav = "goodjob.wav";

SOUND* missed_wav = "missed.wav";

 

TEXT* question_txt =

{

       pos_x = 200;

       pos_y = 200;

       string(question_str);

       flags = SHOW;

}

 

TEXT* answer_txt =

{

       pos_x = 300;

       pos_y = 200;

       string(answer_str);

       flags = SHOW;

}

 

PANEL* score_pan =

{

       layer = 15;

       digits(700, 20, 4, * , 1, score);

       flags = SHOW;

}

 

function init_startup()

{

       random_seed(0); // generate a random sequence of numbers

       wait (-3); // wait until the level is loaded

       while (1)

       {

               str_cpy(question_str, "What is ");

               number1 = integer(random(10) + 1); // number 1 ranges from 1 to 10

               str_for_num(temp_str, number1); // convert number1 to a string

               str_cat(question_str, temp_str); // add number1 to question_str

               str_cat(question_str, " x ");

               number2 = integer(random(10) + 1); // number 2 ranges from 1 to 10

               str_for_num(temp_str, number2); // convert number1 to a string

               str_cat(question_str, temp_str); // add number2 to question_str

               wait (1);                        

               str_cat(question_str, " = ");

               str_cpy(answer_str, "#5");

               inkey(answer_str);

               my_result = str_to_num(answer_str);

               if (my_result == (number1 * number2)) // the player has got the correct answer?

               {

                       score += 1; // then increase the score

                       snd_play(goodjob_wav, 60, 0);

               }

               else

               {

                       snd_play(missed_wav, 60, 0);

                       score -= 1; // then decrease the score

                       score = maxv(0, score); // don't allow negative score values

               }

               wait (-3); // wait for 5 seconds before generating a new exercise

       }

}