2 registered members (Akow, tomaslolo),
1,536
guests, and 12
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Good movement code in c-lite
#175616
12/31/07 20:16
12/31/07 20:16
|
Joined: Mar 2002
Posts: 580 San Francisco
clone45
OP
User
|
OP
User
Joined: Mar 2002
Posts: 580
San Francisco
|
Hello everyone! I took David Lancaster's Kingdom Heart's movement code and converted it to c-lite and made some changes. I posted the code up to Game Beep for download, but I'll also post it here. This is a great place to start for 3rd person movement. Here's a video of the movement code in action: http://www.youtube.com/watch?v=Jk5Qo9HyyckHere's the code: defines.c Code:
#define animate skill31 #define animate2 skill32 #define animblend skill33 #define currentframe skill34 #define blendframe skill35
#define nullframe -2 #define blend -1 #define stand 0 #define run 1 #define walk 2 #define jump 3 #define fall 4
#define run_speed 20 #define strafe_speed 12 #define run_animation_speed 16
#define mouse_pan_speed_max 8 #define mouse_pan_acceleration 1.2
#define mouse_tilt_speed 8
#define mouse_scroll_speed .2
animate.c Code:
#include <acknex.h> // include these predefined, needed files in our project #include <default.c>
#include "defines.c"
function handle_animation(animation_speed) { if (animation_speed <= 0) animation_speed = 1; if (my.animblend != blend && my.blendframe != nullframe) { my.animate2 = 0; my.animblend = blend; } if (my.animblend == blend) { if (my.currentframe == stand) ent_animate(my,"idle",my.animate,ANM_CYCLE); if (my.currentframe == run) ent_animate(my,"run",my.animate,ANM_CYCLE); if (my.currentframe == walk) ent_animate(my,"walk",my.animate,ANM_CYCLE); if (my.blendframe == stand) ent_blend("idle",0,my.animate2); if (my.blendframe == run) ent_blend("run",0,my.animate2); if (my.blendframe == walk) ent_blend("walk",0,my.animate2);
my.animate2 += 45 * time_step; if (my.animate2 >= 100) { my.animate = 0; my.animblend = my.blendframe; my.blendframe = nullframe; } } if (my.animblend == stand) { ent_animate(my,"idle",my.animate,ANM_CYCLE); my.animate += 5 * animation_speed * time_step; my.animate %= 100; my.currentframe = stand; } if (my.animblend == run) { ent_animate(my,"run",my.animate,ANM_CYCLE); my.animate += run_animation_speed * animation_speed * time_step; my.animate %= 100; my.currentframe = run; } if (my.animblend == walk) { ent_animate(my,"walk",my.animate,ANM_CYCLE); my.animate += 8 * animation_speed * time_step; my.animate %= 100; my.currentframe = walk; } }
movement.c Code:
//////////////////////////////////////////////////////////////////////////// // small.c - small lite-C example //////////////////////////////////////////////////////////////////////////// #include <acknex.h> // include these predefined, needed files in our project #include <default.c>
#include "animate.c" #include "defines.c"
//////////////////////////////////////////////////////////////////////////// void main() {
d3d_anisotropy = 2; d3d_antialias = 1; video_mode = 10; video_screen = 1; // C-Script: start settings for Fullscreen
shadow_offset = 0; mouse_sync = 1; mouse_mode = 0; // Load the level named "small.hmp" level_load("goblin_fishing.wmb");
// Wait for 3 frames, until the level is loaded wait (3);
}
function move_camera(camera_distance, camera_height) { VECTOR temp;
vec_set(camera.x,vector(my.x + fcos(my.pan,-1 * camera_distance),my.y + fsin(my.pan,-1 * camera_distance),my.z + camera_height)); //place the camera behind the player vec_diff(temp.x,my.x,camera.x); //make the camera look towards the player vec_to_angle(camera.pan,temp.x); }
// move_me() // // Note: walking isn't implemented. Jumping doesn't have the correct animation. // adapted from Kingdom Hearts Movement Tutorial by David Lancaster (www.rebelplanetcreations.com) //
action move_me() { VECTOR move_to_vector; // Holds the relative x,y,z values that are added to the character's position VECTOR my_pan; // Temporary vector used in panning the character VECTOR vec1_from; // Position vector specifying the location to start scanning for the ground VECTOR vec1_to; // Position vector specifying the destination location for scanning for the ground var camera_distance = 300; var camera_height = 160; var pan_speed; var distance_to_ground; var rotate_results; move_to_vector.x = 0; move_to_vector.y = 0; move_to_vector.z = 0; // Explicitely set the bounding box for the entity. You'll need to set these values for your own entity. // The bounding box should have equal x/y values, otherwise movement on inclines will be choppy. // Make sure that your entity is centered on the x,y,z axis in MED. wait(1); c_setminmax(me); vec_set(my.min_x,vector(-7,-7,-20)); vec_set(my.max_x,vector(7,7,20)); while(1) {
// The scroll wheel controls the distance from the camera to the model. // This is good for now, but more advanced camera control code will be needed.
camera_distance += mickey.z * mouse_scroll_speed * time_step; // Pan the player when the mouse is moved left or right. // I use accelerate() to keep the panning smooth and happy. vec_set(my_pan,nullvector); vec_sub(my_pan, vector(accelerate(pan_speed, 5 * mouse_force.x, 0.7),0,0)); // pan the camera rotate_results = c_rotate(my,my_pan,IGNORE_PASSABLE);
// Get key input from the player for character movement: asdw // Again, accelerate() is used for smooth motion accelerate(move_to_vector.y, (key_d * strafe_speed * time_step * -1), 0.8); // strafe right accelerate(move_to_vector.y, (key_a * strafe_speed * time_step), 0.8); // strafe left accelerate(move_to_vector.x, (key_w * run_speed * time_step), 0.8); // go forward accelerate(move_to_vector.x, (key_s * run_speed * time_step * -1), 0.8); // go back // Calculate the distance from the ground and position the player accordingly. // Once again, make sure that your bounding box has equal x/y values. vec_set(vec1_from,my.x); vec_set(vec1_to,my.x); vec1_to.z -= 500;
// Find the distance from the model to the ground distance_to_ground = c_trace(vec1_from, vec1_to, IGNORE_ME|IGNORE_PASSENTS|IGNORE_PASSABLE|IGNORE_SPRITES|USE_BOX); // If the spacebar is pressed and the model is on the ground, set the move_to_vector.z to 5. This is basically // the same thing as launching the model in to the air. Notice that the move_to_vector.z is NOT set to 0 every // time the movement code is looped through. Below, the code that handles gravity will continually reduce the // move_to_vector.z. For example, move_to_vector.z might go from 5 to 4..to 3.. to 1.. to -1 to -3.. etc.. until the model // hits the ground. if (key_space) { if (distance_to_ground < 2) { distance_to_ground = 1; move_to_vector.z = 5; } } // Handle Gravity // If the model is in the air, reduce the move_to_vector.z value. This simulates the pull of gravity.
if (distance_to_ground > 0) { // Acceleration due to "gravity" accelerate(move_to_vector.z, (-3 * time_step), 0); // fall // If the acceleration of the fall would cause the entity to be moved below the ground, shorten // the fall so that the entity is put directly on to the ground. if (move_to_vector.z < (distance_to_ground * -1)) { move_to_vector.z = distance_to_ground * -1; } } else { // This next piece of code handles two different cases. First, if the distance to the ground is 0, then // there's no need to move the entity along the z-axis. Thus, if distance_to_ground =0, move_to_vector.z = 0. // Secondly, if the distance to the ground is negative, that means that the entity is positioned within a block. // If that's the case, move the entity back up to ground level. move_to_vector.z = -1 * distance_to_ground; }
// Move the player c_move(me, move_to_vector, nullvector, GLIDE|IGNORE_SPRITES|IGNORE_PASSABLE);
// Move camera and handle animation move_camera(camera_distance, camera_height); handle_animation(1); // Calculate new animation - adapted from Kingdom Hearts Movement Tutorial by David Lancaster (www.rebelplanetcreations.com) if (abs(move_to_vector.x) > .5 || move_to_vector.y != 0) // if we are moving { if (my.animblend == stand) //if our current animation is stand { if (key_shift == 1) { my.blendframe = walk; } else { my.blendframe = run; } } if (my.animblend == run && key_shift == 1) { my.blendframe = walk; } if (my.animblend == walk && key_shift == 0) { my.blendframe = run; } } else { if (my.animblend > stand) //if we aren't moving and our current animation is walk or run, blend and cycle the stand animation { my.blendframe = stand; } } wait(1); }
}
////////////////////////////////////////////////////////////////////////////
Last edited by clone45; 12/31/07 20:24.
|
|
|
Re: Good movement code in c-lite
[Re: ello]
#175621
01/02/08 19:55
01/02/08 19:55
|
Joined: Mar 2006
Posts: 2,758 Antwerp,Belgium
frazzle
Expert
|
Expert
Joined: Mar 2006
Posts: 2,758
Antwerp,Belgium
|
Seems quite flexible and dynamic Nice UC Cheers Frazzle
Antec® Case Intel® X58 Chipset Intel® i7 975 Quad Core 8 GB RAM DDR3 SSD OCZ®-VERTEX2 3.5 x4 ; HD 600 GB NVIDIA® GeForce GTX 295 Memory 1795GB
|
|
|
Re: Good movement code in c-lite
[Re: ello]
#175622
01/02/08 20:02
01/02/08 20:02
|
Joined: May 2005
Posts: 2,713 Lübeck
Slin
Expert
|
Expert
Joined: May 2005
Posts: 2,713
Lübeck
|
Why do you use c_setminmax and then reset the boundingbox to an own size (vec_set(my.min_x,vector(-7,-7,-20));vec_set(my.max_x,vector(7,7,20));)? And why does the code always use accelerate? A gravity of 3 seems a bit too high. c_move should also use IGNORE_PASSENTS and the c_rotate should also use the same modes as the c_trace... This: Code:
accelerate(move_to_vector.y, (key_d * strafe_speed * time_step * -1), 0.8); // strafe right accelerate(move_to_vector.y, (key_a * strafe_speed * time_step), 0.8); // strafe left accelerate(move_to_vector.x, (key_w * run_speed * time_step), 0.8); // go forward accelerate(move_to_vector.x, (key_s * run_speed * time_step * -1), 0.8); // go back
could also be done in two lines: Code:
accelerate(move_to_vector.y, (key_a-key_d) * strafe_speed * time_step, 0.8); // strafe accelerate(move_to_vector.x, (key_w-key_s) * run_speed * time_step, 0.8); // go
But anyways this could be some good piece of code for beginners and for advanced 3DGS users that don´t want to code everything on their own @ello: strafing already seems to be in there: accelerate(move_to_vector.y, (key_d * strafe_speed * time_step * -1), 0.8); // strafe right accelerate(move_to_vector.y, (key_a * strafe_speed * time_step), 0.8); // strafe left
|
|
|
Re: Good movement code in c-lite
[Re: ello]
#175625
01/11/08 07:37
01/11/08 07:37
|
Joined: Mar 2002
Posts: 580 San Francisco
clone45
OP
User
|
OP
User
Joined: Mar 2002
Posts: 580
San Francisco
|
@ello: Strafing animation is in there. It's either "run" or "walk. Look a the following code. Basically, if move_to_vector.y !=0 (which means the entity is strafing), then animate: Code:
if (abs(move_to_vector.x) > .5 || move_to_vector.y != 0) // if we are moving { if (my.animblend == stand) //if our current animation is stand { if (key_shift == 1) { my.blendframe = walk; } else { my.blendframe = run; } } if (my.animblend == run && key_shift == 1) { my.blendframe = walk; } if (my.animblend == walk && key_shift == 0) { my.blendframe = run; } }}
PS: I've made improvements to this movement code and some simplifications. I'll post them after I resolve a small problem with sometimes getting stuck on bumpy meshes.
|
|
|
|