Fragen aus dem Forum

Top  Previous  Next

F: Ich würde gern ein 2D Spiel erstellen, das 4 verschiedene Fahrzeugsprites (für 4 mögliche Richtungen) verwendet und in dem man das Fahrzeug mit den Pfeiltasten kontrolliert.

A: Hier ist ein Beispiel:

 

BMAP* carleft_tga = "carleft.tga";

BMAP* carright_tga = "carright.tga";

BMAP* carup_tga = "carup.tga";

BMAP* cardown_tga = "cardown.tga";

 

var direction = 0; // 1 = up, 2 = down, 3 = left, 4 = right

 

PANEL* carleft_pan =

{

       bmap = carleft_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* carright_pan =

{

       bmap = carright_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* carup_pan =

{

       bmap = carup_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* cardown_pan =

{

       bmap = cardown_tga;

       pos_x = 400;

       pos_y = 300;

}

 

function control_car_startup()

{

       set(carleft_pan, VISIBLE); // this will set the initial car orientation

       direction = 3;

       while (1)

       {

               if (key_cuu)

               {

                       if (direction == 2)

                       {

                               carup_pan.pos_x = cardown_pan.pos_x;

                               carup_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               carup_pan.pos_x = carleft_pan.pos_x;

                               carup_pan.pos_y = carleft_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               carup_pan.pos_x = carright_pan.pos_x;

                               carup_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cuu)

                       {

                               clamp(carup_pan.pos_y, 0, 570);

                               clamp(carup_pan.pos_x, 0, 770);

                               set(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);

                               carup_pan.pos_y -= 5 * time_step;

                               wait (1);

                       }

                       direction = 1;

               }

               if (key_cud)

               {

                       if (direction == 1)

                       {

                               cardown_pan.pos_x = carup_pan.pos_x;

                               cardown_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               cardown_pan.pos_x = carleft_pan.pos_x;

                               cardown_pan.pos_y = carleft_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               cardown_pan.pos_x = carright_pan.pos_x;

                               cardown_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cud)

                       {

                               clamp(cardown_pan.pos_y, 0, 570);

                               clamp(cardown_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               set(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);        

                               cardown_pan.pos_y += 5 * time_step;

                               wait (1);

                       }

                       direction = 2;

               }

               if (key_cul)

               {

                       if (direction == 1)

                       {

                               carleft_pan.pos_x = carup_pan.pos_x;

                               carleft_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 2)

                       {

                               carleft_pan.pos_x = cardown_pan.pos_x;

                               carleft_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               carleft_pan.pos_x = carright_pan.pos_x;

                               carleft_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cul)

                       {

                               clamp(carleft_pan.pos_y, 0, 570);

                               clamp(carleft_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               set(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);        

                               carleft_pan.pos_x -= 5 * time_step;

                               wait (1);

                       }

                       direction = 3;

               }

               if (key_cur)

               {

                       if (direction == 1)

                       {

                               carright_pan.pos_x = carup_pan.pos_x;

                               carright_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 2)

                       {

                               carright_pan.pos_x = cardown_pan.pos_x;

                               carright_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               carright_pan.pos_x = carleft_pan.pos_x;

                               carright_pan.pos_y = carleft_pan.pos_y;

                       }

                       while (key_cur)

                       {

                               clamp(carright_pan.pos_y, 0, 570);

                               clamp(carright_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               set(carright_pan, VISIBLE);        

                               carright_pan.pos_x += 5 * time_step;

                               wait (1);

                       }

                       direction = 4;

               }

               wait (1);

       }

}

 

 

F: Ich möchte mein Model mit den WASD Tasten bewegen; das Skript verwendet c_move wie unten gezeigt. Wie schnell (in Quants) wird sich das Model im Level bewegen? Hängt die Geschwindigkeit von der Framerate ab?

 

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

...............................................

c_move (my, vector(speed.x, speed.y, speed.z), nullvector, GLIDE);

 

A: Die Bewegungsgeschwindigkeit hängt in der Tat von der Framerate ab; in Ihrem Beispiel wird sich das Model mit einer Geschwindigkeit von 5 Quants pro Frame bewegen. Das bedeutet, dass dieses Model bei einer Framerate von 100 fps 500 Quants pro Sekunde zurücklegt. Sie können die Geschwindigkeit des Models unabhängig von der Framerate machen, indem Sie diese auf einen kleineren Wert begrenzen (fps_max = 60; oder so) oder besser noch die Geschwindigkeit mit time_step multiplizieren. Im Magazin gibt es viele Beispiele dafür.

 

 

F: Ich hätte gern ein Radar, das seine Umgebung scannt und alle Entities in Reichweite hervorhebt.

A: Hier ist ein Beispiel.

 

action entity_radar() // attach this action to the radar entity

{

       while (1)

       {

               // scan all the entities that are closer than 1000 quants to this entity

               c_scan(my.x, my.pan, vector(360, 180, 1000), IGNORE_ME);

               wait (1);

       }

}

 

function i_am_scanned()

{

       while (event_type == EVENT_SCAN)

       {

               my.ambient = 100;

               wait (1);

       }

       my.ambient = 100;

}

 

action scanned_entities() // attach this action to the scanned entities

{

       my.emask |= ENABLE_SCAN; // make the entity sensitive to scanning

       my.event = i_am_scanned;

}

 

 

F: Gibt es einen Weg, die Texturqualität zu verringern? Mein Spiel läuft mit kleiner Framerate und ich habe das Problem auf die Qualität der Texturen zurückgeführt, es würde also wirklich helfen, wenn ich diese verringern könnte.

A: Eigentlich ist die Qualität der Texturen nicht entscheidend, es ist ihre Größe; Sie können kleinere Texturen verwenden und diese im WED hochskalieren. Generell braucht eine Textur etwa a x b x 3 Byte pro 2 Texturbytes (pcx, bmp, etc) und a x b x 4,5 Byte pro 3 Byte TGA-Textur, wobei hier a und b die Breite und Höhe der Textur in Pixeln sind.

 

Das bedeutet, dass eine 512 x 512 bmp-Textur etwa 0,75 MB verbraucht, wohingegen eine 1024 x 1024 tga-Textur schon 4,5 MB Grafikkartenspeicher einnimmt. Die Shadow Maps sind abhängig von der Levelgeometrie, der Zahl und Art der Lichter und so weiter, aber diese Näherungswerte sind ziemlich realistisch.

 

 

F: Ich versuche gerade ein Außenlevel zu gestelten, in dem etwas Wasser vorkommt, in das der Spieler hineingehen kann. Ich habe die passable Flag meiner Wasserentity gesetzt, aber der Spieler läuft einfach auf der Oberfläche und taucht nicht unter. Was habe ich falsch gemacht?

A: Es müssen zwei Dinge getan werden:

1) Die passierbare Entity muss ihr "passable" Flag gesetzt bekommen und zwar entweder im WED oder innerhalb der zugeordneten Action oder Funktion, so wie hier:

 

action passable_entity()

{

       set (my, PASSABLE);

       // the rest of the code for your entity should go here

       ..................................

}

 

2) Das Model, das durch die Entitz hindurch soll (der Spieler) muss IGNORE_PASSABLE in der c_move Anweisung gesetzt haben, so wie hier:

 

c_move(my, vector(10 * (key_w - key_s) * time_step, 0, 0), nullvector, IGNORE_PASSABLE);

 

 

F: Wie kann ich einen sehr langen String aus einer Datei auslesen und anzeigen? Momentan unterbricht jeder Separator (Komma, etc.) den String und teilt ihn auf.

A: Definieren Sie Ihren eigenen Separator (ich habe im Beispiel das Zeichen "~" genutzt) und diesen Ausschnitt als Grundlage.

 

// this can be a huge string which contains commas, several lines, new lines (Enter), etc.

STRING* my_str = "                                                                          "; 

 

TEXT* my_txt =

{

       pos_x = 50;

       pos_y = 30;

       layer = 10;

       string(my_str);

       flags = VISIBLE;

}

 

function read_lots_of_data()

{

       var filehandle;

       filehandle = file_open_read("mybigfile.txt"); // read the text from this file and copy it to my_str

       file_str_readto(filehandle, my_str, "~", 4000); // use ~ as a separator, read up to 4000 characters

       file_close (filehandle); // now close the file

}

 

 

F: Ich möchte, dass mein Spieler Tagebuchseiten aufsammeln kann, indem er sie berührt und diese dann im Inventar wiederfindet.

A: Hier ist ein Beispiel mit 3 Tagebuchseiten.

 

BMAP* diary1_pcx = "diary1.pcx";

BMAP* diary2_pcx = "diary2.pcx";

BMAP* diary3_pcx = "diary3.pcx";

 

PANEL* diary1_pan =

{

       bmap = diary1_pcx;

       pos_x = 0;

       pos_y = 0;

}

 

PANEL* diary2_pan =

{

       bmap = diary2_pcx;

       pos_x = 0;

       pos_y = 50;

}

 

PANEL* diary3_pan =

{

       bmap = diary3_pcx;

       pos_x = 0;

       pos_y = 100;

}

 

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

{

       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 diary1() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary1_pan, VISIBLE);

       ent_remove(my);

}

 

action diary2() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary2_pan, VISIBLE);

       ent_remove(my);

}

 

action diary3() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary3_pan, VISIBLE);

       ent_remove(my);

}

 

 

F: Ich habe Schwierigkeiten, die Größe der Entities im Level korrekt einzustellen; ist es möglich, diese zur Laufzeit zu ändern?

A: Hier ist ein Beispiel, mit dem man die Größe in z-Richtung für jede Entity einstellen kann, auf die der Mauszeiger gerichtet ist. Ein Panel zeigt diese Größe an und sie kann im WED verwendet werden.

 

BMAP* arrow_pcx = "arrow.pcx";

 

PANEL* size_pan =

{

       digits(100, 50, 3.3, *, 1, mouse_ent.scale_z);

       flags = visible;

}

 

function mouse_startup()

  mouse_mode = 2;

  mouse_map = arrow_pcx;

  while (1)

  { 

       vec_set(mouse_pos, mouse_cursor);

       wait(1);

  }

}

 

function change_entities_startup()

{

       while (1)

       {

               if (mouse_ent) // if the mouse is touching an entity

               {

                       if (key_1) {mouse_ent.scale_z += 0.1 * time_step;}

                       if (key_2) {mouse_ent.scale_z -= 0.1 * time_step;}

               }

               wait (1);

       }

}

 

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

{

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

       }

}

 

 

F: Ich schreibe ein Adventure und hätte gern einen "Tooltip", einen kleinen Text, der am oberen Bildschirmrand erscheint und erklärt, was ein Objekt ist oder was es tut, wenn dieses mit der Maus berührt wird. Wie kann ich das erreichen?

A: Tragen Sie den Tooltip für alle Entities, die einen solchen benötigen im "String 1" Feld im WED ein und verwenden Sie dann den Ausschnitt unten.

 

BMAP* arrow_pcx = "arrow.pcx";

 

STRING* tooltip_str = "                                "; // use up to 32 characters for your tooltip

 

TEXT* tooltip_txt =

{

  pos_x = 50;

  pos_y = 20;

  string (tooltip_str);

  flags = VISIBLE;

}

 

function mouse_startup()

  mouse_mode = 2;

  mouse_map = arrow_pcx;

  while (1)

  { 

       vec_set(mouse_pos, mouse_cursor);

       wait(1);

  }

}

 

function tooltips_startup()

{

       while (1)

       {

               if (mouse_ent)

               {

                       str_cpy(tooltip_str, mouse_ent.string1); // put your text in entity's string1 in Wed

                       set(tooltip_txt, VISIBLE);

               }

               else

               {

                       reset(tooltip_txt, VISIBLE);

               }

               wait (1);

       }

}

 

 

F: Ich brauche eine Funktion, die Datum und Zeit in eine Logdatei schreibt (und an bestehende Daten anfügt) und dann die Engine beendet.

A: Bitte sehr.

 

STRING* log_str = "                                       "; // yyyy mm, dd  hh:mm ss (ex: 2007 January, 25  17:34 56)

STRING* temp_str = "  ";  // temporary string

 

function write_log_startup()

{

       var filehandle;

       filehandle = file_open_append ("mylog.txt");

 

       if (sys_month == 1)

               str_cpy(log_str, "January ");

       if (sys_month == 2)

               str_cpy(log_str, "February ");

       if (sys_month == 3)

               str_cpy(log_str, "March ");

       if (sys_month == 4)

               str_cpy(log_str, "April ");

       if (sys_month == 5)

               str_cpy(log_str, "May ");

       if (sys_month == 6)

               str_cpy(log_str, "June ");

       if (sys_month == 7)

               str_cpy(log_str, "July ");

       if (sys_month == 8)

               str_cpy(log_str, "August ");

       if (sys_month == 9)

               str_cpy(log_str, "September ");

       if (sys_month == 10)

               str_cpy(log_str, "October ");

       if (sys_month == 11)

               str_cpy(log_str, "November ");

       if (sys_month == 12)

               str_cpy(log_str, "December ");

 

       if (sys_day < 10)

       {

               str_cat(log_str, "0");

       }

       str_for_num(temp_str, sys_day);

       str_cat(log_str, temp_str);

       str_cat(log_str, ", ");

 

       str_for_num(temp_str, sys_year);

       str_cat(log_str, temp_str);

       str_cat(log_str, "  ");

 

         str_for_num(temp_str, sys_hours);

         str_cat(log_str, temp_str);

         str_cat(log_str, ":");

         if (sys_minutes < 10)  

         { 

               str_cat(log_str, "0"); 

         } 

         str_for_num(temp_str, sys_minutes);

         str_cat(log_str, temp_str);  

         str_cat(log_str, " ");  

         if (sys_seconds < 10)  

         { 

                 str_cat(log_str, "0"); 

         } 

         str_for_num(temp_str, sys_seconds);

         str_cat(log_str, temp_str);

 

       file_str_write(filehandle, log_str);

       file_asc_write (filehandle, 13);

         file_asc_write (filehandle, 10);

       

       file_close(filehandle);

 

       wait (-5); // wait for 5 seconds

       sys_exit(NULL); // now shut down the engine

}

 

aum70_faq1