2 registered members (AndrewAMD, 7th_zorro),
1,285
guests, and 4
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Animation frames blending, player input/physic
[Re: Orange Brat]
#64760
07/12/06 11:03
07/12/06 11:03
|
Joined: Nov 2004
Posts: 862 Australia
DavidLancaster
User
|
User
Joined: Nov 2004
Posts: 862
Australia
|
I'm not sure if this would be useful to you at all, but it's the latest animation technique I've come across. The great thing about it is that I can control any entities animation simply by calling one function each frame for that entity. This function would be called from a loop each frame: handle_animation(1); Now if at any point I want to change an animation I simply set say: my.animate2 = 0; my.animblend = blend; my.blendframe = walk; Now the entity will blend to the walk animation and then cycle the walk animation. To get a little more complex, here is how I am using the code in a game we are currently developing: Code:
IF (my.move_x != 0 || my.move_y != 0) { //if we are moving IF (my.animblend == stand) { //if our current animation is stand my.animate2 = 0; my.animblend = blend; //blend and cycle to the walk or run animation depending on whether we are holding shift or not IF ((key_pressed(key_for_str(key__shift)) == on || key_pressed(key_for_str(key__shift2)) == on)) { my.blendframe = walk; } ELSE { my.blendframe = run; } } IF (my.animblend == run && (key_pressed(key_for_str(key__shift)) == on || key_pressed(key_for_str(key__shift2)) == on)) { my.animate2 = 0; //if we are cycling the run animation and are not pressing shift blend and cycle to the walk animation my.animblend = blend; my.blendframe = walk; } IF (my.animblend == walk && (key_pressed(key_for_str(key__shift)) == off && key_pressed(key_for_str(key__shift2)) == off)) { my.animate2 = 0; my.animblend = blend; my.blendframe = run; } handle_footsteps(); } ELSE { IF (my.animblend > stand) { //if we arn't moving and our current animation is walk or run blend and cycle the stand animation my.animate2 = 0; my.animblend = blend; my.blendframe = stand; } }
Code:
DEFINE animate,SKILL31; DEFINE animate2,SKILL32; DEFINE animblend,SKILL33; DEFINE currentframe,SKILL34; DEFINE blendframe,SKILL35;
DEFINE blend,-1; DEFINE stand,0; DEFINE run,1; DEFINE walk,2;
FUNCTION handle_animations(animation_speed) { IF (animation_speed <= 0) { animation_speed = 1; } IF (my.animblend == blend) { IF (my.currentframe == stand) { ent_animate(my,"stand",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("stand",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; IF (my.animate2 >= 100) { my.animate = 0; IF (my.blendframe == stand) { my.animblend = stand; } IF (my.blendframe == run) { my.animblend = run; } IF (my.blendframe == walk) { my.animblend = walk; } } } IF (my.animblend == stand) { ent_animate(my,"stand",my.animate,anm_cycle); my.animate += 0.8 * animation_speed * time; my.animate %= 100; my.currentframe = stand; } IF (my.animblend == run) { ent_animate(my,"run",my.animate,anm_cycle); my.animate += 6.8 * animation_speed * time; my.animate %= 100; my.currentframe = run; } IF (my.animblend == walk) { ent_animate(my,"walk",my.animate,anm_cycle); my.animate += 8 * animation_speed * time; my.animate %= 100; my.currentframe = walk; } }
Last edited by AxysPhenomenon; 07/12/06 11:04.
|
|
|
Re: Animation frames blending, player input/physic
[Re: DavidLancaster]
#64761
07/12/06 15:43
07/12/06 15:43
|
Joined: Jun 2005
Posts: 656
Grafton
User
|
User
Joined: Jun 2005
Posts: 656
|
Short, sweet and easy to understand snippit there AxysPhenomenon! And it works very well! Thanks a million!
Not two, not one.
|
|
|
Re: Animation frames blending, player input/physic
[Re: DavidLancaster]
#64762
07/13/06 03:39
07/13/06 03:39
|
Joined: May 2005
Posts: 138 jamrud khatulistiwa
Kotakide
Member
|
Member
Joined: May 2005
Posts: 138
jamrud khatulistiwa
|
I'm not a programmer, but judge from the look at the code, is very clean and sharp. it's getting better and better everyday. i'll just sit and wait you to release the demo using this code .
|
|
|
Re: Animation frames blending, player input/physic
[Re: Kotakide]
#64763
07/13/06 22:27
07/13/06 22:27
|
Joined: Aug 2000
Posts: 7,490
Orange Brat
OP
Senior Expert
|
OP
Senior Expert
Joined: Aug 2000
Posts: 7,490
|
My first attempts at using the Zelda code in mine were comical to say the least. I'll try again later. I'll also investigate that blending technique. That looks much more elegant and cleaner than what I have now. It also appears that it might be easier to add different animation modes easier(duck, jump, etc). For mine, you have to virtually double the size of the script to add something new.
My User Contributions master list - my initial post links are down but scroll down page to find list to active links
|
|
|
Re: Animation frames blending, player input/physic
[Re: Orange Brat]
#64764
07/24/06 01:55
07/24/06 01:55
|
Joined: Aug 2000
Posts: 7,490
Orange Brat
OP
Senior Expert
|
OP
Senior Expert
Joined: Aug 2000
Posts: 7,490
|
Here's a special version of the this system that doesn't use the c_instructions. It uses good ol' trace and ent_move. Some pre-6.31 users have problems with the official version: http://www.geocities.com/hainesrs/special_blending.ziphttp://www.geocities.com/hainesrs/special_blending.rar - same as ZIP only half the file size I think I may have added gamepad support for movementType 0(behind the back at all times camera), but I'm not sure if it's bugfree yet(edit: it isn't and mode 2 is screwy too). I took a 1 week break from this thing, so I don't know which way is up at the moment. BTW, the defaults on this "special" version are movementType 4, so it's in gamepad only, camera relative mode. The two analog stick control movement and camera and the 4 buttons on top of the controller also control the camera. Button 4(on my pad) is the run key(more like a walk key since it only work when the player is running..the sticks are touch sensitive). Defaults can be changed in "main.wdl."
My User Contributions master list - my initial post links are down but scroll down page to find list to active links
|
|
|
Re: Animation frames blending, player input/physic
[Re: Orange Brat]
#64765
08/13/06 01:29
08/13/06 01:29
|
Joined: Jul 2005
Posts: 366
eleroux
Senior Member
|
Senior Member
Joined: Jul 2005
Posts: 366
|
Hey Orange Brat! I am just studying this code and I found it's great! I am adapting the camera style to that one in games like 'thief3', which is a combination of MovementType 0 and 3. (The camera orbits with the mouse, but the player model keeps its orientation, like a freelook. But when the player hits a key or a mouse button, the player model makes a turn to get aligned to the camera target direction, as to run/walk/strafe/attack in the direction the camera is looking). I only found a strange thing at the end of moveCam(): Code:
c_trace(cam_centre.x,cam_pos.x, ignore_me + ignore_passable + ignore_models + ignore_sprites); if(trace_hit == 0) // trace hit something { vec_diff(temp.x,cam_pos.x,target.x); vec_diff(cam_pos.x,cam_pos.x,temp.x); }
vec_set(camera.x,cam_pos.x); ...
trace_hit should be -1 or 1 when c_trace hits something! Why is it tested against Zero? However, I tried (trace_hit !=0) and it never was TRUE. I made a test, and found out that trace_hit is always zero. My guess is that someone quick-fixed a non working IF by changing it to (trace_hit == 0) as a test, and since it worked, it was left as it is. But what is inside the brackets is executed all the time anyway! The IF could be completely removed. So why this is working anyway? I traced the code, and it works because, when c_trace fails the hit, target.x gets the same value of cam_pos. So... vec_diff(temp.x,cam_pos.x,target.x); //temp.x gets a value of {0,0,0} vec_diff(cam_pos.x,cam_pos.x,temp.x); //cam_pos is not changed. When the c_trace HITS something, the same two instructions do change cam_pos value. What puzzles me is that the trace_hit var is just not working after c_trace. Would this be a bug? Regards, Emilio EDIT EDIT EDIT I just added the cam code to a new, clean project, and it works as expected. It seems there's something in the test level you sent that prevents trace_hit to work. For my project to work, I just had to change the line: if(trace_hit != 0) // trace hit something
Last edited by eleroux; 08/13/06 02:26.
|
|
|
Re: Animation frames blending, player input/physic
[Re: Orange Brat]
#64767
08/13/06 12:42
08/13/06 12:42
|
Joined: Aug 2000
Posts: 7,490
Orange Brat
OP
Senior Expert
|
OP
Senior Expert
Joined: Aug 2000
Posts: 7,490
|
One quick info. update. I finally got motivated and am tinkering with the free, open source Intense Pathfinding from Larry Laffer and RAFU. It'll be movementType 5 once I get it in place. I have everything in place(per the supplied documentation), however I'm having trouble getting my graph to build. No crashing or errors..just nothing, yet. Once I get it working in the test level with their supplied movement code, I'll attempt the transition to my own code. Once completed, I'll try and address any additional bugs or issues that are still outstanding. Of course, I will seek permission to release the Intense integration before uploading. If they say no, then at least there will be the fixes and or new stuff. @eleroux: Once you get that Thief3 cam working, I'd like to take a look at it if you don't mind. That may become movementType 6 or better yet I'll just make it a feature of type 3 and 4. As for wall collision, the Zelda movement/cam thread code is the best. Here's the raw code for anyone who wants to take a crack at it. None of this is mine, and I'm wanting to integrate it into my "cam.wdl" at some point, so the system will have perfect wall collision. The current version glides along surfaces but it clips like every other camera out there(except Zelda thus the reason I want to splice it in). Anyway, it's in two chunks...the first one is REALLY raw and has lines that would need to be eliminated or else they'll conflict with what I've already got in place(like the cam_height stuff in chunk 1...the current cam_pos.z trig lines will work for this...it's just a matter of porting my method into this one and making it all gel). The 2nd part is more refined. Good luck to anyone who wants to try and tame this. We'll all owe you big time(note that it uses old trace/ent_move...my code uses c_trace and c_move, however I have set enable_polycollision to 0.5 so it still behaves like the old instructions). Keep in mind that the goal is simply to get it to where the camera neer clips into the geometry under any circumstances. There may be lines that mimic the Zelda style camera movement(it's wonky compared to my more traditional motion), so if something in this script makes it do the wonky dance, then it should be gutted:
Below is the code which handles camera collision in the zelda code, it has been a long time since I looked at this and even now I'm not sure why some instructions and calculations are being used. I went through and commented what I thought was going on in certain places, it may not make sense, somethings confuse me alot.
Hope it helps.
David
//where camera.pan is being used in trigonometry calculations, the value used to be cam_xyangle in the zelda code, I'm not exactly sure if changing it to camera.pan will work or not
//
FUNCTION pan_back()
{
//cam height is the height the camera is relative to the player's z coordinte
cam_height -= mouse_force.y * 40 * time;
cam_height = clamp(cam_height, -150, 300);
//dist_total is the radius the camera is from the player
vec_set(temp.x, vector(player.x - fcos(camera.pan, dist_total - 10), player.y - fsin(camera.pan, dist_total - 10), player.z + cam_height)); //find the camera position 10 quants behind the camera (not sure why I'm tracing 10 quants behind the camera, would be better to use vec_add rather than just the x and y component)
vec_diff(temp2.x,player.x,temp.x); //from behind the camera to the player
vec_normalize(temp2.x,16); //set vector to magnitude of 16
vec_add(temp.x,temp2.x); //set temp.x 16 quants longer, so we are tracing 16 quants behind the camera
trace_mode = ignore_me + ignore_passable;
trace (player.x,temp.x); //trace from the player to the camera position, this trace is used to calculate planar_to and camera_move_to.z
dist_traced = sqrt((target.x - player.x)*(target.x - player.x)+(target.y - player.y)*(target.y - player.y));
IF (dist_traced > 0) //if the trace hit a wall
{
vec_set(temp.x,target.x);
vec_diff(temp2.x,player.x,target.x); //vector from trace hit point to the player
vec_normalize(temp2.x,16); //normalize vector
vec_add(temp.x,temp2.x); //move temp.x 16 quants behind target.x
result = sqrt((temp.x - my.x)*(temp.x - my.x) + (temp.y - my.y)*(temp.y - my.y));
IF (result < dist_total)
{
planar_to = result; //planar_to is the radius at which the camera moves to, if the calculated distance from the camera to the player is less than the maximum distance the camera could possibly be, not exactly sure why this if statement is being used
}
}
ELSE
{
planar_to = dist_total;
}
camera_move_to.z = target.z; //camera_move_to vector is the coordinates at which the camera smoothly moves to, z component is calculate instantly whilst x and y are calculated differently
player.z -= 15; //temporarily changed so that camera focusus slightly above middle
var temp2[3];
vec_set(temp2,camera.x);
vec_set(temp,my.x);
vec_sub(temp,temp2.x);
vec_to_angle(temp.pan,temp);
camera.tilt = temp.tilt + 7; //this causes the camera to tily towards the player
//this smoothly moves dist_planar to the planar_to variable (the radius the camera is from the player)
IF (abs(dist_planar - planar_to) > 2)
{
cradius_speed = (dist_planar - planar_to) / -1;
}
ELSE
{
cradius_speed = 0;
my.skill15 = 0;
}
MY.skill15 += (TIME * cradius_speed) - (min(TIME*0.7,1) * my.skill15);
dist_planar += MY.skill15 * TIME;
dist_planar = planar_to;
//tracing from camera to below the camera to see if the camera is on the ground
trace_mode = ignore_me + ignore_passable;
result = trace (vector(camera.x,camera.y,player.z + 15),vector(camera.x,camera.y,camera.z + 5));
IF (result > 0) && (cam_height > result - 5)
{
cam_height = result - 5;
} //if we have traced something place the camera above it
camera_move_to.x = player.x - dist_planar * cos(camera.pan); //set the value at which the camera needs to smoothly move to
camera_move_to.y = player.y - dist_planar * sin(camera.pan);
//this is similar code to the template camera, the camera needs to be at the camera_move_to coordinates, this traces at a position, which smoothly moves towards the camera_move_to, and places the camera at the target.x vector, this works well because instead of placing the camera ta camera_move_to, it traces at a position which smoothly moves to camera_move_to
// move towards target position
//camera_smooth_to vector smoothly but quicly moves towards the camera_move_to.x variable (the position the camera should be)
temp2 = min(1,0.5 * time); // value of 1 places us at target, this value is what allows the smooth movement
camera_smooth_to.x += temp2*(camera_move_to.x - camera_smooth_to.x); //the bigger the gap between camera_move_to.x - camera_smooth_to.x, the faster the camera moves
camera_smooth_to.y += temp2*(camera_move_to.y - camera_smooth_to.y);
camera_smooth_to.z += temp2*(camera_move_to.z - camera_smooth_to.z);
// keep camera from penetrating walls
vec_diff(temp2.x,camera_smooth_to.x,player.x); //find vector from player to the positoin the camera should be
vec_normalize(temp2.x,16); //move vector 16 quants behind camera
vec_add(temp2.x,camera_smooth_to.x); // temp2 = temp_cdist + 16 units away from view target
me = player;
trace_mode = ignore_me + ignore_passable + ignore_models + ignore_sprites;
IF (trace(player.x,temp2.x) > 0)
{ //trace from the player to the position 16 quants behind the camera
//if the trace hit a wall
vec_diff(temp2.x,player.x,target.x); //from player to the target position
vec_normalize(temp2.x,16);
vec_set(camera.x,target.x); //set camera at the traced position
vec_add(camera.x,temp2.x);
}
ELSE
{
//if the trace has not hit something set the camera to camera_smooth_to;
vec_set(camera.x,camera_smooth_to.x);
}
}
Hey OB
Sorry for the late reply.
I hope this works, this is very simple camera movement which should work with any entity, just have the player call handle_camera(); from it's main loop. And it should work. Although simple camera collision may be more effective, so I've added something like that further below.
Let me know how it goes.
David
var camera_move_to[3];
var camera_smooth_to[3];
var camera_distance = 200;
var camera_pan;
var camera_tilt;
FUNCTION handle_camera()
{
camera_pan -= mouse_force.x * 12 * time_step;
camera_tilt += mouse_force.y * 8 * time_step;
camera_tilt = clamp(camera_tilt,-30,10);
camera.pan = camera_pan;
temp = fcos(camera_tilt,-camera_distance);
vec_set(camera_move_to.x,vector(my.x + fcos(camera.pan,temp),my.y + fsin(camera.pan,temp),my.z + 20 + fsin(camera_tilt,-camera_distance)));
//this is similar code to the template camera, the camera needs to be at the camera_move_to coordinates, this traces at a position, which smoothly moves towards the camera_move_to, and places the camera at the target.x vector, this works well because instead of placing the camera ta camera_move_to, it traces at a position which smoothly moves to camera_move_to
// move towards target position
temp = min(1,0.5 * time); // value of 1 places us at target, this value is what allows the smooth movement
camera_smooth_to.x += temp*(camera_move_to.x - camera_smooth_to.x);
camera_smooth_to.y += temp*(camera_move_to.y - camera_smooth_to.y);
camera_smooth_to.z += temp*(camera_move_to.z - camera_smooth_to.z);
// keep camera from penetrating walls
vec_diff(temp.x,camera_smooth_to.x,my.x);
vec_normalize(temp.x,16);
vec_add(temp.x,camera_smooth_to.x); // temp2 = temp_cdist + 16 units away from view target
trace_mode = ignore_me + ignore_passable + ignore_models + ignore_sprites;
IF (trace(my.x,temp.x) > 0)
{
vec_diff(temp.x,my.x,target.x);
vec_normalize(temp.x,16);
vec_set(camera.x,target.x);
vec_add(camera.x,temp.x);
}
ELSE
{
vec_set(camera.x,camera_smooth_to.x);
}
vec_diff(temp.x,my.x,camera.x);
vec_to_angle(temp.pan,temp.x);
camera.pan = temp.pan;
camera.tilt = temp.tilt;
}
FUNCTION handle_camera()
{
camera.pan -= mouse_force.x * 12 * time_step;
camera.tilt += mouse_force.y * 8 * time_step;
camera.tilt = clamp(camera.tilt,-30,10);
temp = fcos(camera.tilt,-camera_distance);
vec_set(camera.x,vector(my.x + fcos(camera.pan,temp),my.y + fsin(camera.pan,temp),my.z + 20 + fsin(camera.tilt,-camera_distance)));
vec_diff(temp.x,camera.x,my.x); //find the vector from the player to the camera
vec_normalize(temp.x,16); //get the magnitude of it's vector to 16 quants and store it in temp
vec_add(temp.x,camera.x); //add the vector (from player to camera) of a magnitude of 16 quants and add it to the camera's position.
trace_mode = ignore_me+ignore_passable;
result = trace(my.x,temp.x); //trace from the player to 16 quants behind the camera.
IF (result > 0)
{
vec_diff(temp.x,my.x,target.x); //find the vector from the point the trace hit to the player
vec_normalize(temp.x,16); //get the magnitude of this vector to 16 quants and store in temp
vec_set(camera.x,target.x); //place the camera at the trace hit point
vec_add(camera.x,temp.x); //move the camera away from the wall by the vector temp, 16 quants towards the player
}
}
My User Contributions master list - my initial post links are down but scroll down page to find list to active links
|
|
|
|