Motion AfterImage Effect??
by Kevin Epps · in Torque Game Builder · 03/09/2008 (11:49 am) · 10 replies
I don't really know what anyone else would call this to do a proper search, but I'm trying to figure out how achieve an afterimage motion effect.
Meaning, I want copies of a sprite to trail the main sprite and fade out. I really hope you know what I'm talking about because I don't know how to put it into words without just calling it a motion afterimage effect.
Does anyone know how to achieve this in TGB? Maybe use particles for this or something?
Meaning, I want copies of a sprite to trail the main sprite and fade out. I really hope you know what I'm talking about because I don't know how to put it into words without just calling it a motion afterimage effect.
Does anyone know how to achieve this in TGB? Maybe use particles for this or something?
About the author
#2
03/09/2008 (4:03 pm)
You'd just have to create copies of the static sprite that just have the same dimensions and picture. Set them at a lower alpha then fade them out and delete them. If the object is moving, the images will be copied in a row and have different blend alphas then fade out.
#3
You can easily adapt this for different objects, but I'll be posting a much more refined method later. (After I write it.)
03/09/2008 (4:48 pm)
Here's some quick code for an after image effect for an animated sprite:// after image motion blur effect
function t2dAnimatedSprite::doAfterImageEffect(%this)
{
%this.createAfterImageClone();
%this.schedule(50, "createAfterImageClone");
%this.schedule(100, "createAfterImageClone");
%this.schedule(150, "createAfterImageClone");
%this.schedule(200, "createAfterImageClone");
%this.schedule(250, "createAfterImageClone");
%this.schedule(300, "createAfterImageClone");
%this.schedule(350, "createAfterImageClone");
%this.schedule(400, "createAfterImageClone");
%this.schedule(450, "createAfterImageClone");
%this.schedule(500, "createAfterImageClone");
}
function t2dAnimatedSprite::createAfterImageClone(%this)
{
%clone = new t2dAnimatedSprite()
{
scenegraph = %this.getSceneGraph();
class = "afterImageObject";
size = %this.getSize();
position = %this.getPosition();
layer = (%this.getLayer() + 1);
flipX = %this.FlipX;
rotation = %this.getRotation();
animationName = %this.getAnimation();
};
%clone.setFrameChangeCallback(true);
%clone.setAnimationFrame(%this.getAnimationFrame());
%clone.fadeOut(0.14, 50, 0);
%clone.schedule(1500, "safeDelete");
}
function afterImageObject::onFrameChange(%this, %frameIndex)
{
%this.setAnimationFrame(%frameIndex - 1);
}You can easily adapt this for different objects, but I'll be posting a much more refined method later. (After I write it.)
#4
03/09/2008 (5:00 pm)
Oh yeah, this function would probably be helpful://This function makes the object gradually disappear.
function t2dSceneObject::fadeOut(%this, %increment, %speed, %goal)
{
if(isEventPending(%this.fadeInSchedule))
cancel(%this.fadeInSchedule);
%curAlpha = %this.getBlendAlpha();
%this.setBlendAlpha(%curAlpha - %increment);
if(%this.getBlendAlpha() >= %goal)
%this.fadeOutSchedule = %this.schedule(%speed, "fadeOut", %increment, %speed, %goal);
else
{
%this.setBlendAlpha(%goal);
cancel(%this.fadeOutSchedule);
}
}
#5
03/09/2008 (7:55 pm)
Thanks so much, Kevin!
#7
03/12/2008 (1:33 pm)
No problem Kevin. I'm still going to post some more refined code, but I've been pretty busy. ;)
#8
03/21/2008 (4:25 pm)
Finally got around to working on the after image effect some more. Now you can pass in parameters that distinctly change how the effect plays out. Recommended defaults:object.doSimpleAfterImageEffect(100, 1500, false, true, 0.14, 50, 0);
//**simple after image motion blur effect for animated sprites**
//frequency - how often to make after image clones (copies of object that fade out)
//duration - how long the effect will last
//owner visible - if true, the owner stays visible during the entire effect
// if false, the owner disappears during the effect, and reappears
// at the end.
//still frames - if true, then the copies are forced to render the same exact frame
// as the owner had when the particular copy was made. Bit of a hacked
// solution. Changes the frame back to previous one on an onFrameChange
// callback.
//increment, speed, goal - all of these parameters are used soly for the fadeOut
// function. Increment is the number by which to reduce
// the alpha each speed interval which is in milliseconds.
// Goal tells the function when to stop fading.
function t2dAnimatedSprite::doSimpleAfterImageEffect(%this, %frequency, %duration, %ownerVisible, %stillFrames, %increment, %speed, %goal)
{
for(%i = 0; %i < %duration; %i += %frequency)
{
%this.schedule(%i, "createAfterImageClone", %stillFrames, %increment, %speed, %goal);
}
if(!%ownerVisible)
{
%this.visible = false;
%this.schedule(%duration, "setVisible", true);
}
}
//used by the after image effects to produce copy images.
function t2dAnimatedSprite::createAfterImageClone(%this, %stillFrames, %increment, %speed, %goal)
{
%clone = new t2dAnimatedSprite()
{
scenegraph = %this.getSceneGraph();
class = "afterImageObject";
size = %this.getSize();
position = %this.getPosition();
layer = (%this.getLayer() + 1);
flipX = %this.FlipX;
rotation = %this.getRotation();
animationName = %this.getAnimation();
};
%clone.setAnimationFrame(%this.getAnimationFrame());
%clone.fadeOut(%increment, %speed, %goal);
//the next line assumes that your goal is 0. It just automatically computes a safe waiting
//time for the deletion of the clone. Use the commented line after it to manually control
//the deletion. Make sure to comment the automated line.
%clone.schedule(((((1 - %increment) * %speed)/43) * 1500), "safeDelete");
//%clone.schedule([int in milliseconds] "safeDelete");
if(%stillFrames)
%clone.setFrameChangeCallback(true);
}
//hacked solution to freeze an animation
function afterImageObject::onFrameChange(%this, %frameIndex)
{
%this.setAnimationFrame(%frameIndex - 1);
}
function t2dStaticSprite::doSimpleAfterImageEffect(%this, %frequency, %duration, %ownerVisible, %increment, %speed, %goal)
{
for(%i = 0; %i < %duration; %i += %frequency)
{
%this.schedule(%i, "createAfterImageClone", %increment, %speed, %goal);
}
if(!%ownerVisible)
{
%this.visible = false;
%this.schedule(%duration, "setVisible", true);
}
}
function t2dStaticSprite::createAfterImageClone(%this, %increment, %speed, %goal)
{
%clone = new t2dStaticSprite()
{
scenegraph = %this.getSceneGraph();
class = "afterImageObject";
size = %this.getSize();
position = %this.getPosition();
layer = (%this.getLayer() + 1);
flipX = %this.FlipX;
rotation = %this.getRotation();
imageMap = %this.getImageMap();
};
%clone.fadeOut(%increment, %speed, %goal);
//the next line assumes that your goal is 0. It just automatically computes a safe waiting
//time for the deletion of the clone. Use the commented line after it to manually control
//the deletion. Make sure to comment the automated line.
%clone.schedule(((((1 - %increment) * %speed)/43) * 1500), "safeDelete");
//%clone.schedule([int in milliseconds] "safeDelete");
}
#9
03/29/2008 (1:13 pm)
Now to make this into a behavior :)
Torque Owner Brian Carter