Fragen aus dem Forum

Top  Previous  Next

F: Die Kollisionskamera aus Morrowing gefällt mir richtig gut. Ich habe versucht, sie in nach lite-C zu übertragen, dies ist mir jedoch nicht gelungen. Können Sie helfen?

A: Hier ist der Code für die lite-C Kamera und den Spieler.

 

var camera_distance = 200; // distance from the player to the camera in 3rd person mode

var camera_height = 240; // distance from the origin of the player to the camera (on the z axis)

var distance_traced; // distance that is return by a trace instruction

var camera_mode; // starts in 3rd person mode, changes to 1 for first person

var stop_player = 0; // set it to 1 to stop the player until stop_player is set to 0 again

var player_speed = 15;

 

VECTOR temporary_distance;

 

SOUND* step_wav = "step.wav";

 

function avoid_obstacles();

function first_person_camera();

function third_person_camera();

 

#define shield skill1

#define mace skill2

#define bodyarmor skill3

#define flare skill4

#define strength skill10 // use these skills to store player's abilities

#define experience skill11

#define mana skill12

#define health skill40 // use skill40 to store health for the player and its enemies

 

action player1()

{

       on_f1 = first_person_camera;

       on_f3 = third_person_camera;

       VECTOR temp;

       VECTOR trace_coords;

       player = my; // I'm the player

       set (my, TRANSLUCENT); // the player is transparent

       my.alpha = 100; // but opaque if the camera doesn't run into obstacles

       my.skill41 = camera_height; // and its height

       my.skill42 = camera_distance; // we store the distance to the camera

       camera_mode = 3; // the game starts with the camera in 3rd person mode

       my.health = 100;

       while (my.health > 0)

       {

               while (stop_player == 1) {wait (1);}

               // player's pan is controlled by the mouse and the "A" and "D" keys

               player.pan -= 10 * mouse_force.x * time_step - 1.5 * (key_a - key_d);

               camera.x = player.x - camera_distance * cos(player.pan); // keep the camera behind the player

               camera.y = player.y - camera_distance * sin(player.pan); // at the distance given by camera_distance

               camera.z = player.z + camera_height + 0.8 * sin(my.skill46 * 3.6); // and above the player

               camera.pan = player.pan; // the camera has the same pan angle with the player

               camera.tilt += 7 * mouse_force.y * time_step; // and can tilt freely

               camera_distance = minv(maxv(camera_distance, 5), 500); // camera_distance can have values between 5 and 500

               if (key_w + key_s > 0) // if the player is walking

               {

                       ent_animate(my, "walk", my.skill46, ANM_CYCLE); // play its "walk" frames animation

                       // the animation speed increases when the player presses the "shift" key

                       my.skill46 += 5 * (1 + key_shift * 0.7) * time_step;

                       my.skill46 %= 100; // loop the animation

               }

               else // if the player is standing

               {

                       my.skill47 = 0; // reset the skill that stores the distance needed for the step sound (not really needed)

                       ent_animate(my, "stand", my.skill48, ANM_CYCLE); // play the "stand" frames animation

                       my.skill48 += 2 * time_step; // "stand" animation speed

                       my.skill48 %= 100; // loop animation

               }

               if (camera_mode == 3) // if we are in 3rd person mode

               {                        

                       avoid_obstacles(); // run the function that avoids camera collisions with the relief

               }

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

               temp.z -= 10000;

               temp.z = - c_trace (my.x, temp, IGNORE_ME | IGNORE_PASSABLE | USE_BOX); // and adjust its height accordingly, placing its feet on the ground

               // allow the player to move using the "W" and "S" keys; the speed increases to 200% if the player presses the "shift" key

               temp.x = player_speed * (key_w - key_s) * (1 + 1 * key_shift) * time_step;

               temp.y = 0;

               my.skill47 += c_move (my, temp, nullvector, IGNORE_PASSABLE);

               if (my.skill47 > 250) // play with 250 (here we've got a step sound every 50 quants)

               {

                       snd_play(step_wav, 15, 0);

                       my.skill47 = 0;

               }

               wait (1);

       }

       // the player is dead here

       my.skill40 = 0; // use the same skill40 (health) to control the "death" animation

       while (my.skill40 < 90) // don't play all the animation frames because the result doesn't look too good

       {

               ent_animate(my, "death", my.skill40, NULL); // play the "death" animation

               my.skill40 += 2 * time_step; // "death" animation speed

               camera.roll -= 0.3 * time_step;

               camera.tilt += 0.8 * time_step;

               wait (1);

       }

       set (my, PASSABLE); // the corpse will be passable from now on

}

 

function avoid_obstacles()

{

       vec_set (temporary_distance.x, camera.x);

       temporary_distance.z -= 50; // sets a position closer to the feet of the player; 50 = experimental value

       distance_traced = c_trace (player.x, temporary_distance.x, IGNORE_ME | IGNORE_PASSABLE); // trace between the player and temporary_distance

       if (distance_traced == 0) // no obstacles on the way?

       {

               my.alpha = minv(100, my.alpha + 3 * time_step); // then increase player's alpha up to 100

               if (player.alpha == 100)

               {

                       reset(player, TRANSLUCENT);

               }

               else

               {

                       set(player, TRANSLUCENT);

               }

               if (camera_distance < my.skill40) // if the camera got closer to the player

               {

                       camera_distance += 1; // restore the initial camera_distance slowly

               }

       }

       else // obstacles encountered?

       {

               distance_traced -= 2; // then bring the camera 2 quants closer to the player!

               my.alpha = (distance_traced / (my.skill40 + 1)) * 100; // decrease player's alpha; don't allow a division by zero

               camera.x = player.x - distance_traced * cos(camera.pan); // place the camera behind the player

               camera.y = player.y - distance_traced * sin(camera.pan); // at the new distance given by distance_traced

       }

}

 

function first_person_camera() // press "F1" to run this function

{

       camera_distance = 0; // place the camera at player's position

       camera_height = 150; // play with this value

       set (player, INVISIBLE); // make the player model invisible

       camera_mode = 1; // set the camera_mode variable to 1st person

}

 

function third_person_camera() // press "F3" to run this function

{

       camera_height = player.skill41; // restore the height

       camera_distance = player.skill42; // restore the distance from the player to the camera

       reset (player, INVISIBLE); // and show the player

       camera_mode = 3; // set the camera_mode variable to 3rd person

}

 

 

F: Wie erstelle ich einen Spiegel an der Wand, der alles korrekt reflektiert (keine Bodenreflektion)?

A: Verwenden Sie den Code unten und beherzigen Sie die folgenden Hinweise:

 

1) Die Spiegel Entity sollte nicht gedreht werden, erstellen Sie sie und platzieren Sie sie im Level.

2) Die Spiegel Entity sollte alle Oberflächen auf "flat" stehen haben, mit Ausnahme der reflektierenden Oberfläche, die auf "mirror" stehen sollte.

3) Der Spiegel Code ändert sich je nach Orientierung der Entity. Mein Beispiel geht von einem Spiegel auf der Südseite eines Raumes (in der Draufsicht von WED) aus.

4) Die Rückseite des Spiegels sollte genug Platz beinhalten, denn was man im Spiegel sehen kann wird dahinter erzeugt.

5) Die Level Blocks, die den Spiegel einrahmen, sollten auf "none" stehen.

 

VIEW* mirror =

{

       layer = 10;

}

 

function mirror_startup()

{

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

       camera.portal = mirror;

       set (mirror, NOSHADOW); // suppress shadows in the mirror

       set (mirror, NOPARTICLE); // suppress particles in the mirror

       set (mirror, PORTALCLIP); // clip at portal plane

       while (1)

       {

               proc_kill(4);

               mirror.genius = camera.genius;

               mirror.aspect = camera.aspect;

               mirror.arc = -camera.arc;

               mirror.x = camera.x;

               mirror.y = camera.portal_y - (abs(camera.portal_y - camera.y));

               mirror.z = camera.z;

               mirror.pan = -camera.pan;

               mirror.tilt = camera.tilt;

               mirror.roll = camera.roll;

               wait(1);

       }

}

 

aum82_faq1

 

aum82_faq2

 

aum82_faq3

 

 

F: Wie erreiche ich es, dass ein Model transparent wird, wenn der Spieler dahinter ist (so dass weniger als 60% noch zu sehen sind)? Ich brauche Gebäude, die transparent werden, wenn der Spieler hinter sie tritt.

A: Verwenden Sie dieses Beispiel für Ihren Code.

 

var temp_building;

 

ENTITY* building_ent;

 

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

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       VECTOR trace_pos;

       player = my; // I'm the player

       set(my, FLAG2);

       while (1)

       {

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

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

               temp.y = 0;

               temp.z = 0;

               my.pan += 4 * (key_a - key_d) * time_step;

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

               if (key_w + key_s > 0) // if the player is walking

               {

                       ent_animate(my, "walk", my.skill46, ANM_CYCLE); // play its "walk" frames animation

                       my.skill46 += 5 * time_step;

                       my.skill46 %= 100; // loop the animation

               }

               else // if the player is standing

               {

                       ent_animate(my, "stand", my.skill48, ANM_CYCLE); // play the "stand" frames animation

                       my.skill48 += 2 * time_step; // "stand" animation speed

                       my.skill48 %= 100; // loop the animation

               }

               vec_set(trace_pos.x, my.x);

               trace_pos.z += 20; // play with this value

               c_trace(trace_pos.x, camera.x, IGNORE_FLAG2 | USE_BOX);

               if (you)

               {

                       temp_building = handle(you);                        

                       set(you, TRANSLUCENT);

                       you.alpha = 60;

                       my.skill99 = 1;

               }

               else

               {

                       if (my.skill99 == 1) // building_ent exists?

                       {

                               building_ent = ptr_for_handle(temp_building);

                               reset (building_ent, TRANSLUCENT);

                       }

               }

               wait (1);

       }

}

 

function camera_startup() // camera code sample

{

       VECTOR temp;

       vec_set(camera.x, vector(0, 0, 1000));

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

       while (1)

       {

               vec_set(temp, player.x);

               vec_sub(temp, camera.x);

               vec_to_angle(camera.pan, temp);

               wait (1);

       }

}

 

 

F: Ich muss einige Namen aus einer Textdatei lesen und diese alphabetisch sortieren. Wie geht das?

A: Hier ist ein Beispiel.

 

FONT* arial_font = "Arial#20";

 

TEXT* names_txt =

{

       pos_x = 30;

       pos_y = 50;

       font(arial_font);

       strings = 30; // stores up to 30 names

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       string = "                    "; // 20 characters

       flags = visible;

}

 

function opendata_startup()

{

       var file_handle;

       var read_result = 0;

       var i = 0;

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

       file_handle = file_open_read("names.txt");

       while (read_result != -1) // read the data until the end of the file is reached

       {

               read_result = file_str_read(file_handle, (names_txt.pstring)[i]);

               i += 1;

       }

       str_cpy((names_txt.pstring)[i-1], "                    "); // reset the last string

       // all the names are read from the file and stored in the text strings here

       file_close(file_handle);

       while (!key_n) {wait (1);} // press the "N" key to sort the names

       while (key_n) {wait (1);}

       txt_sort(names_txt); // the names are sorted here

}

 

 

F: Wie erstelle ich einen Timer, der schneller als sys_seconds läuft? Ich brauche eine Uhr, bei der ein Tag etwa 20 bis 30 Minuten dauert.

A: Verwenden Sie den Code unten. Bei dieser Uhr vergeht ein Tag in 24 Minuten.

 

STRING* clock_str = "        "; // hh:mm ss = 8 chars

STRING* temp_str = "  ";  // 2 chars storing temporary data

 

FONT* arial_font = "Arial#20";

 

TEXT* clock_text =

{

       layer = 20;

       pos_x = 40;

       pos_y = 30;

       font(arial_font);

       string(clock_str);

       flags = visible;

}

 

function clock_startup()

{

       // limit the frame rate to 60 fps, 1 second for our clock = 1 / 60 real seconds

       fps_max = 60; // this clock runs 60 times faster than normal

       var my_seconds = 0;

       var my_minutes = 0;

       var my_hours = 0;

       var my_days = 0; // not used, but might come in handy someday

       while (1)

       {

               my_seconds += 1;

               if (my_seconds == 60) // a full minute was reached (in fact, a second has passed)?

               {

                       my_seconds = 0;

                       my_minutes += 1;

               }

               if (my_minutes == 60) // a full hour was reached (in fact, a minute has passed)?

               {

                       my_minutes = 0;

                       my_hours += 1;

               }

               if (my_hours == 24) // a full day has was reached (in fact, 24 minutes have passed)?

               {

                       my_seconds = 0;

                       my_hours = 0;

                       my_days += 1;

               }        

               str_for_num(clock_str, my_hours);

               str_cat(clock_str, ":"); // add : to create hh:mm

               if (my_minutes < 10) // add a "0" if the minutes are displayed with a digit

                       str_cat(clock_str, "0");

               str_for_num(temp_str, my_minutes);

               str_cat(clock_str, temp_str);

               wait (1);

       }

}

 

 

F: Nachdem mein Spiel startet, kann ich die Musik hören, die im Level platziert wurde. Sobald ich mich entferne, hört diese abrupt auf. Wieso geschieht das?

A: Fügen Sie Hintergrundmusik nicht im WED hinzu, das ist für statische Soundeffekte gedacht. Kopieren Sie den Code unten in Ihr Skript, wenn Sie Musik für Ihr Spiel brauchen.

 

var sound_volume = 50; // controls the sound volume

 

function music_startup()

{

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

       // replace my_music.wav with the name of your song

       media_handle = media_loop("my_music.wav", NULL, sound_volume);

}

 

 

F: Ist es möglich, den Rahmen des Fensters abzuschalten (so dass mein Panel als Rahmen fungiert) und den Exitknopf zu verwenden, den ich gestaltet habe?

A: Hier ist ein Beispiel.

 

BMAP* pointer_tga = "pointer.tga";

BMAP* quit1_pcx = "quit1.pcx";

BMAP* quit2_pcx = "quit2.pcx";

 

STRING* test_wmb = "test.wmb";

 

function quit_game();

 

PANEL* my_pan =

{

       layer = 15;

       pos_x = 0;

       pos_y = 0;

       bmap = "mypanel.tga"; // the frame panel

       button = 780, 0, quit2_pcx, quit1_pcx, quit2_pcx, quit_game, null, null;

       flags = visible;

}

 

void main()

{

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 2; // start in window mode

       video_window(NULL, NULL, 1, NULL);

       level_load (test_wmb);

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function quit_game()

{

       sys_exit(NULL);

}

 

aum82_faq4

 

 

F: Ich versuche, einen einfachen Sky Cube in einem mit lite-C geladenen Level zu implementieren, bekomme es aber leider nicht hin.

A: Hier ist ein Beispiel.

 

STRING* test_wmb = "test.wmb";

 

void main()

{

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 1; // start in full screen mode

       level_load (test_wmb);

       wait (3);

       ent_createlayer("skycube+6.tga", SKY | CUBE | VISIBLE , 1);

}

 

aum82_faq5

 

 

F: Ich brauche Code für einen Levelladebalken in meinem Spiel.

A: Hier kommt er schon.

 

var loading_percentage;

 

STRING* test_wmb = "test.wmb";

 

FONT* arial_font = "Arial#20";

 

function loading_percent(factor)

{

       loading_percentage = factor;

       loading_percentage = minv(100, loading_percentage); // loaded: 101 / 100 would look bad on the screen

}

 

PANEL* time_pan =

{

       layer = 15;

       digits (300, 300, "Loaded: %.f / 100", arial_font, 1, loading_percentage);        

       flags = visible;

}

 

void main()

{

       fps_max = 70;

       video_mode = 7; // run in 800x600 pixels

       video_depth = 32; // 32 bit mode

       video_screen = 1; // start in full screen mode

       on_level = loading_percent;

       level_load (test_wmb);

       while (loading_percentage < 100) {wait (1);} // the level is loaded here

       reset (time_pan, VISIBLE); // so let's hide the panel

}

 

 

F: Wie kann ich meinen Charakter für die Kamera sichtbar machen, auch wenn ein Block dazwischen ist, der den Weg versperrt?

A: Bitte sehr.

 

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

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       player = my; // I'm the player

       while (1)

       {

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

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

               temp.y = 0;

               temp.z = 0;

               my.pan += 4 * (key_a - key_d) * time_step;

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

               if (key_w + key_s > 0) // if the player is walking

               {

                       ent_animate(my, "walk", my.skill46, ANM_CYCLE); // play its "walk" frames animation

                       my.skill46 += 5 * time_step;

                       my.skill46 %= 100; // loop the animation

               }

               else // if the player is standing

               {

                       ent_animate(my, "stand", my.skill48, ANM_CYCLE); // play the "stand" frames animation

                       my.skill48 += 2 * time_step; // "stand" animation speed

                       my.skill48 %= 100; // loop the animation

               }

               if (c_trace(camera.x, player.x, USE_BOX)) // the player isn't visible?

               {

                       set(player, ZNEAR);

               }

               else

               {

                       reset(player, ZNEAR);

               }

               wait (1);

       }

}