Questions from the forum |
Top Previous Next |
Q: I am looking for a solution that allows me to check if certain entities are visible in the current camera view. A: Here's an example.
var object_id = -1; var visible_objects[100]; // displays up to 100 visible objects var total_visible;
action visible_or_not() // attach this action to all the object that need to be tracked { // put the rest of your code here // ..............................
VECTOR my_pos[3]; object_id += 1; my.skill99 = object_id; // don't use skill99 for something else while (1) { // put the rest of your code here // ..............................
vec_set(my_pos.x, my.x); if (vec_to_screen(my_pos.x, camera)) // if this entity is visible on the screen { visible_objects[my.skill99] = 1; } else // the entity isn't visible on the screen { visible_objects[my.skill99] = 0; } wait (1); } }
function total_startup() { var i; while (1) { total_visible = 0; for(i = 0; i < 100; i++) { total_visible += visible_objects[i]; } wait (1); } }
PANEL* entities_pan = { layer = 15; digits(20, 20, 3, *, 1, total_visible); flags = visible; }
Q: What is the best way to make a simple lives system? It should start with three lives and every time player's health hits zero, one of the lives goes down and the game reloads. If no lives are left, the game should jump to a game over panel. A: There you go.
PANEL* gameover_pan = { layer = 15; pos_x = 300; pos_y = 200; bmap = "gameover.pcx"; }
action player_destroyer() // kills the player if the player comes too close { set(my, PASSABLE); while (1) { if (player) // the player exists? { if (vec_dist(player.x, my.x) < 100) // the player has come close to the destroyer object? { player.skill99 -= 5 * time_step; // then decrease player's health } } wait (1); } }
function players_action() { VECTOR temp; var movement_speed = 10; // movement speed set (my, INVISIBLE); // 1st person player my.skill99 = 100; // player's skill99 stores its health while (my.skill99 > 0) { 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); // play with 50 and 1.1 camera.pan = my.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); } player = NULL; wait (1); ent_remove(my); // remove the player if it is dead }
function init_startup() { wait (-1); // wait until the level is loaded player = ent_create("guard.mdl", vector (10, 10, 70), players_action); // first life while (player) {wait (1);} // wait until the player disappears from the level wait (3); player = ent_create("guard.mdl", vector (10, 10, 70), players_action); // create it again (that's the second life) while (player) {wait (1);} // wait until the player disappears from the level wait (3); player = ent_create("guard.mdl", vector (10, 10, 70), players_action); // create it again (that's the third life) wait (3); while (player) {wait (1);} // wait until the player disappears from the level // the game is over here, so let's display the "Game Over" panel set(gameover_pan, VISIBLE); while (key_any) {wait (1);} // wait until the keys are released while (!key_any) {wait (1);} // wait until any key is pressed sys_exit(NULL); // and now let's shut down the engine }
Q: I would like to display several parameters for my entities on the screen (for debugging purposes). Is there an easy way to do that? A: Here's an example.
BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function debug_startup() { while (1) { if(mouse_ent) // the mouse touches an entity? watched = mouse_ent; // then display information about that entity! wait (1); } }
Q: How can you jump with a character in lite-C? The character should jump only when he is on the floor. A: Here's an improved version of my code from Aum52's workshop.
action player_code() { VECTOR temp[3]; VECTOR movement_speed[3]; // player's movement speed var anim_percentage; // animation percentage var jump_percentage; // animation percentage for jumping var distance_to_ground; // the distance between player's origin and the ground var jump_height; var reached_height; player = my; // I'm the player while (1) { my.pan += 6 * (key_a - key_d) * time_step; // rotate the player using the "A" and "D" keys vec_set (temp.x, my.x); // copy player's position to temp temp.z -= 10000; // set temp.z 10000 quants below player's origin distance_to_ground = c_trace (my.x, temp.x, IGNORE_ME | USE_BOX); movement_speed.x = 5 * (key_w - key_s) * time_step; // move the player using "W" and "S" movement_speed.y = 0; // don't move sideways if (key_space && !reached_height) { jump_height = minv(40, jump_height + 5 * time_step); // 40 sets the height, 5 sets the ascending speed if (jump_height == 40) // reached the maximum height? Then start descending! { reached_height = 1; jump_height = maxv(0, jump_height - 5 * time_step); // 5 sets the falling speed } } else // space isn't pressed anymore? { jump_height = maxv(0, jump_height - 3 * time_step); // use a smaller falling speed (3) for smaller jumps if (!jump_height && !key_space) // the player has touched the ground? { reached_height = 0; // then allow it to jump again } } movement_speed.z = -(distance_to_ground - 17) + jump_height; // 17 = experimental value movement_speed.z = maxv(-35 * time_step, movement_speed.z); // 35 = falling speed c_move (my, movement_speed.x, nullvector, GLIDE); // move the player if (!jump_height) // the player isn't jumping? { if (!key_w && !key_s) // the player isn't moving? { ent_animate(my, "stand", anim_percentage, ANM_CYCLE); // play the "stand" animation } else // the player is moving? { ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation } anim_percentage += 5 * time_step; // 5 = animation speed jump_percentage = 0; // always start jumping with the first frame } else // the player is jumping { jump_percentage += 5 * time_step; // 5 = jump animation speed ent_animate(my, "jump", jump_percentage, ANM_CYCLE); // play the "jump" animation }
// camera code camera.x = player.x - 250 * cos(player.pan); camera.y = player.y - 250 * sin(player.pan); // use the same value (250) here camera.z = player.z + 150; // place the camera above the player, play with this value camera.tilt = -20; // look down at the player camera.pan = player.pan; wait (1); } }
Q: How can I create a convincing police siren sound effect that can be attached to my police cars? A: Try several sound effects and the following snippet.
SOUND* siren_wav = "siren.wav";
action police_car() { // put the rest of your car code in here // .....................................
var police_handle; var freq_range; var speed = 30; // sets the speed of the sound effect police_handle = ent_playloop (my, siren_wav, 400); while (1) { // freq_range ranges from 30 to 370% (play with 200 and 190) freq_range = 200 - 170 * sin(total_ticks * speed); snd_tune (police_handle, 0, freq_range, 0); // change the frequency from 10% to 300% wait (1);
// put the rest of your car code in here // ..................................... } }
Q: Is it possible to adjust the range of a dynamic light using the mouse wheel? A: Sure. Just move the mouse over the light bulb entity and rotate the wheel.
BMAP* pointer_tga = "pointer.tga";
function mouse_startup() { mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function adjust_light() { while (event_type != EVENT_RELEASE) { my.lightrange += 0.5 * mickey.z * time_step; my.lightrange = clamp(my.lightrange, 0, 1000); // limit the light range to 0...1000 wait (1); } }
action light_bulb() // attach this action to all the light bulbs { vec_set(my.blue, vector(255, 255, 255)); // generate white light my.lightrange = 300; // default light range value my.emask |= (ENABLE_TOUCH | EVENT_RELEASE); my.event = adjust_light; }
Q: I have placed invisible blocks in my level but the player is just going straight through them. Why could this be? A: Even a player that's driven by a c_move instruction will pass through invisible level blocks, but not through invisible map entities. Add a block to an empty level, save it and build it as a separate wmb entity. Place this entity in the level and check its "Invisible" checkbox; the player won't be able to pass though it.
Q: I want to create an avatar of the player on screen, filming his face during combat. Is this possible? A: Create a tga bitmap that has a cutout with a size that's identical to the size of the avatar camera, and then use the code below.
VIEW* avatar_cam = { pos_x = 120; pos_y = 48; size_x = 158; size_y = 119; layer = 10; flags = VISIBLE; }
PANEL* hud_pan = { layer = 5; pos_x = 0; pos_y = 0; bmap = "hud.tga"; flags = VISIBLE; }
function avatarcam_startup() { while (!player) {wait (1);} while (1) { vec_set (avatar_cam.x, vector (20, 0, 35)); // play with these values vec_rotate (avatar_cam.x, player.pan); vec_add (avatar_cam.x, player.x); avatar_cam.pan = player.pan + 180; // make avatar_cam look at the player wait (1); } }
Q: I'm trying to make a panel that shows me how much health I have. I want to make something like the Zelda panels. A: There you go.
BMAP* hearts_tga = "hearts.tga"; // that's a stripe that contains 5 small hearts BMAP* bigheart_tga = "bigheart.tga"; // that's the big heart that appears over the stripe
PANEL* hearts_pan = { layer = 15; pos_x = 0; pos_y = 20; bmap = hearts_tga; flags = visible; }
PANEL* bigheart_pan = { layer = 25; // this panel appear above one of the other panels pos_x = 200; pos_y = 15; bmap = bigheart_tga; flags = visible; }
function health_startup() { while (!player) {wait (1);} // wait until the player is loaded in the level player.skill10 = 100; while (1) { if (player.skill10 > 90) // player's health is stored inside its skill10 in this example bigheart_pan.pos_x = 200; if ((player.skill10 > 70) && (player.skill10 <= 90)) bigheart_pan.pos_x = 150; if ((player.skill10 > 50) && (player.skill10 <= 70)) bigheart_pan.pos_x = 100; if ((player.skill10 > 30) && (player.skill10 <= 50)) bigheart_pan.pos_x = 100; if ((player.skill10 > 10) && (player.skill10 <= 30)) bigheart_pan.pos_x = 50; if ((player.skill10 <= 10)) bigheart_pan.pos_x = 0; wait (1); } }
Q: If I place a model in the level and I set its polygon flag, the collision works as expected; however, if I create the same model using ent_create and I set its polygon flag in the function that drives it, the bounding box doesn't change as expected. How can I fix that? A: You need to use c_setminmax(my) if you want to ent_create your models and have them use polygon-based collision.
function guards_function() { c_setminmax(my); // put the rest of your code here // .............................. }
function create_startup() { wait (-3); // wait until the level is loaded ent_create("guard.mdl", vector(100, 100, 50), guards_function); }
|