Questions from the forum

Top  Previous  Next

Q: I would like to create a 2D game that uses 4 different car sprites (for the 4 movement directions) and allows you to control the car using the arrow keys.

A: Here's an example:

 

BMAP* carleft_tga = "carleft.tga";

BMAP* carright_tga = "carright.tga";

BMAP* carup_tga = "carup.tga";

BMAP* cardown_tga = "cardown.tga";

 

var direction = 0; // 1 = up, 2 = down, 3 = left, 4 = right

 

PANEL* carleft_pan =

{

       bmap = carleft_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* carright_pan =

{

       bmap = carright_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* carup_pan =

{

       bmap = carup_tga;

       pos_x = 400;

       pos_y = 300;

}

 

PANEL* cardown_pan =

{

       bmap = cardown_tga;

       pos_x = 400;

       pos_y = 300;

}

 

function control_car_startup()

{

       set(carleft_pan, VISIBLE); // this will set the initial car orientation

       direction = 3;

       while (1)

       {

               if (key_cuu)

               {

                       if (direction == 2)

                       {

                               carup_pan.pos_x = cardown_pan.pos_x;

                               carup_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               carup_pan.pos_x = carleft_pan.pos_x;

                               carup_pan.pos_y = carleft_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               carup_pan.pos_x = carright_pan.pos_x;

                               carup_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cuu)

                       {

                               clamp(carup_pan.pos_y, 0, 570);

                               clamp(carup_pan.pos_x, 0, 770);

                               set(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);

                               carup_pan.pos_y -= 5 * time_step;

                               wait (1);

                       }

                       direction = 1;

               }

               if (key_cud)

               {

                       if (direction == 1)

                       {

                               cardown_pan.pos_x = carup_pan.pos_x;

                               cardown_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               cardown_pan.pos_x = carleft_pan.pos_x;

                               cardown_pan.pos_y = carleft_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               cardown_pan.pos_x = carright_pan.pos_x;

                               cardown_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cud)

                       {

                               clamp(cardown_pan.pos_y, 0, 570);

                               clamp(cardown_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               set(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);        

                               cardown_pan.pos_y += 5 * time_step;

                               wait (1);

                       }

                       direction = 2;

               }

               if (key_cul)

               {

                       if (direction == 1)

                       {

                               carleft_pan.pos_x = carup_pan.pos_x;

                               carleft_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 2)

                       {

                               carleft_pan.pos_x = cardown_pan.pos_x;

                               carleft_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 4)

                       {

                               carleft_pan.pos_x = carright_pan.pos_x;

                               carleft_pan.pos_y = carright_pan.pos_y;

                       }

                       while (key_cul)

                       {

                               clamp(carleft_pan.pos_y, 0, 570);

                               clamp(carleft_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               set(carleft_pan, VISIBLE);        

                               reset(carright_pan, VISIBLE);        

                               carleft_pan.pos_x -= 5 * time_step;

                               wait (1);

                       }

                       direction = 3;

               }

               if (key_cur)

               {

                       if (direction == 1)

                       {

                               carright_pan.pos_x = carup_pan.pos_x;

                               carright_pan.pos_y = carup_pan.pos_y;

                       }

                       if (direction == 2)

                       {

                               carright_pan.pos_x = cardown_pan.pos_x;

                               carright_pan.pos_y = cardown_pan.pos_y;

                       }

                       if (direction == 3)

                       {

                               carright_pan.pos_x = carleft_pan.pos_x;

                               carright_pan.pos_y = carleft_pan.pos_y;

                       }

                       while (key_cur)

                       {

                               clamp(carright_pan.pos_y, 0, 570);

                               clamp(carright_pan.pos_x, 0, 770);

                               reset(carup_pan, VISIBLE);

                               reset(cardown_pan, VISIBLE);        

                               reset(carleft_pan, VISIBLE);        

                               set(carright_pan, VISIBLE);        

                               carright_pan.pos_x += 5 * time_step;

                               wait (1);

                       }

                       direction = 4;

               }

               wait (1);

       }

}

 

 

Q: I want to move my model using the WSAD keys; the script uses c_move as shown below. How fast (in quants) will the model move in the level? Is the speed dependent on the fps of the computer?

 

speed.x = 5 * (key_w - key_s);

...............................................

c_move (my, vector(speed.x, speed.y, speed.z), nullvector, GLIDE);

 

A: The movement speed depends on the frame rate indeed; in your example, the model will move with a speed of 5 quants per frame. This means that if the frame rate is 100 fps, the model will move with 500 quants per second. You can make the movement independent of the speed of the computer by limiting the frame rate to a smaller value (fps_max = 60 or so) or, even better, by multiplying the speed with time_step. Check out the magazine to see several examples.

 

 

Q: I'd like to create a radar that scans around it and highlights all the entities that are within its range.

A: Use this example.

 

action entity_radar() // attach this action to the radar entity

{

       while (1)

       {

               // scan all the entities that are closer than 1000 quants to this entity

               c_scan(my.x, my.pan, vector(360, 180, 1000), IGNORE_ME);

               wait (1);

       }

}

 

function i_am_scanned()

{

       while (event_type == EVENT_SCAN)

       {

               my.ambient = 100;

               wait (1);

       }

       my.ambient = 100;

}

 

action scanned_entities() // attach this action to the scanned entities

{

       my.emask |= ENABLE_SCAN; // make the entity sensitive to scanning

       my.event = i_am_scanned;

}

 

 

Q: Is there a way to decrease the texture quality? I'm having a small frame rate in my game, and I narrowed it down to the texture quality, so if I could decrease the texture quality, that would really help.

A: Actually, this has to do more with the size of your textures and not with their quality; you can use smaller sized textures and scale them bigger in Wed. As a general rule, a texture uses about a x b x 3 bytes for 2 byte textures (pcx, bmp, etc) and about a x b x 4.5 for 3 byte (tga) textures, where a and b are the width and height of the texture in pixels.

 

This means that a 512 x 512 bmp file needs about 0.75 MB, while a 1024 x 1024 tga file uses about 4.5 MB of video memory. The shadow maps used by the textures depend on the level geometry, the number and type of lights, and so on, but these values are pretty close to the "real" ones.

 

 

Q: I'm currently making an outside level in which I would like some water the player can enter. I have set the passable flag for my water entity but when I enter the water the player just walks on top of the water and does not enter through the surface. What am I doing wrong?

A: There are two things that need to be done:

1) The passable entity must have its "passable" flag set in Wed or inside its action or function, just like this:

 

action passable_entity()

{

       set (my, PASSABLE);

       // the rest of the code for your entity should go here

       ..................................

}

 

2) The model that is supposed to pass through the passable entity (the player) must have IGNORE_PASSABLE set in its c_move instruction, just like this:

 

c_move(my, vector(10 * (key_w - key_s) * time_step, 0, 0), nullvector, IGNORE_PASSABLE);

 

 

Q: How can I read and display a very big string from a file? Right now, any separator (comma, etc) will break the string so I'll only get to see a part of it.

A: Define your own separator (I have used a "~" in my example) and then use this snippet as a base for your code.

 

// this can be a huge string which contains commas, several lines, new lines (Enter), etc.

STRING* my_str = "                                                                          "; 

 

TEXT* my_txt =

{

       pos_x = 50;

       pos_y = 30;

       layer = 10;

       string(my_str);

       flags = VISIBLE;

}

 

function read_lots_of_data()

{

       var filehandle;

       filehandle = file_open_read("mybigfile.txt"); // read the text from this file and copy it to my_str

       file_str_readto(filehandle, my_str, "~", 4000); // use ~ as a separator, read up to 4000 characters

       file_close (filehandle); // now close the file

}

 

 

Q: I would like to have my player pick up the diary pages by colliding with them, like walking up to them and they go into the inventory.

A: Here's an example that uses 3 diary pages.

 

BMAP* diary1_pcx = "diary1.pcx";

BMAP* diary2_pcx = "diary2.pcx";

BMAP* diary3_pcx = "diary3.pcx";

 

PANEL* diary1_pan =

{

       bmap = diary1_pcx;

       pos_x = 0;

       pos_y = 0;

}

 

PANEL* diary2_pan =

{

       bmap = diary2_pcx;

       pos_x = 0;

       pos_y = 50;

}

 

PANEL* diary3_pan =

{

       bmap = diary3_pcx;

       pos_x = 0;

       pos_y = 100;

}

 

action players_code() // simple player and 1st person camera code

{

       player = my; // I'm the player

       set (my, INVISIBLE); // no need to see player's model in 1st person mode

       while (1)

       {

               // move the player using the "W", "S", "A" and "D" keys; "10" = movement speed, "6" = strafing speed

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x); // use player's x and y for the camera as well

               camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level)

               camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse

               camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis

               player.pan = camera.pan; // the camera and the player have the same pan angle

               wait (1);

       }

}

 

action diary1() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary1_pan, VISIBLE);

       ent_remove(my);

}

 

action diary2() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary2_pan, VISIBLE);

       ent_remove(my);

}

 

action diary3() // attach this to your diary entity (model, sprite, etc)

{

       set(my, PASSABLE);

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

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

       set(diary3_pan, VISIBLE);

       ent_remove(my);

}

 

 

Q: I have a hard time setting the proper size of the entities in my level; is there a possibility to change their size at runtime?

A: Here's an example that changes the size on the z axis for any entity that is touched with the mouse pointer. A panel displays the z scale, which can then be used in Wed.

 

BMAP* arrow_pcx = "arrow.pcx";

 

PANEL* size_pan =

{

       digits(100, 50, 3.3, *, 1, mouse_ent.scale_z);

       flags = visible;

}

 

function mouse_startup()

  mouse_mode = 2;

  mouse_map = arrow_pcx;

  while (1)

  { 

       vec_set(mouse_pos, mouse_cursor);

       wait(1);

  }

}

 

function change_entities_startup()

{

       while (1)

       {

               if (mouse_ent) // if the mouse is touching an entity

               {

                       if (key_1) {mouse_ent.scale_z += 0.1 * time_step;}

                       if (key_2) {mouse_ent.scale_z -= 0.1 * time_step;}

               }

               wait (1);

       }

}

 

action players_code() // simple player and 1st person camera code

{

       player = my; // I'm the player

       set (my, INVISIBLE); // no need to see player's model in 1st person mode

       while (1)

       {

               // move the player using the "W", "S", "A" and "D" keys; "10" = movement speed, "6" = strafing speed

               c_move (my, vector(10 * (key_w - key_s) * time_step, 6 * (key_a - key_d) * time_step, 0), nullvector, GLIDE);

               vec_set (camera.x, player.x); // use player's x and y for the camera as well

               camera.z += 30; // place the camera 30 quants above the player on the z axis (approximate eye level)

               camera.pan -= 5 * mouse_force.x * time_step; // rotate the camera around by moving the mouse

               camera.tilt += 3 * mouse_force.y * time_step; // on its x and y axis

               player.pan = camera.pan; // the camera and the player have the same pan angle

               wait (1);

       }

}

 

 

Q: I am creating an adventure game and I would like to have a "tooltip", a small text that appears at the top of the screen and explains what an object is or does when that object is touched by the mouse pointer. How can I do that?

A: Fill in the "String 1" field in Wed for all the entities that need tooltips, and then use the snippet below.

 

BMAP* arrow_pcx = "arrow.pcx";

 

STRING* tooltip_str = "                                "; // use up to 32 characters for your tooltip

 

TEXT* tooltip_txt =

{

  pos_x = 50;

  pos_y = 20;

  string (tooltip_str);

  flags = VISIBLE;

}

 

function mouse_startup()

  mouse_mode = 2;

  mouse_map = arrow_pcx;

  while (1)

  { 

       vec_set(mouse_pos, mouse_cursor);

       wait(1);

  }

}

 

function tooltips_startup()

{

       while (1)

       {

               if (mouse_ent)

               {

                       str_cpy(tooltip_str, mouse_ent.string1); // put your text in entity's string1 in Wed

                       set(tooltip_txt, VISIBLE);

               }

               else

               {

                       reset(tooltip_txt, VISIBLE);

               }

               wait (1);

       }

}

 

 

Q: I need a function that writes the date and time to a log file (appending them to the existing info) and then shuts down the engine.

A: There you go:

 

STRING* log_str = "                                       "; // yyyy mm, dd  hh:mm ss (ex: 2007 January, 25  17:34 56)

STRING* temp_str = "  ";  // temporary string

 

function write_log_startup()

{

       var filehandle;

       filehandle = file_open_append ("mylog.txt");

 

       if (sys_month == 1)

               str_cpy(log_str, "January ");

       if (sys_month == 2)

               str_cpy(log_str, "February ");

       if (sys_month == 3)

               str_cpy(log_str, "March ");

       if (sys_month == 4)

               str_cpy(log_str, "April ");

       if (sys_month == 5)

               str_cpy(log_str, "May ");

       if (sys_month == 6)

               str_cpy(log_str, "June ");

       if (sys_month == 7)

               str_cpy(log_str, "July ");

       if (sys_month == 8)

               str_cpy(log_str, "August ");

       if (sys_month == 9)

               str_cpy(log_str, "September ");

       if (sys_month == 10)

               str_cpy(log_str, "October ");

       if (sys_month == 11)

               str_cpy(log_str, "November ");

       if (sys_month == 12)

               str_cpy(log_str, "December ");

 

       if (sys_day < 10)

       {

               str_cat(log_str, "0");

       }

       str_for_num(temp_str, sys_day);

       str_cat(log_str, temp_str);

       str_cat(log_str, ", ");

 

       str_for_num(temp_str, sys_year);

       str_cat(log_str, temp_str);

       str_cat(log_str, "  ");

 

         str_for_num(temp_str, sys_hours);

         str_cat(log_str, temp_str);

         str_cat(log_str, ":");

         if (sys_minutes < 10)  

         { 

               str_cat(log_str, "0"); 

         } 

         str_for_num(temp_str, sys_minutes);

         str_cat(log_str, temp_str);  

         str_cat(log_str, " ");  

         if (sys_seconds < 10)  

         { 

                 str_cat(log_str, "0"); 

         } 

         str_for_num(temp_str, sys_seconds);

         str_cat(log_str, temp_str);

 

       file_str_write(filehandle, log_str);

       file_asc_write (filehandle, 13);

         file_asc_write (filehandle, 10);

       

       file_close(filehandle);

 

       wait (-5); // wait for 5 seconds

       sys_exit(NULL); // now shut down the engine

}

 

aum70_faq1