Questions from the forum

Top  Previous  Next

Q: How can I detect if two particular objects hit each other?

A: Here's an example that uses three balls; two of them are special (particular).

 

function bounce_off()

{

       vec_to_angle(my.pan, bounce);

       my.pan += 5 - random(10); // add some randomness at each collision

       if (you) // collided with another entity?

       {

               if ((you.skill100 == 13579) && (my.skill100 == 13579)) // you and I are special entities?

               {

                       beep(); // do what you need here

               }

       }

 

action object1() // this is a special object

{

       my.emask |= (ENABLE_BLOCK | ENABLE_ENTITY); // the object is sensitive to block and entity collisions

       my.event = bounce_off;

       my.skill100 = 13579; // set this skill to a weird value in order to differentiate the object from the others

       while(1)

       {

               c_move(me, vector(5 * time_step, 0, 0), nullvector, 0); // move ahead, in the direction given by the pan angle

               wait(1);

       }

}

 

action object2() // this is a special object

{

       my.emask |= (ENABLE_BLOCK | ENABLE_ENTITY); // the object is sensitive to block and entity collisions

       my.event = bounce_off;

       my.skill100 = 13579; // set this skill to a weird value in order to differentiate the object from the others

       while(1)

       {

               c_move(me, vector(5 * time_step, 0, 0), nullvector, 0); // move ahead, in the direction given by the pan angle

               wait(1);

       }

}

 

action object3() // this is a regular object (just an example)

{

       my.emask |= (ENABLE_BLOCK | ENABLE_ENTITY); // the object is sensitive to block and entity collisions

       my.event = bounce_off;

       while(1)

       {

               c_move(me, vector(5 * time_step, 0, 0), nullvector, 0); // move ahead, in the direction given by the pan angle

               wait(1);

       }

}

 

 

Q: I would like to know if it is possible to put views from one or more cameras to small windows and display them on the screen.

A: There you go.

 

VIEW* camera1 =

{

       pos_x = 0;

       pos_y = 0;

       size_x = 512;

       size_y = 384;

       flags = VISIBLE;

}

 

VIEW* camera2 =

{

       pos_x = 512;

       pos_y = 0;

       size_x = 512;

       size_y = 384;

       flags = VISIBLE;

}

 

VIEW* camera3 =

{

       pos_x = 0;

       pos_y = 384;

       size_x = 512;

       size_y = 384;

       flags = VISIBLE;

}

 

VIEW* camera4 =

{

       pos_x = 512;

       pos_y = 384;

       size_x = 512;

       size_y = 384;

       flags = VISIBLE;

}

 

function init_startup()

{

       wait (-1);

       video_switch(8, 0, 0); // change the resolution to 1024 x 768 pixels

       camera.flags &= ~VISIBLE; // now hide the default camera

       // set the desired positions and angles for the 4 cameras

       vec_set (camera1.x, vector (800, 700, 100));

       camera1.pan = 50;

       camera1.tilt = 20;

       camera1.roll = 0;

       // settings for camera 2

       vec_set (camera2.x, vector (500, -600, 200));

       camera2.pan = 150;

       camera2.tilt = -30;

       camera2.roll = 20;

       // settings for camera 3

       vec_set (camera3.x, vector (-1000, 300, 300));

       camera3.pan = 110;

       camera3.tilt = -20;

       camera3.roll = 10;

       // settings for camera 4

       vec_set (camera4.x, vector (-800, -700, 200));

       camera1.pan = 220;

       camera1.tilt = -10;

       camera1.roll = 30;

}

 

aum78_faq1

 

 

Q: In my racing game I have an object to mark the start and goal. I want to start the watch when the player drives near it.

A: Here's an example.

 

var race_over = 0;

var total_time;

 

action start_counter() // attach this action to your object

{

       fps_max = 60; // feel free to use other values (75, etc) here

       var time_offset;

       while (!player) {wait (1);} // wait until player's car is loaded

       // wait until the player comes close to the object; play with 100

       while (vec_dist(player.x, my.x) > 100) {wait (1);}

       time_offset = total_frames; // ignore the frames that have passed until now

       while (!race_over) // this loop will run until the race is over

       {

               total_time = (total_frames - time_offset) / fps_max; // world's simplest racing timer ;)

               wait (1);

       }

}

 

PANEL* time_pan =

{

       layer = 150;

       digits(700, 20, 4.3 ,* , 1, total_time);

       flags = visible;

}

 

 

Q: I have a problem with A7. When I run the level after a build, no matter what script I use, the camera is messed up - it bounces all over the place. Any ideas why this is happening? I am using Windows XP with sp3.

A: Disconnect your joystick / gamepad or (even better) calibrate it using Windows' Control Panel => Game Controllers.

 

 

Q: Would it be possible to automatically allocate unique ID's to each entity that is created in Wed, without it being left to the user to find a way?

A: There you go.

 

var index = 0;

var my_entities[1000]; // stores the IDs for up to 1000 entities

 

ENTITY* temp_entity;

 

function setid_startup()

{

       wait (-3); // wait until the level is loaded

       you = ent_next(NULL); // retrieve the first entity from the level

       while(you) // run this loop until all the entities are processed

       {

               my_entities[index] = handle(you); // get a handle to the "you" entity and store it

               index += 1; // move on to the following array element

               you = ent_next(you); // get the next entity

       }

}

 

function entities_startup() // just a test function, allows you to control the entities

{

       while (!key_s) {wait (1);} // wait until the player presses the "S" key

       temp_entity = ptr_for_handle(my_entities[1]); // now get the entity with ID = 1

       temp_entity.scale_x = 3; // and set its scale_x parameter to 3

       temp_entity = ptr_for_handle(my_entities[2]); // now get the entity with ID = 2

       temp_entity.z += 100; // and move it upwards by 100 quants

}

 

 

Q: I'm building a quite big level, but when I want to compile it, I get the error: "Block outside level boundaries! What can i do to avoid this error?

A: Take a look at the wmb compiler window:

 

aum78_faq2

 

"Max level size" sets the maximum level size; you can increase this value up to 250,000 quants. If that's not enough, lower the scale of all your entities, objects, etc. If even that isn't enough, you can increase the size of the level even more IF you choose a bigger camera.clip_near value. If some of your important entities (weapons, etc) are clipped because of that you can set their z_near flag - look it up in the manual.

 

 

Q: When an object is not tall (like a little box) my player just climbs on it. How can I get rid of that? I'd like to keep the player at the floor level all the time.

A: Use regular player code (including gravity) and decrease the negative z component of the speed (temp.z in my example) a bit more, just like below:

 

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

{

       var movement_speed = 10; // movement speed

       VECTOR temp;

       player = my; // I'm the player

       set (my, INVISIBLE); // 1st person player

       while (1)

       {

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

               camera.x = player.x;

               camera.y = player.y;

               camera.z = player.z + 50 + 1.1 * sin(my.skill44);

               camera.pan = player.pan;

               camera.tilt += 5 * mouse_force.y * time_step;

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

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 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);

       }

}

 

 

Q: I am using some sprites for the wheels of my train; however, the sprites are always looking at the camera. How can I fix that?

A: Use this example as a base for your code.

 

function train_wheel1()

{

       while (1)

       {

               // play with the numerical values; they give the offset of the wheels in relation to the body

               vec_set(my.x, vector(-100, -40, 10));

               vec_rotate(my.x, you.pan);

               vec_add(my.x, you.x);

               my.pan = you.pan + 90;

               wait (1);

       }

}

 

function train_wheel2()

{

       while (1)

       {

               vec_set(my.x, vector(100, -40, 10));

               vec_rotate(my.x, you.pan);

               vec_add(my.x, you.x);

               my.pan = you.pan + 90;

               wait (1);

       }

}

 

function train_wheel3()

{

       while (1)

       {

               vec_set(my.x, vector(-100, 40, 10));

               vec_rotate(my.x, you.pan);

               vec_add(my.x, you.x);

               my.pan = you.pan + 90;

               wait (1);

       }

}

 

function train_wheel4()

{

       while (1)

       {

               vec_set(my.x, vector(100, 40, 10));

               vec_rotate(my.x, you.pan);

               vec_add(my.x, you.x);

               my.pan = you.pan + 90;

               wait (1);

       }

}

 

action my_train() // attach this action to your train

{

       var distance_covered;

       ent_create("wheel.tga", nullvector, train_wheel1);

       ent_create("wheel.tga", nullvector, train_wheel2);

       ent_create("wheel.tga", nullvector, train_wheel3);

       ent_create("wheel.tga", nullvector, train_wheel4);

       while (1)

       {        

               distance_covered = 0;

               while (distance_covered < 1000) // move 1000 quants forward

               {

                       distance_covered += c_move(my, vector(20 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

                       wait (1);

               }

               wait (-2); // make a 2 second pause at each end

               distance_covered = 0;

               while (distance_covered > -1000) // move 1000 quants backward

               {

                       distance_covered -= c_move(my, vector(-20 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

                       wait (1);

               }

               wait (-2); // make a 2 second pause at each end

       }

}

 

 

Q: Does anyone know how to put a fire particle effect behind the tail of a jet?

A: There you go.

 

BMAP* fire_tga = "fire.tga";

 

function fade_fire(PARTICLE *p)

{

       p.alpha -= 4 * time_step; // fade out the fire particles

       if (p.alpha < 0)

               p.lifespan = 0;

}

 

function fire_effect(PARTICLE *p)

{

      p->vel_x = 1 - random(2);

      p->vel_y = 1 - random(2);

      p->vel_z = 1 + random(1);

      p.alpha = 25 + random(50);

      p.bmap = fire_tga;

      p.size = 25; // gives the size of the fire particles

      p.flags |= (BRIGHT | MOVE);

      p.event = fade_fire;

}

 

action my_jet() // attach this action to your plane

{

       VECTOR jet_offset;

       // put your own code here

       // ........................

       while (1)

       {

               // put your own jet 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 circle

               // end of the simply flying example code

               

               // the jet particle effect code starts below

               // place the particle jet at the proper position, play with these values

               vec_set(jet_offset.x, vector(-100, -10, -20));

               vec_rotate(jet_offset.x, my.pan);

               vec_add(jet_offset.x, my.x);

               effect(fire_effect, 5, jet_offset.x, nullvector); // generate 5 fire particles each frame

               wait (1);

       }

}

 

aum78_faq3

 

 

Q: How do I make a level take me to another level after getting a key, instead of making the entire game in one map?

A: Follow these simple steps:

1) Paste the code below in one of your scripts.

2) Create two levels and name them level1.wmb and level2.wmb

3) Place a model entity in level1 and attach it the "my_key" action.

4) Place another model entity (a gate?) close to the end of the first level and attach it the action named "level_end".

The player will be moved from level1 to level2, but only if he has got the key first and has approached the gate at the end of the first level. You can, of course, repeat the process, adding more different levels, keys, and so on.

 

var got_key = 0;

 

STRING* message_str = "#50"; // this string can store up to 50 characters

 

TEXT* message_txt =

{

       pos_x = 200;

       pos_y = 20;

       string(message_str);

       flags = VISIBLE;

}

 

action my_key()

{

       set(my, PASSABLE);

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

       while (vec_dist (player.x, my.x) > 50) // this loop runs until the player picks up the key

       {        

               my.pan += 5 * time_step; // 5 gives the rotation speed of the key

               wait (1);

       }

       // the player has got the key here

       got_key = 1; // so let's set the variable named got_key to 1

       set(my, INVISIBLE);

}

 

action level_end() // takes the player to the second level if he has got the key first

{

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

       while (1)

       {

               if (vec_dist(player.x, my.x) < 100) // the player is closer than 100 quants to the exit gate?

               {

                       if (got_key) // the player has got the key?

                       {

                               level_load("level2.wmb"); // then let's load the second level

                               break; // and let's get out of this while loop, no need to run it anymore

                       }

                       else // the player has come close to the exit gate, but hasn't got the key

                       {

                               str_cpy(message_str, "You need to pick up the key first. Go and find it!");

                       }

               }

               else // the player is away from the exit gate

               {

                       str_cpy(message_str, ""); // so let's reset the message

               }

               wait (1);

       }

}