Questions from the forum |
Top Previous Next |
Q: I've got some damage code from one of the AUMs working fine in my game. But how can I create a visual effect that looks like a red laser barrier which moves up and down at all times? A: Use the following snippet.
var height;
function energy_startup() { while (1) { // set the starting point for the 3D line // the numbers below (100, 100) set the x and y coordinates of the starting point draw_line3d(vector(100, 100, height), NULL, 100); // draw the red laser line // the numbers below (100, 150) set the x and y coordinates of the ending point draw_line3d(vector(100, 150, height), vector(0, 0, 255), 100); wait (1);
} }
function init_startup() { fps_max = 60; // limit the frame rate while (1) { // -150 is the minimum laser barrier height // 80 = laser movement amplitude height = -150 + sinv(total_frames) * 80; wait (1); } }
Q: I need code for a player/NPC combo. The NPC should start playing its "talk" animation when the player comes close and is looking at it. Can you help? A: Sure, here's your player/NPC combo.
var t_player_speed = 25; // player's movement speed var t_fwdbk_accel = 7; // player's forward / backward acceleration var t_side_accel = 3; // player's sideway (strafe) acceleration var t_friction = 1.5; // player's friction - this value should always be greater than 1 var t_fallspeed = 1; // player's fall down speed var t_jump = 20; // player's jumping force var t_resilience = 4; // pushes the player upwards a bit if it sinks too much in the floor var t_disttoground = 64; // distance between the origin of player's model and the ground (used by the camera as well) var t_camera_h = 12; // horizontal camera acceleration var t_camera_h_frict = 0.95; // always use a value below 1 here var t_camera_v = 8; // vertical camera acceleration var t_camera_v_frict = 0.8; // always use a value below 1 here var t_players_health = 100; // the player starts with 100 health points var camera_h_speed = 0; var camera_v_speed = 0;
var animation_mode = 0; // 0 = stand, 1 = talk; var anim_percentage = 0;
action players_code() // attach this piece of code to your player { player = my; set (my, INVISIBLE); // using a 1st person player set (my, FLAG2); // will be used by enemies' c_scan instructions to detect the player var forward_on, backward_on, right_on, left_on, jump_on, run_on; var current_height = 0, jump_handle; VECTOR horizontal_speed, vertical_speed, temp; vec_set(horizontal_speed.x, nullvector); // initialize this vector vec_set(vertical_speed.x, nullvector); // initialize this vector while(t_players_health > 0) { // the player scans on a radius of 1,000 quants around it c_scan(my.x, my.pan, vector(60, 180, 150), IGNORE_ME);
// key input start forward_on = 0; // reset all the key values at the beginning of each frame backward_on = 0; right_on = 0; left_on = 0; jump_on = 0; run_on = 0; // set the proper variables if their corresponding keys are pressed if(key_w) forward_on = 1; if(key_s) backward_on = 1; if(key_a) left_on = 1; if(key_d) right_on = 1; if(key_space) jump_on = 1; if(key_shift) run_on = 1; // key input end if (key_q) camera.pan -= 5 * time_step; if (key_e) camera.pan += 5 * time_step;
vec_set(camera.x, my.x); // accelerate camera's pan and tilt angles depending on mouse_force.x and mouse_force.y in order to create a smooth camera camera.pan -= accelerate (camera_h_speed, t_camera_h * (mouse_force.x), t_camera_h_frict); camera.tilt += accelerate (camera_v_speed, t_camera_v * (mouse_force.y), t_camera_v_frict); camera.tilt = clamp(camera.tilt, -90, 90); // limit the tilt angle of the camera to -90... 90 degrees my.pan = camera.pan;
// player's horizontal speed (forward / backward / sideways) movement uses acceleration and friction as well horizontal_speed.x = (horizontal_speed.x > 0) * maxv(horizontal_speed.x - time_step * t_friction, 0) + (horizontal_speed.x < 0) * minv(horizontal_speed.x + time_step * t_friction, 0); if(forward_on) { horizontal_speed.x += time_step * t_fwdbk_accel; horizontal_speed.x = minv(horizontal_speed.x, time_step * t_player_speed * (1 + run_on)); } if(backward_on) { horizontal_speed.x -= time_step * t_fwdbk_accel; horizontal_speed.x = maxv(horizontal_speed.x, -(time_step * t_player_speed * (1 + run_on))); } horizontal_speed.y = (horizontal_speed.y > 0) * maxv(horizontal_speed.y - time_step * t_friction, 0) + (horizontal_speed.y < 0) * minv(horizontal_speed.y + time_step * t_friction, 0); if(left_on) { horizontal_speed.y += time_step * t_side_accel; horizontal_speed.y = minv(horizontal_speed.y, time_step * t_player_speed * (1 + run_on)); } if(right_on) { horizontal_speed.y -= time_step * t_side_accel; horizontal_speed.y = maxv(horizontal_speed.y, -(time_step * t_player_speed * (1 + run_on))); } // disable the friction, allow smooth gliding along the surfaces move_friction = 0; vec_set(temp.x, my.x); temp.z -= 10000; current_height = c_trace(my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX | GLIDE); // compute the distance between player's origin and the floor below its feet if(current_height < (t_disttoground * 0.97)) // if it is smaller than the default value (64 quants) push the player upwards a bit (resilience) - 0.97 gives the hysteresis { vertical_speed.z = t_resilience * time_step; } else { if(current_height > t_disttoground) // if it is bigger than the default value (64 quants), move the player downwards { vertical_speed.z -= t_fallspeed * time_step; } else // sitting properly on the floor? { vertical_speed.z = 0; // then don't do anything on the z axis } } if((jump_on) && (current_height < t_disttoground)) // jumping while player's feet are placed on the floor? { vertical_speed.z = t_jump * 0.25; // push the player upwards } // this c_move instruction does all the job, moving the player in the direction given by horizontal_speed (forward, backward, sideways) and vertical_speed (on the z axis) c_move (my, horizontal_speed.x , vertical_speed.x, IGNORE_PASSABLE | USE_BOX | GLIDE); // player movement end wait(1); } camera.z -= 30; // bring the camera closer to the floor camera.roll = 40; // and rotate its view (the player is dead here) }
function got_scanned() { while (event_type == EVENT_SCAN) { animation_mode = 1; // "talk" wait (1); } animation_mode = 0; // "stand" }
action my_enemies() // attach this action to your enemies { reset (my, SHOW); my.emask |= ENABLE_SCAN; // make the entity sensitive to scanning my.event = got_scanned; while (1) { anim_percentage += 3 * time_step; // use your own animation code here if (animation_mode == 1) { ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "talk" animation } else { ent_animate(my, "idle", anim_percentage, ANM_CYCLE); // play the "stand" animation } wait (1); } }
Q: How do I fade out my soundtrack after the player clicks the "Start" game button, before loading the level? A: Here's an example.
var game_started = 0; var track_volume = 100; var soundtrack_handle;
BMAP* menu_png = "menu.png";
BMAP* start1_png = "start1.png"; BMAP* start2_png = "start2.png"; BMAP* exit1_png = "exit1.png"; BMAP* exit2_png = "exit2.png";
BMAP* pointer_tga = "pointer.tga";
STRING* level1_wmb = "level1.wmb";
function init_game(); function start_game(); function exit_game();
PANEL* main_pan = { layer = 10; bmap = menu_png; pos_x = 0; pos_y = 0; button (250, 10, start2_png, start1_png, start2_png, start_game, NULL, NULL); button (250, 50, exit2_png, exit1_png, exit2_png, exit_game, NULL, NULL); flags = SHOW; }
function game_startup() { var track_volume = 100; // initial sound volume, put your prefered value here soundtrack_handle = media_play("soundtrack.mp3", NULL, track_volume); mouse_mode = 2; mouse_map = pointer_tga; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function start_game() { reset(main_pan, SHOW); while (track_volume > 0) // the game has started, so decrease the volume { media_tune(soundtrack_handle, track_volume, 100, 0); track_volume -= 2 * time_step; // 2 gives the volume decrease speed wait (1); } media_stop (soundtrack_handle); // stop the sound for good // level_load (level1_wmb); // load the first game level here }
function exit_game() { sys_exit(NULL); }
Q: I'd need some code for a little bunny that jumps for several seconds, rests for several seconds, and can avoid obstacles. Is it possible to do that? A: Sure, see for yourself!
var distance_covered = 0;
action my_bunny() { var anim_percentage; var jumping_interval = 0; var random_interval; while (1) { if (jumping_interval == 0) { // sets the number of jumping seconds before changind the direction random_interval = 5 + random(3); } // "10" controls the jumping speed distance_covered = c_move (my, vector(10 * time_step, 0, 0), nullvector, GLIDE); // use your own rabbit animation name below ent_animate(my, "rockrun", anim_percentage, ANM_CYCLE); // "6" controls the animation speed anim_percentage += 6 * time_step; // increase jumpung_interval by 1 each second jumping_interval += time_step / 16; // the rabbit has jumped more than random_interval in a direction? Then it's time to change the direction! if (jumping_interval > random_interval) { // let the bunny rest for a while while (jumping_interval > 0) { // decrease jumping_interval by 1 each second jumping_interval -= time_step/16; ent_animate(my, "stand", anim_percentage, ANM_CYCLE); // "6" controls the animation speed anim_percentage += 6 * time_step; wait (1); } // add -90...+90 degrees to the pan angle my.pan += 90 - random(180); } // the rabbit got stuck? if (distance_covered < 1) // the value returned by c_move is really small { // then add 120...+240 degrees to its pan angle (about 180 degrees, should get the rabbit out of trouble) my.pan += 120 + random(120); } wait (1); } }
PANEL* distance_pan = { layer = 15; digits(100, 20, "Distance covered per frame: %.f", *, 1, distance_covered); flags = SHOW; }
Q: How do I reduce the size of my game? Right now, the published version has over 500MB! A: It all comes down to the size of the textures that are used for the levels and models in your game. Most mobile game developers start with texture sizes that are as small as possible, and then go up until their games look good enough. To give you a few examples, characters have 256x256 pixels skins, and level elements use 64x64 or 128x128 pixels textures. A little known trick is to reduce texture depth; use RIOT to convert your textures to 8 bits (256 colors). Good luck!
Q: The player has to control 3 team members. How do I code it, so that a player becomes active and starts moving forward when it is clicked? When one of the other team members is clicked, the first team member should stop and the second member should start moving, etc. A: Place your 3 team members in the level, and then attach them all the "team_members" action below.
BMAP* arrow_pcx = "arrow.pcx";
function init_startup() { // allow the player to click the team members even if they are 10,000 quants away from its model mouse_range = 10000; // set the desired x y z values for the camera vec_set(camera.x, vector (200, -300, 300)); camera.pan = 90; // set the proper camera.pan angle camera.tilt = -40; // set the proper camera.tilt angle }
// standard mouse code function mouse_startup() { mouse_mode = 1; mouse_map = arrow_pcx; while (1) { vec_set(mouse_pos, mouse_cursor); wait(1); } }
function team_control() { player = my; my.skill1 = 99; // set a unique value for skill1 var walk_percentage; if (my.skill1 == 99) // if this is the active team member { while (player == my) // this loop will only run for the entity that was clicked { c_move (my, vector(3 * time_step, 0, 0), nullvector, GLIDE); ent_animate(my, "walk", walk_percentage, ANM_CYCLE); // play the "walk" animation walk_percentage += 3 * time_step; // "3" controls the animation speed wait (1); } my.skill1 = 0; // the current team member has changed, so let's reset skill1 now } }
action team_members() // attach this action to your team members { my.emask |= ENABLE_CLICK; // make the entity sensitive to mouse clicking my.event = team_control; // this function will run when the player clicks one of the team members }
Q: How do I code 5 weapons that can be selected by pressing the 1...5 buttons on the keyword? A: There you go.
var active_weapon = 1; // ranges from 1 to 5, depending on the current weapon
ENTITY* weapon1_ent = { type = "weapon1.mdl"; // weapon model pan = 0; // weapon angle x = 55; // 55 quants ahead of the view, play with this value y = -20; // 20 quants towards the right side of the screen, play with this value z = -20; // 20 quants below, play with this value pan = 2; // weapon's pan angle (you can also use tilt and roll) }
ENTITY* weapon2_ent = { type = "weapon2.mdl"; // weapon model pan = 0; // weapon angle x = 60; // 60 quants ahead of the view, play with this value y = 15; // 15 quants towards the left side of the screen, play with this value z = -18; // 18 quants below, play with this value pan = -3; // weapon's pan angle (you can also use tilt and roll) }
ENTITY* weapon3_ent = { type = "weapon3.mdl"; // weapon model pan = 0; // weapon angle x = 60; // 60 quants ahead of the view, play with this value y = 15; // 15 quants towards the left side of the screen, play with this value z = -18; // 18 quants below, play with this value pan = -3; // weapon's pan angle (you can also use tilt and roll) }
ENTITY* weapon4_ent = { type = "weapon4.mdl"; // weapon model pan = 0; // weapon angle x = 60; // 60 quants ahead of the view, play with this value y = 15; // 15 quants towards the left side of the screen, play with this value z = -18; // 18 quants below, play with this value pan = -3; // weapon's pan angle (you can also use tilt and roll) }
ENTITY* weapon5_ent = { type = "weapon5.mdl"; // weapon model pan = 0; // weapon angle x = 60; // 60 quants ahead of the view, play with this value y = 15; // 15 quants towards the left side of the screen, play with this value z = -18; // 18 quants below, play with this value pan = -3; // weapon's pan angle (you can also use tilt and roll) }
function gun_startup() { while (1) { if (key_1) { weapon1_ent.flags2 = VISIBLE; weapon2_ent.flags2 = ~VISIBLE; weapon3_ent.flags2 = ~VISIBLE; weapon4_ent.flags2 = ~VISIBLE; weapon5_ent.flags2 = ~VISIBLE; active_weapon = 1; } if (key_2) { weapon1_ent.flags2 = ~VISIBLE; weapon2_ent.flags2 = VISIBLE; weapon3_ent.flags2 = ~VISIBLE; weapon4_ent.flags2 = ~VISIBLE; weapon5_ent.flags2 = ~VISIBLE; active_weapon = 2; } if (key_3) { weapon1_ent.flags2 = ~VISIBLE; weapon2_ent.flags2 = ~VISIBLE; weapon3_ent.flags2 = VISIBLE; weapon4_ent.flags2 = ~VISIBLE; weapon5_ent.flags2 = ~VISIBLE; active_weapon = 3; } if (key_4) { weapon1_ent.flags2 = ~VISIBLE; weapon2_ent.flags2 = ~VISIBLE; weapon3_ent.flags2 = ~VISIBLE; weapon4_ent.flags2 = VISIBLE; weapon5_ent.flags2 = ~VISIBLE; active_weapon = 4; } if (key_5) { weapon1_ent.flags2 = ~VISIBLE; weapon2_ent.flags2 = ~VISIBLE; weapon3_ent.flags2 = ~VISIBLE; weapon4_ent.flags2 = ~VISIBLE; weapon5_ent.flags2 = VISIBLE; active_weapon = 5; } wait (1); } }
function gun_code() { while (1) { if (active_weapon == 1) { // put the code for your first weapon here wait (1); } if (active_weapon == 2) { // put the code for your second weapon here wait (1); } if (active_weapon == 3) { // put the code for your third weapon here wait (1); } if (active_weapon == 4) { // put the code for your fourth weapon here wait (1); } if (active_weapon == 5) { // put the code for your fifth weapon here wait (1); } wait (1); } }
Q: How do I create a patrolling entity that has a working flashlight attached to its helmet? A: Here's an example.
ENTITY* dummy;
function headlight() // attaches a flashlight to the patrolling entity { set(my, PASSABLE); vec_set(d3d_spotlightcone, vector(25, 80, 4)); // play with these values vec_set(my.blue, vector(255, 255, 255)); // the headlight will generate white light my.lightrange = 300; // on a range of up to 300 quants my.flags2 |= SPOTLIGHT; while (1) { // play with the numerical values, they set the position of the headlight (x, y, z) // make them match player's head/helmet coords vec_set (my.x, vector (10, 0, 50)); vec_rotate (my.x, you.pan); vec_add (my.x, you.x); my.pan = you.pan; wait (1); } }
action patroller() // simple path patrolling movement code { var walk_percentage; var distance = 0; var previous_pan; var following_pan; var min_speed = 1; var max_speed = 3; var walking_speed; VECTOR last_pos[3]; VECTOR direction[3]; ent_create("headlight.mdl", nullvector, headlight); // create the headlight model // create a dummy entity that will move on the path dummy = ent_create(NULL, nullvector, NULL); // make sure to name your path this way path_set(dummy, "path_001"); while(1) { previous_pan = my.pan; // place the dummy entity on the path path_spline(dummy, my.x, distance); distance += walking_speed * time_step; // let the npc look ahead vec_diff(direction, my.x, last_pos); vec_to_angle(my.pan, direction); vec_set(last_pos, my.x); wait(1); following_pan = my.pan; // sudden direction change during the last frame? Then lower the speed of the npc! if (abs(following_pan - previous_pan) > 1) { walking_speed -= 4 * time_step; } else { walking_speed += 2 * time_step; } // don't allow the walking speed to exceed the specified min / max limits walking_speed = clamp(walking_speed, min_speed, max_speed); ent_animate(my, "walk", walk_percentage, ANM_CYCLE); // play the "walk" animation walk_percentage += 3 * time_step; // "3" controls the animation speed } }
Q: I am building my levels using models. How do I create a function that writes down the coordinates for all their vertices to a file? A: Use this snippet as a base for your code:
STRING* temp_str = "#20";
VECTOR temp;
action entity_coords() { var filehandle_write, i = 0; filehandle_write = file_open_write("vertexcoords.txt"); while (i < ent_vertices(my)) { vec_for_vertex (temp, my, i); file_var_write(filehandle_write, i); file_str_write(filehandle_write, ", "); str_for_num(temp_str, temp.x); file_str_write(filehandle_write, temp_str); file_str_write(filehandle_write, ", "); str_for_num(temp_str, temp.y); file_str_write(filehandle_write, temp_str); file_str_write(filehandle_write, ", "); str_for_num(temp_str, temp.z); file_str_write(filehandle_write, temp_str); // move on to the following row file_asc_write (filehandle_write, 13); // write the following strings on a new line file_asc_write (filehandle_write, 10); // using asc(13) = carriage return + asc(10) = line feed i++; } // all the data has been written, so let's close the text file now file_close(filehandle_write); }
PANEL* debug_pan = { pos_x = 0; pos_y = 0; digits (15, 20, 3, _a4font, 1, temp[0]); digits (15, 40, 3, _a4font, 1, temp[1]); digits (15, 60, 3, _a4font, 1, temp[2]); flags = SHOW; }
|