|
Fragen aus dem Forum |
Top Previous Next |
|
F: Der Code aus dem Beitrag Player -> Car in AUM88 hat einen kleinen Bug: Das Gewehr kann auch dann schießen, wenn der Player es gar nicht aufnimmt. A: Ersetzen Sie die Funktion fire_bullets( ) durch die unten. Ich habe auch den Code in aum88code.zip berichtigt.
function fire_bullets() { if (weapon1.roll != 0) {return;} // the player didn't pick up the weapon yet? Then don't allow the gun to fire! if (players_health <= 0) {return;} // can't fire bullets if the player is dead if (player_in_car == 1) {return;} // can't fire bullets while the player is driving VECTOR temp; proc_kill(4); // don't allow more than 1 copy of this function to run while (mouse_left) // this loop runs for as long as the left mouse button is pressed { front_offset -= 1; // move the weapon backwards a bit vec_for_vertex (temp.x, weapon1, 29); // get the coordinates for the bullets' origin // create the bullet at camera's position and attach it the "move_bullets" function ent_create (bullet_mdl, temp.x, move_bullets); ent_create (muzzle_tga, temp.x, display_muzzle); // create the gun muzzle snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100 wait (-0.07); // fire 7 bullets per second (2 * 0.07 * 7 = 1 second) front_offset += 1; // restore the position of the weapon wait (-0.07); } }
F: Ich versuche ein Stück Code zu schreiben, der es meinen Feinden ermöglicht erneut zu starten. Wenn einer der Feinde stirbt, wird ein anderer generiert. Können Sie helfen? A: Hier ein Schnipsel, der Feinde aus einer Höhle heraus erstellt. Sie können natürlich auch jede andere Entity verwenden. Klicken Sie mit der linken Maustaste auf einen Feind, um ihn zu töten.
ENTITY* enemy;
BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function destroy_enemy() // this function runs if the player clicks the enemy using the left mouse button { enemy = NULL; // free the enemy pointer ent_remove(my); // remove the enemy from the level; another one will be created }
function move_enemy() { var anim_percentage = 0; my.emask = ENABLE_CLICK; // the enemy is sensitive to mouse clicks my.event = destroy_enemy; my.z += 50; // create the enemy 50 quants above the origin of the cave model my.pan = random(360); // and give it a random pan angle while (1) { c_move (my, vector(5 * time_step, 0, 0), nullvector, GLIDE); // "5" controls the walking speed ent_animate(my, "walk", anim_percentage, ANM_CYCLE); anim_percentage += 3 * time_step; // "3" controls the animation speed anim_percentage %= 100; wait (1); } }
action enemy_respawner() // attach this action to your cave model, etc { set (my, PASSABLE); while (1) { while (enemy) {wait (1);} // don't do anything if the enemy exists already // create the enemy and attach it the function named move_enemy enemy = ent_create("guard.mdl", my.x, move_enemy); } }
F: Um die beste Auflösung für mein Spiel herauszufinden, verwende ich Ihre Funktion aus den FAQs in AUM88. Wenn ich jedoch die Auflösung per F5-Taste verändere, verlieren alle Panels ihre Positionen. Wie kann ich sicherstellen, dass meine Panels bei jeder Auflösung korrekt aligned sind? A: Hier ein Beispiel mit vier Panels (eines für jede Bildschirmecke), die bei jeder Auflösung aligned bleiben:
BMAP* upperleft_tga = "upperleft.tga"; BMAP* upperright_tga = "upperright.tga"; BMAP* lowerleft_tga = "lowerleft.tga"; BMAP* lowerright_tga = "lowerright.tga";
PANEL* upperleft_pan = { bmap = upperleft_tga; layer = 15; flags = SHOW; }
PANEL* upperright_pan = { bmap = upperright_tga; layer = 15; flags = SHOW; }
PANEL* lowerleft_pan = { bmap = lowerleft_tga; layer = 15; flags = SHOW; }
PANEL* lowerright_pan = { bmap = lowerright_tga; layer = 15; flags = SHOW; }
function align_startup() { while (1) { // that's the easy part; the panel from the upper left corner will always be placed at x = 0 and y = 0; upperleft_pan.pos_x = 0; upperleft_pan.pos_y = 0; // the panel from the upper right corner has x = horizontal resolution - panel bitmap width and y = 0; upperright_pan.pos_x = screen_size.x - bmap_width(upperright_tga); upperright_pan.pos_y = 0; // the panel from the lower left corner has x = 0 and y = vertical resolution - panel bitmap height lowerleft_pan.pos_x = 0; lowerleft_pan.pos_y = screen_size.y - bmap_height(lowerleft_tga); // the panel from the lower right corner x = horizontal resolution - panel bitmap width // and y = vertical resolution - panel bitmap height lowerright_pan.pos_x = screen_size.x - bmap_width(lowerright_tga); lowerright_pan.pos_y = screen_size.y - bmap_height(lowerright_tga); wait (1); } }
F: Welchen Event-Typus muß ich nehme (impact, push etc.) wenn ich will, daß ein Ball einen Event auslöst sobald er durch ein passables Sprite geht? A: Die einfachste (und genauere) Methode ist es, vec_dist zu verwenden. Man prüft den Abstand zwischen dem Zentrum des Balls und dem Zentrum des Sprites - hier ein Beispiel:
var movement_speed = 10;
ENTITY* ball;
action simple_ball() // attach this action to your ball entity { VECTOR temp; ball = my; while (1) { temp.x = movement_speed * (key_cuu - key_cud) * time_step; temp.y = movement_speed * (key_cul - key_cur) * 0.6 * time_step; temp.z = 0; // use gravity, etc here c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE); wait (1); } }
action passable_sprite() // attach this action to your passable sprite { set (my, PASSABLE); while (!ball) {wait (1);} // wait until the player model is loaded while (1) { if (vec_dist (ball.x, my.x) < 50) // play with 50 { beep(); // do what you need here // get rid of the "break" line if you want to trigger the event several times break; // get out of the while loop } wait (1); } }
F: Wie kann ich die große Bitmap, die als Höhenmap für mein Terrain dient in diverse Kacheln aufteilen? A: Die meisten Grafik-Editoren haben Tools, die es ermöglichen, Bilder für´s Web aufzuteilen. Sie können diese Tools zum Aufteilen Ihrer Höhenmap in diverse kleinere Bitmaps verwenden. So geht es mit Paint Shop Pro 9:
F: Ich habe zwei Kugeln und möchte gerne eine 3D-Linie erstellen, die sie verbindet. Wie mache ich das? A: Hier ist ein Beispiel:
ENTITY* s1; ENTITY* s2;
action sphere1() // attach this line to the first sphere { s1 = my; // I'm the first sphere }
action sphere2() // attach this line to the second sphere { s2 = my; // I'm the second sphere }
function line_startup() { while (!s1 || !s2) {wait (1);} while (1) { // set the starting point for the 3D line draw_line3d(vector(s1.x, s1.y, s1.z), NULL, 100); // draw a blue line that connects s1 and s2 draw_line3d(vector(s2.x, s2.y, s2.z), vector(255, 0, 0), 100); wait (1); } }
F: Wie stellen Sie fest ob der Player einen bestimmten Raum betritt? A: Dazu können Sie c_scan benutzen.
STRING* detected_str = "#50";
TEXT* detected_txt = { pos_x = 200; pos_y = 20; string(detected_str); flags = SHOW; }
// attach this action to an entity that is placed inside the room, near the door action detect_player() { set (my, PASSABLE); // set (my, INVISIBLE); // remove this comment after you have set the proper scanning value while (!player) {wait (1);} VECTOR temp[3]; while (1) { // scan for the player every 5 frames to save a bit of cpu power // the player will be detected if it comes closer than 200 quants to this entity c_scan(my.x, my.pan, vector(360, 90, 200), IGNORE_ME | SCAN_ENTS); // play with 200 if (you == player) // detected the player? { beep(); beep(); // do what you need here (a level_load instruction, etc) str_cpy((detected_txt.pstring)[0], "The player has entered the room"); break; // get out of the loop, the player has entered the room } else { str_cpy((detected_txt.pstring)[0], "The player is outside the room"); } wait (5); } }
F: Wie kann ich die Kamerabewegung abschalten, wenn der Anwender auf die Nulltaste drückt? Und wie kann ich die Kamerabewegung anschalten, ohne die Nulltaste drücken zu müssen? A: Die Nulltaste funktioniert nur solange Sie das Spiel entwickeln. In der gepublishten Version Ihres Spiels funktioniert sie nicht, Sie müssen dazu also gar nichts tun. Um eine sich frei bewegende Kamera zu bekommen, ohne die Nulltaste drücken zu müssen, platzieren Sie irgendeine Entity in Ihrem Level und weisen Sie ihr die folgende Aktion. Vergessen Sie nicht das Level nochmal zu 'builden'.
// place a model in your level using Wed and then attach it this action action my_camera() { var speed_factor = 5; VECTOR camera_speed; set (my, INVISIBLE); // make the camera entity invisible while (1) { // use the left and right mouse buttons to move forward and backward; 5 gives the movement speed camera_speed.x = speed_factor * (mouse_left - mouse_right); // press and hold the shift key to increase the movement speed 6 times, useful for large areas if (key_shift) { speed_factor = 30; // 5 * 6 } else { speed_factor = 5; // restore the default movement speed if the shift key isn't pressed } // no need to change the y and z components of the camera_speed vector camera_speed.y = 0; camera_speed.z = 0; my.pan -= 5 * mouse_force.x * time_step; // 5 = horizontal rotation speed my.tilt -= 3 * mouse_force.y * time_step; // 3 = vertical rotation speed // now move the entity in the direction given by its pan and tilt angles c_move (my, camera_speed.x, nullvector, IGNORE_PASSABLE | GLIDE); // the camera will inherit the same position and angles with the entity vec_set (camera.x, my.x); camera.pan = my.pan; camera.tilt = my.tilt; wait(1); } }
F: Gibt es irgendeine Möglichkeit, alle Entities zu scannen und ihre Skills zu prüfen, ohne an der Nächsten stoppen zu müssen? A: c_scan findet in der Tat nur die nächstliegende Entity, kann aber den Event EVENT_SCAN für sämtliche Entities, die in den Scankegel kommen, auslösen. Hier ist ein Beispiel:
var entity_id = -1;
var value[100];
function show_info() // runs if the entities are scanned by the scanner { while (event_type == EVENT_SCAN) { my.skill1 = 123; // set skill1 to 123 while the entity is being scanned value[my.skill2] = my.skill1; // and copy it to the "value" array my.scale_z = 4; // also increase the z scale of the entity that is being scanned wait (1); } my.scale_z = 1; // restore the original z scale of the entity if it isn't being scanned anymore my.skill1 = 0; // set skill1 to zero if the entity isn't scanned value[my.skill2] = 0; // reset "value" }
action scanner() // attach this action to the entity that will scan the area { while (1) { // scan using a pan angle of 120 degrees, a tilt of 60 degrees and a range of 500 quants c_scan(my.x, my.pan, vector (120, 60, 500), 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); } }
action scanned_objects() // attach this action to several entities { entity_id += 1; my.skill2 = entity_id; my.emask |= ENABLE_SCAN; // the scanned entities are sensitive to c_scan instructions my.event = show_info; }
PANEL* values_pan = // displays the first 10 "value" values { layer = 15; digits(20, 20, 4 ,* , 1, value[0]); digits(20, 40, 4 ,* , 1, value[1]); digits(20, 60, 4 ,* , 1, value[2]); digits(20, 80, 4 ,* , 1, value[3]); digits(20, 100, 4 ,* , 1, value[4]); digits(20, 120, 4 ,* , 1, value[5]); digits(20, 140, 4 ,* , 1, value[6]); digits(20, 160, 4 ,* , 1, value[7]); digits(20, 180, 4 ,* , 1, value[8]); digits(20, 200, 4 ,* , 1, value[9]); flags = SHOW; }
F: Hat irgendjemand Vorschläge für ein einfachws Schwerkraft-System, das effektiv funkrioniert? Ich brauche, daß meine Objekte fallen, aber auch den Boden entlanggleiten und Schrägen hinabgleiten können. A: Es gibt keine Physik die so ist wie die, die von einer Physik-Engine geboten wird.
action physics_box() // this should be a function, but it can be used as a standalone action { VECTOR kick_speed; ph_setgravity (vector(0, 0, -386)); set (my, SHADOW); phent_settype (my, PH_RIGID, PH_BOX); phent_setmass (my, 20, PH_BOX); phent_setfriction (my, 50); phent_setdamping (my, 50, 50); phent_setelasticity (my, 30, 30); kick_speed.x = 250; // kick speed kick_speed.y = 0; kick_speed.z = 50; // make it move a bit upwards as well vec_rotate(kick_speed, camera.pan); // kick it depending on the angle of the camera phent_addvelcentral(my, kick_speed); // kick the box, comment this line to turn the box into a regular one }
function create_boxes() { VECTOR box_pos; vec_set(box_pos.x, vector(100, 0, 0)); vec_rotate (box_pos.x, camera.pan); vec_add (box_pos.x, camera.x); ent_create ("box.mdl", box_pos.x, physics_box); }
function init_startup() { on_c = create_boxes; // creates a box when the player presses the "c" key }
|