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);
}
}
////////////////////////////////////////////////////////////////////////////