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