I just wanted to share this code I came with while playing with ent_blendpose.
I know blendpose is slower than ent_blend, but we are talking about just a few frames, and I think there are other advantages.
What I like in this is that the animation that is blending-in starts animating right away (no wait for the blend to end), and that the code ended up ridiculously simple. (To tell the truth I had no idea it would end this way when I started coding)
Be aware that this is not ready-to-use. It doesn't include the functions for setting up strings and animations, or entity physics - I just provide it as a general idea of using ent_blendpose.
Code:
Function mAnim_Animate_Actor()
{
mAnim_initSceneStrings(); //setup animation strings
var base_scene = 1;
var base_scene_old = 1;
var base_mode = 0; //cyclic, one time, one time no blend
var base_cycle = 0;
var base_anim = 0;
var base_anim_old = 0;
var blending = 0;
//loop while actor exists
while (me)
{
//set animation state
if (my._mActor_movestate == STATE_NONE)
{
//no animation
wait(1);
continue;
}
//Get Base scene and parameters
mAnim_setBaseAnim(); //will determine the scene and other global vars below
base_scene = mAnim_temp_basescene;
base_mode = mAnim_temp_basemode;
base_cycle = mAnim_temp_basecycle; //temp globals set by the function
if (base_cycle == 0)
{
base_cycle = 16; //to avoid possible errors
}
if (base_cycle < 0)
{
//time based animation
my._mAnim_distance += time_step;
}
else
{
//distance based
my._mAnim_distance += (my._mActor_distance); //add phisical distance to animation value
}
//At the end of a cycle
if (my._mAnim_distance >= base_cycle)
{
if (base_mode != 0)
{
//Animation is Once-Only. Reset state
my._mActor_movestate = STATE_MOVE;
my._mActor_movestate_val = STATEVAL_FORWARD;
my._mAnim_distance = 0;
wait(1);
continue; //go back to the loop //what happens to the upper scene?
}
//warp time or distance
if (my._mAnim_distance > abs(base_cycle)) //why while?
{
my._mAnim_distance -= abs(base_cycle);
}
}
//Warp if negative
if (my._mAnim_distance < 0)
{
my._mAnim_distance += abs(base_cycle);
}
if (base_cycle == 0)
{
beep; //error
base_cycle == 1;
}
//calculate a percentage for the time/dist
base_anim = (100* my._mAnim_distance / abs(base_cycle));
//NOTE: should prevent empty pointer errors here (from the "text" array)
ent_animate(me,mAnim_scene_text.string[base_scene],base_anim,ANM_CYCLE *(base_mode ==0));
//THE BLEND CODE
if ( (base_scene != base_scene_old) && ( blending <= 0) )
{
//set up a blend, only if not blending
my.pose = 2;
//store the old pose in pose 2 (only once)
ent_animate(me,mAnim_scene_text.string[base_scene_old],base_anim_old, ANM_CYCLE);
my.pose = 1;
blending = 99;
}
//Execute the blend each cycle, backwards
if (blending >0)
{
ent_blendpose(me,1,2,blending);
blending -=50*time_step;
}
if (blending <=0)
{
//end blend
base_scene_old = base_scene;
base_anim_old = base_anim;
}
wait(1); //wait (redraw) a frame
} //end while (me)
}
Note that the Blend part of the function is about the 15 last lines.
|Emilio|