Working example of fxAnimatedSprite2D ??
by Nicolas Quijano · in Torque Game Builder · 03/02/2005 (2:26 pm) · 13 replies
Hi, was just wondering if there is an example of using an fxAnimatedSprite2D somewhere ?
Specifically, using a chunked image, the datablocks for the animations, that sort of thing.
Thanks in advance
Specifically, using a chunked image, the datablocks for the animations, that sort of thing.
Thanks in advance
About the author
Veteran and even a casualty of the mainstream game industry, as well as one of the early adopters of GG's tech : did the first builds of Orbz for MacOS X. A (great) Old One? And like one of 'em Cthonic thingies, from a great slumber or depths, I rise...
#2
The chunked-image datablock is a specialised one specifically for large images that are above the maximum specification you're targetting your game to. As you know, all images are loaded into the graphics card and require the appropriate size support for them to render correctly. We'll be adding interrogative support for this later so you can adjust what you do dynamically at runtime.
Anyway, if you render a 1600x1200 image say, the graphics card needs that to be a power-of-two texture so T2D will automatically resize it to 2048x2048 which is a large texture, not for a 6800 Ultra but for lots of other cards, it just wouldn't work and your shipped game will just not display that sprite/background.
Most images like this are just backgrounds and are nearly always static and doing animations at this resolution is a little crazy at this point in time.
The chunked-image datablocks are specifically designed to be used with the fxChunkedSprite2D and do not offer animation support. Unlike an object just to produce backgrounds, it inherits all the capabilities of the core including mounting, physics, hardware blending etc. What it does is internally split-up the image into lots of seperate, graphics-card compatible textures (256x256 and smaller) and render them seemlessly onto the screen.
This means that no matter how big it gets, it should work unless the image is so big that you run out of video-memory which is also possible if you get really silly.
We use this for large-pieces of scenery in the fish-demo as well as the wide-screen, very high-res street-scene background (2560 x 960) in the gravity-demo featuring our hero "Flegg".
You can do some serious rendering with this beast and all it asks is that you don't use it for animations. :)
Okay, next problem is controlling your animations when you move in a specific direction. Real easy to do. Presumably you have a signal when you change to a new direction? When you do, simply play the appropriate animation which will be one of eight animations you've setup like walkN, walkNE, walkE etc.
- Melv.
03/02/2005 (2:53 pm)
Well, I really need to go to bed (got a stinking cold here) but here's my offering before I disappear...The chunked-image datablock is a specialised one specifically for large images that are above the maximum specification you're targetting your game to. As you know, all images are loaded into the graphics card and require the appropriate size support for them to render correctly. We'll be adding interrogative support for this later so you can adjust what you do dynamically at runtime.
Anyway, if you render a 1600x1200 image say, the graphics card needs that to be a power-of-two texture so T2D will automatically resize it to 2048x2048 which is a large texture, not for a 6800 Ultra but for lots of other cards, it just wouldn't work and your shipped game will just not display that sprite/background.
Most images like this are just backgrounds and are nearly always static and doing animations at this resolution is a little crazy at this point in time.
The chunked-image datablocks are specifically designed to be used with the fxChunkedSprite2D and do not offer animation support. Unlike an object just to produce backgrounds, it inherits all the capabilities of the core including mounting, physics, hardware blending etc. What it does is internally split-up the image into lots of seperate, graphics-card compatible textures (256x256 and smaller) and render them seemlessly onto the screen.
This means that no matter how big it gets, it should work unless the image is so big that you run out of video-memory which is also possible if you get really silly.
We use this for large-pieces of scenery in the fish-demo as well as the wide-screen, very high-res street-scene background (2560 x 960) in the gravity-demo featuring our hero "Flegg".
You can do some serious rendering with this beast and all it asks is that you don't use it for animations. :)
Okay, next problem is controlling your animations when you move in a specific direction. Real easy to do. Presumably you have a signal when you change to a new direction? When you do, simply play the appropriate animation which will be one of eight animations you've setup like walkN, walkNE, walkE etc.
- Melv.
#3
I guess it's only to be used when the in-memory representation is not a power of 2, right ?
Doh :)
03/02/2005 (3:08 pm)
Oh, I wanted to use chunked becuase I have a strip of 32x32 frames but the complete texture is not power of 2...I guess it's only to be used when the in-memory representation is not a power of 2, right ?
Doh :)
#4
T2D can use non-POT images for everything apart from the fxScroller2D so don't worry, just do it. Previously it didn't but now it does. Be aware that T2D will internally pad the textures which wastes video-memory though and it reports so in the console.
Chunked-images are only for images that are larger than the maximum support for users your target platform.
Cutting edge cards use 4096x4096 and workstation-level ones even higher. The average is probably 1024 or maybe 2048 but lots of people still have 256 or 512 only.
Typically 256x256 textures will work almost anywhere. Above this, you have to ask yourself if the users will have support for it, most probably will but that's your choice.
Totally your choice.
- Melv.
03/02/2005 (3:17 pm)
No.T2D can use non-POT images for everything apart from the fxScroller2D so don't worry, just do it. Previously it didn't but now it does. Be aware that T2D will internally pad the textures which wastes video-memory though and it reports so in the console.
Chunked-images are only for images that are larger than the maximum support for users your target platform.
Cutting edge cards use 4096x4096 and workstation-level ones even higher. The average is probably 1024 or maybe 2048 but lots of people still have 256 or 512 only.
Typically 256x256 textures will work almost anywhere. Above this, you have to ask yourself if the users will have support for it, most probably will but that's your choice.
Totally your choice.
- Melv.
#5
03/02/2005 (3:49 pm)
For the padded textures, will there be some kind of texture packing to help out? I'm surprised this isn't already part of TGE, actually.
#6
heres the image I use
03/02/2005 (11:02 pm)
datablock fxImageMapDatablock2D(circleGuy)
{
mode = cell;
cellWidth = 64;
cellHeight = 64;
textureName = "~/client/images/circleGuy";
};
datablock fxAnimationDatablock2D(circleGuyStandLeft)
{
imageMap = circleGuy;
animationFrames = "0";
animationTime = 1;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyWalkLeft)
{
imageMap = circleGuy;
animationFrames = "1 2 3";
animationTime = 0.75;
animationCycle = 1;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyStandRight)
{
imageMap = circleGuy;
animationFrames = "7";
animationTime = 1;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyWalkRight)
{
imageMap = circleGuy;
animationFrames = "6 5 4";
animationTime = 0.75;
animationCycle = 1;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyCastSpellLeft)
{
imageMap = circleGuy;
animationFrames = "8 9 10";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyCastSpellLeftEnd)
{
imageMap = circleGuy;
animationFrames = "10";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuySpellCastedLeft)
{
imageMap = circleGuy;
animationFrames = "11";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyCastSpellRight)
{
imageMap = circleGuy;
animationFrames = "15 14 13";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuyCastSpellRightEnd)
{
imageMap = circleGuy;
animationFrames = "13";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
datablock fxAnimationDatablock2D(circleGuySpellCastedRight)
{
imageMap = circleGuy;
animationFrames = "12";
animationTime = 0.75;
animationCycle = 0;
randomStart = 0;
};
$circleGuy = new fxAnimatedSprite2D() { scenegraph = t2dSceneGraph; };
$circleGuy.setPosition("-35 0");
$circleGuy.setSize( "10 7" );
$circleGuy.playAnimation(circleGuyStandLeft)heres the image I use
#7
03/02/2005 (11:05 pm)
Here are the keys and corresponding functions I use with themnew ActionMap(playerMap);
// Bind keys to actions.
playerMap.bindCmd(keyboard, "w", "castSpellLeft();", "spellCastedLeft();");
playerMap.bindCmd(keyboard, "s", "castSpellRight();", "spellCastedRight();");
playerMap.bindCmd(keyboard, "a", "circleGuyLeft();", "circleGuyLeftStop();");
playerMap.bindCmd(keyboard, "d", "circleGuyRight();", "circleGuyRightStop();");
playerMap.bindCmd(keyboard, "space", "playerFire();", "");
playerMap.push();
function castSpellLeft()
{
$circleGuy.playAnimation(circleGuyCastSpellLeft, 0);
$animation = "circleGuyCastSpellLeft";
%fire = new fxParticleEffect2D() { scenegraph = t2dSceneGraph; };
%fire.loadEffect("~/client/effects/fire_fury.eff");
%fire.mount( $circleGuy, "0.8 -0.12", 0, false );
%fire.setRotation( 180 );
%fire.setScale( "0.1 0.1" );
%fire.playEffect();
}
function spellCastedLeft()
{
$circleGuy.playAnimation(circleGuySpellCastedLeft, 0);
%fireBall = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%fireBall.setPosition( $circleGuy.getPosition() );
%fireBall.setSize( "3 1.5" );
%fireBall.setImageMap( enemymissileImageMap );
%fireBall.setLinearVelocityX( -35 );
%fireBall.setWorldLimit( kill, "-60 -40 60 40" );
%fire = new fxParticleEffect2D() { scenegraph = t2dSceneGraph; };
%fire.loadEffect("~/client/effects/smallThruster.eff");
%fire.mount( %fireBall, "0.8 -0.12", 0, false );
%fire.setRotation( 180 );
%fire.playEffect();
}
function castSpellRight()
{
$circleGuy.playAnimation(circleGuyCastSpellRight, 0);
$animation = "circleGuyCastSpellRight";
}
function spellCastedRight()
{
$circleGuy.playAnimation(circleGuySpellCastedRight, 0);
%fireBall = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%fireBall.setPosition( $circleGuy.getPosition() );
%fireBall.setRotation( 180 );
%fireBall.setSize( "3 1.5" );
%fireBall.setImageMap( enemymissileImageMap );
%fireBall.setLinearVelocityX( 35 );
%fireBall.setWorldLimit( kill, "-60 -40 60 40" );
%fire = new fxParticleEffect2D() { scenegraph = t2dSceneGraph; };
%fire.loadEffect("~/client/effects/smallThruster.eff");
%fire.mount( %fireBall, "0.8 -0.12", 0, false );
%fire.setRotation( 0 );
%fire.playEffect();
}
function circleGuyLeft()
{
$circleGuy.playAnimation(circleGuyWalkLeft);
$circleGuy.setLinearVelocityX( -10 );
}
function circleGuyLeftStop()
{
if ( $circleGuy.getLinearVelocityX() < 0 )
{
$circleGuy.setLinearVelocityX( 0 );
$circleGuy.playAnimation(circleGuyStandLeft);
}
}
function circleGuyRight()
{
$circleGuy.playAnimation(circleGuyWalkRight);
$circleGuy.setLinearVelocityX( 10 );
}
function circleGuyRightStop()
{
if ( $circleGuy.getLinearVelocityX() > 0 )
{
$circleGuy.setLinearVelocityX( 0 );
$circleGuy.playAnimation(circleGuyStandRight);
}
}
#8
@Melv: sorry about your cold ! hope you feel better... get some needed rest man :)
p.s. for those that will have use, working on a simple animation queueing system in script so you can que animations to animatedsprites and if you want them they will complete the queue in order... nothing too major, just some data handling :) (if you check my plans I have been working in torqueScript data handling a lot)
03/02/2005 (11:08 pm)
Those work... with the exception of the bug that causes non-cycle animations to end at the first frame (which Melv has already addressed and fixed for future versions via his post on the bug forums)@Melv: sorry about your cold ! hope you feel better... get some needed rest man :)
p.s. for those that will have use, working on a simple animation queueing system in script so you can que animations to animatedsprites and if you want them they will complete the queue in order... nothing too major, just some data handling :) (if you check my plans I have been working in torqueScript data handling a lot)
#9
Thanks that is exactly what I was looking for! I now have a little guy who animates in all the directions I need :o)
03/03/2005 (12:47 am)
@MatthewThanks that is exactly what I was looking for! I now have a little guy who animates in all the directions I need :o)
#10
Thanks that is exactly what I was looking for! I now have a little guy who animates in all the directions I need :o)
03/03/2005 (12:49 am)
@MatthewThanks that is exactly what I was looking for! I now have a little guy who animates in all the directions I need :o)
#11
Be aware that for near-future development, we want much more sophisticated animation controls including different interpolation schemes, backwards/bounce through frames as well as random frame mode, queued animations and much more. None of that work is actually that difficult and it shouldn't break the existing features at all. There are certain areas such as the animation that may seem a little bare at the moment, that will most certainly change although priorities also change but it is an intention.
As mentioned above, lots of fixes in the next update.
- Melv.
03/03/2005 (12:58 am)
Thanks guys, cold is causing me to lag behind at the moment. Bah, damn cold.Be aware that for near-future development, we want much more sophisticated animation controls including different interpolation schemes, backwards/bounce through frames as well as random frame mode, queued animations and much more. None of that work is actually that difficult and it shouldn't break the existing features at all. There are certain areas such as the animation that may seem a little bare at the moment, that will most certainly change although priorities also change but it is an intention.
As mentioned above, lots of fixes in the next update.
- Melv.
#12
Melv, do we have a flag to reverse an animation, or is it as I think it is : currently my only option is doing another datablock with the list of frames reversed ?
Thanks, keep up the good work ;)
03/03/2005 (7:37 am)
Got it to work, but thanks for posting that, should be useful to other users, erh, addicts :)Melv, do we have a flag to reverse an animation, or is it as I think it is : currently my only option is doing another datablock with the list of frames reversed ?
Thanks, keep up the good work ;)
#13
- Melv.
03/03/2005 (9:15 am)
As I mentioned above, we'll be adding backwards/bounce animations later. For the moment though, you'll have to create an additional datablock.- Melv.
Torque Owner Peter Dwyer
At the moment I'm stuck trying to get some animations set-up for a single sprite that walks in 8 directions. How do I set it up so that I can switch between the frames as I need to?
Edit: Sounds like time for one of Melvs excellent mini tutorials :o)