Questions from the forum

Top  Previous  Next

Q: When I run my wmb level, it uses about 65 MB of ram, but when I run it using the script it needs about 255 MB! My code loads several entities and scales them  using values from an xml file. Is there a problem with my code?

A: Probably not; however, the entities that are created at runtime would use less memory if their skins would be smaller. As a general rule, your code can't use too much memory, unless your are doing some crazy stuff like defining huge multi-dimensional arrays, and so on.

 

 

Q: I was wondering if it is possible to make a door open and stay open when the player comes near it and close when the player moves out of range.

A: There you go.

 

var clockwise = 1; // the door will rotate clockwise, set it to 0 if you need a conter-clockwise rotation

 

SOUND* dooropens_wav = "dooropens.wav";

 

action my_door()

{

       var init_pan;

       init_pan = my.pan;

       while (!player) {wait (1);} // make sure to add the "player = my;" line of code to your player action

       while (1)

       {

               // this section opens the door

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

               snd_play (dooropens_wav, 100, 0);

               if (clockwise) // the door is supposed to rotate clockwise?

               {

                       while (my.pan > init_pan - 90)

                       {

                               c_rotate (me, vector(-4 * time_step, 0, 0), IGNORE_MAPS);

                               wait (1);

                       }

               }

               else // default = rotate counter-clockwise

               {

                       while (my.pan < init_pan + 90)

                       {

                               c_rotate (me, vector(4 * time_step, 0, 0), IGNORE_MAPS);

                               wait (1);

                       }

               }

               // this section closes the door

               while (vec_dist (player.x, my.x) < 300) {wait (1);} // wait until the player moves away, play with 300

               snd_play (dooropens_wav, 100, 0);

               if (clockwise) // the door is supposed to rotate clockwise?

               {

                       while (my.pan < init_pan)

                       {

                               c_rotate (me, vector(4 * time_step, 0, 0), IGNORE_MAPS);

                               wait (1);

                       }

               }

               else // default = rotate counter-clockwise

               {

                       while (my.pan > init_pan)

                       {

                               c_rotate (me, vector(-4 * time_step, 0, 0), IGNORE_MAPS);

                               wait (1);

                       }

               }        

               wait (1);

       }

}

 

 

Q: I'm trying to create a character selection snippet; the player should go through all the available characters by clicking a model. How can I do that?

A: Here's an example that uses 3 different models; feel free to add as many as you want.

 

var character_type = 1; // the first model is the default one

 

BMAP* arrow_pcx = "arrow.pcx";

 

STRING* level1_wmb = "test.wmb";

 

function start_game()

{

       level_load (level1_wmb); // now load the "real" level

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

       // load the proper player model, depending on the "character_type" value

       if(character_type == 1)

       {

               ent_morph(player, "character1.mdl");

       }

       if(character_type == 2)

       {

               ent_morph(player, "character2.mdl");

       }

       if(character_type == 3)

       {

               ent_morph(player, "character3.mdl");

       }

       // add as many characters as you want here        

}

 

function mouse_startup()

       on_mouse_right = start_game; // click the right mouse button to start the game using the selected character

       mouse_map = arrow_pcx; // use an arrow bitmap for the mouse pointer

       mouse_mode = 2;

       while (mouse_mode > 0)

       { 

                 vec_set(mouse_pos, mouse_cursor);

                  wait(1);

       }

}

 

function set_character()

{

       character_type %= 3;

       character_type += 1;

       if(character_type == 1)

       {

               ent_morph(my, "character1.mdl");

       }

       if(character_type == 2)

       {

               ent_morph(my, "character2.mdl");

       }

       if(character_type == 3)

       {

               ent_morph(my, "character3.mdl");

       }

       // add as many characters as you want here

}

       

// attach this action to character1.mdl (your default character model)

action my_character()

{

       my.emask |= ENABLE_CLICK;

       my.event = set_character;

}

 

 

Q: How can I have my enemies detect me from far away when they can see me and also detect me when I'm behind (but very close to) them?

A: Use the code below.

 

action smart_enemy() // attach this action to your enemies

{

       // make sure that the player action includes this line of code "player = my;"

       while (!player) {wait (1);}

       while (1)

       {

               // the enemy will "see" the player if it is in front, up to 1000 quants away

               if ((c_scan(my.x, my.pan, vector(180, 90, 1000), IGNORE_ME) > 0) && (you == player))

               {

                       beep(); // put your own code

               }

               if (vec_dist (player.x, my.x) < 150) // the player has come really close to the enemy?

               {

                       beep(); // do something else if the player tries to sneak behind the enemy (or do the same thing)

               }

               wait (1);

       }

}

 

 

Q: Do you have some code for a bird that would fly randomly in a big outdoor level?

A: Attach the action below to your bird model.

 

// place the birds at slightly different heights and pan angles if you plan to use several birds

action pretty_bird()

{

       set (my, PASSABLE);

       var bird_distance;

       var anim_percentage;

       while (1)

       {

               bird_distance = 200 + random(1000); // move 200... 1200 quants in a random direction        

               my.skill1 = 0;

               while (my.skill1 < bird_distance)

               {

                       my.skill1 += c_move (my, vector(10 * time_step, 0, 0), nullvector, IGNORE_PASSABLE);

                       ent_animate(my, "fly", anim_percentage, NULL);

                       anim_percentage += 5 * time_step;

                       anim_percentage %= 100;

                       wait (1);

               }

               // now add 10... 60 degrees to the current angle of the bird slowly while it keeps flying

               my.skill2 = my.pan + (10 + random(50)); // my.skill2 will store the new angle of the bird

               while (my.pan < my.skill2)

               {

                       my.pan += 1 * time_step; // change the rotation speed by playing with 1

                       // the bird will fly a little slower while it is changing its pan angle

                       c_move (my, vector(8 * time_step, 0, 0), nullvector, IGNORE_PASSABLE);

                       ent_animate(my, "fly", anim_percentage, NULL);

                       anim_percentage += 4 * time_step;

                       anim_percentage %= 100;

                       wait (1);

               }

               // the bird is now oriented in the direction of its new pan angle here and can move another 200...1000 quants

               wait (1);

       }

}

 

 

Q: I can't assign an action in Wed from an included script. If I create actions in my main script, they appear in Wed; I have no errors and I can call the included actions in my main script, but I want to attach them to my entities using Wed. Does anyone have an idea?

A: I have seen this happening some time ago. The solution is simple: type in the correct name of the action in the "Choose Action" text field, even if its name doesn't appear in the action list, and then click OK.

 

aum69_faq1

 

 

 

Q: I am trying to make a ball toggle its 2 skins when it collides with the wall.

A: Here's a snippet that should help you.

 

var ball_speed = 25;

 

function ball_event()

{

       if (event_type == EVENT_BLOCK) // collided with the level geometry?

       {

               my.skin %= 2;

               my.skin += 1;

       }

       vec_to_angle (my.pan, bounce);

       // don't allow movement in 3D, comment this line if you plan to create a 3D breakout game

       my.tilt = 0;

       // add some randomness to the ball (we wouldn't want to see it bouncing back and forth between 2 obstacles)

       my.pan += 1 - random(2);

}

 

action my_ball()

{

       randomize();

       my.pan = 70 - random(140);

       my.emask = ENABLE_BLOCK;

       my.event = ball_event;

       while(1)

       {

               c_move (my, vector(ball_speed * time_step, 0, 0), nullvector, IGNORE_PASSABLE);

               wait(1);

       }

}

 

 

Q: I would like to know more about the inner works of the "wait" instruction. When the number is positive, what is the time that the function pauses? What can "wait(50)" be replaced with using "wait(-x)" ?

A: If you are using positive "wait" values, they will always depend on the frame rate. As an example, if we lock the frame rate to 60 fps using fps_max and the computer is able to deliver at least 60 fps, each frame will last for 1 second / 60 frames = 0.0166 seconds = 16.6 milliseconds. This means that if you would use a "wait(50);" instruction, the pause would be 50 * 16.6 = 0.83 seconds, so you could use something like "wait(-0.83);" to get the same duration.

 

 

 

Q: I'd like to have a panel that is barely visible (only a small edge should be visible on the screen) but slides until it is displayed completely when the player moves the mouse pointer over it.

A: There you go:

 

var panel_edge = -250; // the panel will be moved 250 pixels outside the screen on the monitor's y axis

 

BMAP* sliding_pcx = "sliding.pcx"; // I have used a 256x256 pixels bitmap for the panel

BMAP* arrow_pcx = "arrow.pcx"; // mouse pointer bitmap

 

// this panel will be displayed in the upper left corner of the screen

// you can place it anywhere else and the code will continue to work properly

PANEL* sliding_pan =

{

       bmap = sliding_pcx;

       pos_x = 0;

       pos_y = 0; // we are using a negative value here in order to hide a part of the panel

       // feel free to add buttons, digits, etc here

       flags =  VISIBLE;

}

 

function slide_panel_startup()

{

       var min_pan_x;

       var max_pan_x;

       var min_pan_y;

       var max_pan_y;

       sliding_pan.pos_y = panel_edge;

       while (1)

       {

               min_pan_x = sliding_pan.pos_x;

               max_pan_x = sliding_pan.pos_x + bmap_width(sliding_pcx);

               min_pan_y = sliding_pan.pos_y;

               max_pan_y = sliding_pan.pos_y + bmap_height(sliding_pcx);

               if ((mouse_pos.x >= min_pan_x) && (mouse_pos.x <= max_pan_x) && (mouse_pos.y >= min_pan_y) && (mouse_pos.y <= max_pan_y))

               {

                       // the mouse pointer is placed over the panel here, so let's display it completely                

                       while (sliding_pan.pos_y < -1) // we are using a panel that slides vertically here

                       {

                               sliding_pan.pos_y += 20 * time_step; // 20 gives the sliding speed

                               wait (1);                                

                       }

                       sliding_pan.pos_y = 0;

               }

               else // the mouse isn't placed in the proper position here, so let's move the panel to its original (hidden) position

               {

                       while (sliding_pan.pos_y > panel_edge + 1)

                       {

                               sliding_pan.pos_y -= 15 * time_step; // 15 gives the sliding speed

                               wait (1);                                                                

                       }

                       sliding_pan.pos_y = panel_edge;

               }

               wait (1);

       }

}

 

function mouse_startup()

       mouse_map = arrow_pcx;

       mouse_mode = 2;

       while (mouse_mode > 0)

       { 

                 vec_set(mouse_pos, mouse_cursor);

                  wait(1);

       }

}

 

 

Q: I have a puzzle in my game in which the 1st person player can only get past a door if he has found a hidden key. How can I do that?

A: Use this piece of code.

 

var got_key = 0; // this var will be set to 1 as soon as the player gets the key

 

SOUND* gotkey_wav = "gotkey.wav";

SOUND* dooropens_wav = "dooropens.wav";

 

action my_key()

{

       set (my, PASSABLE);

       while (!player) {wait (1);}

       while (vec_dist (player.x, my.x) > 50) {wait (1);} // wait until the player comes really close to the key

       got_key = 1;

       snd_play (gotkey_wav, 100, 0);

       wait(-1);

       ent_remove (my);

}

 

action key_door()

{

       var init_pan;

       init_pan = my.pan;

       while (!player) {wait (1);} // make sure to add the "player = my;" line of code to your player action

       while (!got_key) {wait (1);}

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

       snd_play (dooropens_wav, 100, 0);

       while (my.pan > init_pan - 90) // rotate the door clockwise

       {

               c_rotate (me, vector(-4 * time_step, 0, 0), IGNORE_MAPS);

               wait (1);

       }

       // use the loop below if you need to rotate the door counter-clockwise

//        while (my.pan < init_pan + 90) // rotate the door clockwise

//        {

//                c_rotate (me, vector(4 * time_step, 0, 0), IGNORE_MAPS);

//                wait (1);

//        }

}