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

       }

}

 

aum91_faq1

 

 

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;

}

 

aum91_faq2

 

 

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

       }

}

 

aum91_faq3

 

 

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

       }

}

 

aum91_questions4