|
Fragen aus dem Forum |
Top Previous Next |
|
F: Ich habe mit einem kleinen Weltraumspiel angefangen und würde für die Abgase gerne ein Sprite und keine Partikel benutzen. Können Sie helfen? A: Hier ist ein Beispiel:
VECTOR engine_offset;
function engine_sprite() { set(my, BRIGHT); my.scale_x = 0.6; // set a proper scale for the engine sprite my.scale_y = my.scale_x; while (1) { my.pan = you.pan; vec_set (my.x, engine_offset.x); // choose a random frame for the engine - comment the following line if your sprite isn't animated my.frame = 1 + random(4); wait (1); } }
action my_ship() // attach this action to your space ship { ent_create("explo+5.tga", engine_offset.x, engine_sprite); // create the animated engine sprite while (1) { // put your own flight code here // the example below simply makes the plane fly in a circle c_move (my, vector(20 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); my.pan += 2 * time_step; // 2 sets the radius of the rotation circle // end of the simply flying example code
// the engine sprite code starts below // place the engine sprite at the proper position, play with the numerical values below vec_set(engine_offset.x, vector(-85, 0, -10)); vec_rotate(engine_offset.x, my.pan); vec_add(engine_offset.x, my.x); wait (1); } }
F: Wie mache ich es, dass c_scan nur eine bestimmte Gruppe von Entities aufspürt (beispielsweise nur Entities mit skill14==1) und alle anderen ignoriert? SCAN_FLAG2 ist zu diesem Zweck perfekt aber ich habe dieses Tag für eine andere Entitiy-Gruppe gebraucht und es gibt bedauerlicherweise keinen SCAN_FLAG3, SCAN_FLAG4... A: Hier ein Beispiel, das genaus das macht was Sie suchen:
var entities_detected = 0; // will store the number of entities that have their skill14 set to 1
action entity_detector() { random_seed(0); // generate a series of random numbers, used by the scanned entities set (my, PASSABLE); // set (my, INVISIBLE); // remove this comment after you have set the proper scanning value while (1) { // play with 500, it gives the scanning range c_scan(my.x, my.pan, vector(360, 90, 500), IGNORE_ME | SCAN_ENTS); wait (1); } }
function entity_was_scanned() { if (my.skill14 == 1) // the scanning will work only if this entity has its skill14 set to 1 { entities_detected += 1; my.event = NULL; // no need to scan this entity anymore, it was detected already } }
action scanned_entities() // place several entities in the level and attach them this action { wait (-3); // wait until the level is loaded my.emask |= ENABLE_SCAN; // this entity is sensitive to scanning my.event = entity_was_scanned; if (random(1) > 0.5) my.skill14 = 1; // this entity can be scanned if random(1) is greater than 0.5 }
PANEL* output_pan = { layer = 15; digits (500, 40, "Entities detected: %.0f", *, 1, entities_detected); flags = SHOW; }
F: Wie sieht es mit der Lizenz für Modelle und Code, die in AUM enthalten sind aus? Ich würde sie gerne zum Erstellen eines kommerziellen Spieles benutzen, das ich verkaufen will. A: Den Code aus AUM können Sie verwenden, ohne mir etwas bezahlen oder mich erwähnen zu müssen. Allerdings dürfen Sie den Rest der Ressourcen (Sounds, Modelle, Texturen etc.), die nicht für kommerzielle Zwecke freigegeben sind, nicht benutzen. Ich kümmere mich immer darum, das Recht zu haben, diese Ressourcen in AUM einbinden zu dürfen, habe aber nicht die Erlaubnis, sie an andere Leute weiter zu geben. s make sure that I have the right to include these resources in Aum, but I am not allowed to give them away to other people.
F: Ich kann in A7 keine passierbare Entity (Wasser) erstellen. Das "passable" Wasser / Terrain wird als "impassabler" normaler Boden behandelt. A: Hier ist ein einfaches Beispiel einer funktionierenden Player / Passable-Wasser-Entitykombination, die auf der Grundlage meines Artikels aus AUM 34 basiert:
#define amplitude skill1 #define water_speed skill2 #define number_of_vertices 1089 // the terrain entity used for the water has 33 x 33 vertices = 1089
var vertex_array[number_of_vertices]; var counter; var index;
action players_code() // attach this action to your player { var movement_speed = 20; VECTOR temp, players_sensor; set (my, INVISIBLE); player = my; 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); camera.pan = my.pan; camera.tilt += 5 * mouse_force.y * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 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 passable_water() { VECTOR temp; set (my, TRANSLUCENT | PASSABLE); my.alpha = 75; my.ambient = -100; if (my.amplitude == 0) { my.amplitude = 2; // default wave amplitude value } if (my.water_speed == 0) { my.water_speed = 10; // default wave speed value } counter = 0; while (counter < number_of_vertices) { vertex_array[counter] = random(360); // set random values in vertex_array counter += 1; } while (1) { index = 0; while (index < number_of_vertices) { vec_for_mesh(temp, my, index); // store the vertex coordinates in temp temp.z = sin(counter + vertex_array[index]) * my.amplitude; // change the z component vec_to_mesh(temp, my, index); // deform the terrain entity index += 1; } counter += my.water_speed * time_step; wait(1); } }
F: Kann ich *.wdl- und *.c-Skripte in einem Projekt mischen. Normalerweise verwende ich die template6 *wdl-Skripte aber ich kann in diesen Templates keine "shader.wdl" wie mtlFX.c finden. Wenn ich mtlFX.c include, bekomme ich jede Menge Fehler! A: Mixen Sie keinen *.wdl- und .c-Code: Sie werden jede Menge Ärger bekommen etwa unerklärte / nicht zu behebende Bugs etc. Besser ist es, sie schalten um auf lite-C. Das wird mit jedem Release besser und besser und Sie bekommen Zugriff auf eine Menge an neuen, starken Features.
F: Ich bräuchte einen Feind, der einem Pfad folgt und der, wenn sich der Player ihm nähert, anfängt den Player zu verfolgen. Wenn er nahe genug am Player dran ist, muß er auf den Player schiessen. A: Hier ein voll funktionierendes Beispiel:
var entity_speed = 3; var movement_enabled = 0; var dist_to_node; var current_node = 1; var angle_difference = 0;
VECTOR temp_angle; VECTOR pos_node; // stores the position of the node
SOUND* hit_wav = "hit.wav";
function remove_bullets() { my.event = NULL; ent_playsound (my, hit_wav, 1000); wait (-0.1); ent_remove (me); }
function move_bullets() { my.pan = you.pan; // the bullet and the enemy have the same pan angle my.emask |= (ENABLE_ENTITY | ENABLE_IMPACT | ENABLE_BLOCK); // the bullet is sensitive to other entities and level blocks my.event = remove_bullets; while (my) { my.skill1 = 15 * time_step; // bullet speed my.skill2 = 0; my.skill3 = 0; move_mode = IGNORE_YOU + IGNORE_PASSABLE + IGNORE_PUSH; // ignores the enemy (its creator = you) ent_move(my.skill1, nullvector); wait (1); } }
function move_target() { while(1) { if(movement_enabled) { entity_speed = minv(5, entity_speed + 0.5 * time_step); ent_animate(my, "walk", my.skill46, ANM_CYCLE); // play its "walk" frames animation my.skill46 += 5 * time_step; my.skill46 %= 100; // loop the animation c_move(my, vector(entity_speed * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE); vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x)); } wait(1); } }
action my_enemy() // attach this action to your enemy model { VECTOR temp, bullet_coords; while (!player) {wait (1);} move_target(); result = path_scan(me, my.x, my.pan, vector(90, 80, 400)); // scan the area looking for the player if (result) {movement_enabled = 1;} path_getnode (my, 1, pos_node, NULL); vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x)); // rotate towards the node while(1) { if ((c_scan(my.x, my.pan, vector(120, 90, 1000), IGNORE_ME) > 0) && (you == player)) // detected the player? break; // then get out of this loop! dist_to_node = vec_dist(my.x, pos_node); if(dist_to_node < 50) // close to the node? { current_node = path_nextnode(my, current_node, 1); if (!current_node) {current_node = 1;} // reached the end of the path? Then start over! path_getnode (my, current_node, pos_node, NULL); } wait(1); } // the enemy has spotted the player here while (1) // so it rotates towards it and starts chasing it { vec_set(temp, player.x); vec_sub(temp, my.x); vec_to_angle(my.pan, temp); my.tilt = 0; if (vec_dist (player.x, my.x) < 400) // the enemy has come close enough to the player? { movement_enabled = 0; // then it should stop walking my.skill46 = 0; if (random(1) > 0.92) // play with 0.92 { vec_set(bullet_coords.x, vector(25, -7, 14)); // play with these values vec_rotate(bullet_coords.x, my.pan); vec_add(bullet_coords.x, my.x); ent_create ("bullet.mdl", bullet_coords.x, move_bullets); // create a bullet while (my.skill46 < 100) { ent_animate(my, "standshoot", my.skill46, ANM_CYCLE); // play its "walk" frames animation my.skill46 += 15 * time_step; // "shoot" animation speed wait (1); } } } else // the player has moved away again? { movement_enabled = 1; // then start chasing him again } wait (1); } }
F: Ich möchte ein Sprite erstellen, das, wenn ich näher komme, weich einblendet und wenn ich mich davon wegbewege, sanft ausblendet. A: Nehmen Sie den Schnipsel unten:
var fading_distance = 1000;
action fading_entity() { set (my, TRANSLUCENT); my.alpha = 100; // make sure that the player code includes the "player = my;" line while (!player) {wait (1);} while (1) { while(vec_dist (player.x, my.x) < fading_distance) {wait (1);} while (my.alpha > 0) { my.alpha -= 5 * time_step; wait (1); } // the entity is invisible here while(vec_dist (player.x, my.x) > fading_distance) {wait (1);} while (my.alpha < 100) { my.alpha += 5 * time_step; wait (1); } } }
F: Ich bräuchte einen Feind, der auf den Player schiesst und der, wenn er stirbt, eine Health-Box erstellt, die vom Player aufgenommen werden kann. A: Hier ist ein Update meines Feind-Codes aus AUM32, der macht, was Sie brauchen.
STRING* bullet_mdl = "bullet.mdl";
SOUND* gothealth_wav = "gothealth.wav";
function fire_bullets(); // creates the bullets function remove_bullets(); // removes the bullets after they've hit something function got_shot(); function move_enemy_bullets();
#define idle 1 #define attacking 2 #define dead 3 #define status skill1 #define health skill10
function remove_bullets() // this function runs when the bullet collides with something { wait (1); // wait a frame to be sure (don't trigger engine warnings) ent_remove (my); // and then remove the bullet }
function health_box() { set (my, PASSABLE); while (!player) {wait (1);} // wait until the player comes close to the health box while (vec_dist (player.x, my.x) > 60) { my.pan += 5 * time_step; wait (1); } player.skill99 += 50; // player's health would be stored by its skill99 in this example snd_play (gothealth_wav, 50, 0); wait (-1); ent_remove(my); }
action my_enemy() // attach this action to your enemies { wait (-7); while (!player) {wait (1);} var idle_percentage = 0; var run_percentage = 0; var death_percentage = 0; VECTOR content_right; // tracks the content in front of the player VECTOR content_left; // tracks the content in front of the player VECTOR temp; set (my, POLYGON); // use accurate collision detection my.health = 100; my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // the enemy is sensitive to impact with player's bullets my.event = got_shot; // and runs this function when it is hit my.status = idle; // that's the same thing with my.skill1 = 1; (really!) while (my.status != dead) // this loop will run for as long as my.skill1 isn't equal to 3 { if (my.status == idle) // hanging around? { ent_animate(my, "stand", idle_percentage, ANM_CYCLE); // play the "stand" aka idle animation idle_percentage += 3 * time_step; // "3" controls the animation speed if (vec_dist (player.x, my.x) < 1000) // the player has come too close? { // scanned in the direction of the pan angle and detected the player? if ((c_scan(my.x, my.pan, vector(120, 60, 1000), IGNORE_ME) > 0) && (you == player)) { my.status = attacking; // then attack the player even if it hasn't fired at the enemy yet } } } if (my.status == attacking) // shooting at the player? { // the road is clear? then rotate the enemy towards the player if (c_content (content_right.x, 0) + c_content (content_left.x, 0) == 2) { vec_set(temp, player.x); vec_sub(temp,my.x); vec_to_angle(my.pan, temp); // turn the enemy towards the player } if (vec_dist (player.x, my.x) > 500) { vec_set(content_right, vector(50, -20, -15)); vec_rotate(content_right, my.pan); vec_add(content_right.x, my.x); if (c_content (content_right.x, 0) != 1) // this area isn't clear? { my.pan += 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle } vec_set(content_left, vector(50, 20, -15)); vec_rotate(content_left, my.pan); vec_add(content_left.x, my.x); if (c_content (content_left.x, 0) != 1) // this area isn't clear? { my.pan -= 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle } c_move (my, vector(10 * time_step, 0, 0), nullvector, GLIDE); ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation run_percentage += 6 * time_step; // "6" controls the animation speed } else { ent_animate(my, "alert", 100, NULL); // use the last frame from the "alert" animation here } if ((total_frames % 80) == 1) // fire a bullet each second { vec_for_vertex (temp, my, 8); // create the bullet at enemy's position and attach it the "move_enemy_bullets" function ent_create (bullet_mdl, temp, move_enemy_bullets); } if (vec_dist (player.x, my.x) > 1500) // the player has moved far away from the enemy? { my.status = idle; // then switch to "idle" } } wait (1); } while (death_percentage < 100) // the loop runs until the "death" animation percentage reaches 100% { ent_animate(my, "deatha", death_percentage, NULL); // play the "die" animation only once death_percentage += 3 * time_step; // "3" controls the animation speed wait (1); } set (my, PASSABLE); // allow the player to pass through the corpse now ent_create ("healthbox.mdl", my.x, health_box); wait (3); ent_remove (my); }
function got_shot() { if (you.skill30 != 1) {return;} // didn't collide with a bullet? Then nothing should happen my.health -= 35; if (my.health <= 0) // dead? { my.status = dead; // stop the loop from "action my_enemy" my.event = NULL; // the enemy is dead, so it should stop reacting to other bullets from now on return; // end this function here } else // got shot but not (yet) dead? { my.status = attacking; // same thing with my.skill1 = 2 } }
function move_enemy_bullets() { VECTOR bullet_speed; // this var will store the speed of the bullet my.skill30 = 1; // I'm a bullet // the bullet is sensitive to impact with other entities and to impact with level blocks my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK); my.event = remove_bullets; // when it collides with something, its event function (remove_bullets) will run my.pan = you.pan; // the bullet has the same pan my.tilt = you.tilt; // and tilt with the enemy bullet_speed.x = 50 * time_step; // adjust the speed of the bullet here bullet_speed.y = 0; // the bullet doesn't move sideways bullet_speed.z = 0; // or up / down on the z axis // the loop will run for as long as the bullet exists (it isn't "null") while (my) { // move the bullet ignoring its creator (the enemy) c_move (my, bullet_speed, nullvector, IGNORE_YOU); wait (1); } }
F: Ich arbeite an einer High-Score-Liste. Wie lasse ich den Player seinen Namen eintragen und weise den dann seinem Punktestand zu so, dass die Punktzahl neben seinem Namen steht? A: Hier ein Beispiel, das zählt wie oft man in 5 Sekunden mit der linken Maustaste klicken kann. Zum Starten klicken Sie einmal mit der rechten Maustaste.
var high_score = 0; var current_score = 0;
STRING* name_str = "#50"; STRING* input_str = "#50"; STRING* temp_str = "#10"; // just a temporary string
TEXT* name_txt = { pos_x = 30; pos_y = 30; string(name_str); flags = SHOW; }
TEXT* input_txt = { pos_x = 10; pos_y = 450; string(input_str); flags = SHOW; }
PANEL* score_txt = { pos_x = 0; pos_y = 0; digits (450, 30, "Current score: %.0f", *, 1, current_score); flags = SHOW; }
function init_startup() { var i; while (1) { while (!mouse_right) {wait (1);} while (mouse_right) {wait (1);} str_cpy(input_str, "#50"); // reset the input string current_score = 0; i = 0; while (i < 5) { if (mouse_left) {current_score += 1;} while (mouse_left) {wait (1);} i += time_step / 16; wait (1); } if (current_score > high_score) // a new high score was achieved? { high_score = current_score; str_cpy(input_str, "New high score! Please type in your name!"); wait (-3); // display the message for 3 seconds str_cpy(input_str, "#50"); // reset the string inkey(input_str); // now let's input player's name str_cpy(name_str, input_str); // let's update the high score name on the screen as well str_cat(name_str, " ---- "); // these characters separate the name and the actual high score str_for_num(temp_str, high_score); // convert the numerical value to a string str_cat(name_str, temp_str); // now add the high score to the string that contains the name of the player } str_cpy(input_str, "The test is over! Press the right mouse button to try again."); wait (1); } }
F: Wie erstellt man einen Code für die Maussensibilität, der es erlaubt, die Veränderung in Echtzeit zu sehen? A: Nehmen Sie diesen Schnipsel als Grundlage für Ihren Code:
var mouse_sensitivity = 2; var mouse_type = 0;
BMAP* slider_pcx = "slider.pcx"; BMAP* background_pcx = "background.pcx"; BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function toggle_mouse() { mouse_type += 1; mouse_type %= 2; mouse_mode = mouse_type * 2; }
function init_startup() { on_mouse_right = toggle_mouse; }
PANEL* gameover_pan = { bmap = background_pcx; layer = 15; pos_x = 20; pos_y = 30; // create a slider that changes mouse_sensitivity between 1 and 10 over 256 pixels hslider(22, 0, 256, slider_pcx, 1, 10, mouse_sensitivity); flags = SHOW; }
action players_code() // attach this action to your player { var movement_speed = 20; VECTOR temp, players_sensor; set (my, INVISIBLE); player = my; while (1) { my.pan -= 3 * mouse_force.x * mouse_sensitivity * time_step; camera.x = my.x; camera.y = my.y; camera.z = my.z + 50 + 1.1 * sin(my.skill44); camera.pan = my.pan; camera.tilt += 2.5 * mouse_force.y * mouse_sensitivity * time_step; vec_set (temp.x, my.x); temp.z -= 10000; temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 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); } }
|