Game Development Community

setAnimationFrame() Frame Index Invalid Error

by practicing01 · in Torque Game Builder · 08/06/2012 (6:38 am) · 3 replies

Hello, I bought Torque 2D a few weeks ago and am slowly learning it. I've echoed the t2dAnimationDatablock.animationFrames variable and it shows the proper values. However, the console says there is an error with the provided arguments to setAnimationFrame() (that they aren't within range).

Link to full project (26mb):
http://www.mediafire.com/?vq77zx51d2ttxlg

Code that initiates player and declares movement function:
processplayer.cs:
function a_player()
{

%imghandle=new t2dImageMapDatablock()
{
imageName="~/data/playersprites/jillvalentine/jillvalentine.png";
imageMode="CELL";
frameCount="-1";
filterMode="NONE";
filterPad="1";
preferPerf="1";
cellRowOrder="1";
cellOffsetX="0";
cellOffsetY="0";
cellStrideX="0";
cellStrideY="0";
cellCountX="-1";
cellCountY="-1";
cellWidth="16";
cellHeight="23";
preload="1";
allowUnload="1";
force16Bit="0";
};

$managedDatablockSet.add(%imghandle);

%animhandle=new t2dAnimationDatablock()
{
imageMap=%imghandle;
animationFrames="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15";
animationTime="2.0";
animationCycle="1";
randomStart="0";
startFrame="0";
animationPingPong="0";
animationReverse="0";
};

$managedDatablockSet.add(%animhandle);

%spritehandle=new t2dAnimatedSprite()
{
class="a_playersprite";
animationName=%animhandle;
canSaveDynamicFields="1";
Position="2.870 -27.719";
size="16 23";
};

%spritehandle.setFrameChangeCallback(true);

scenegraph_levelcontent.add(%spritehandle);

%handle=new ScriptObject()
{

imagemapdatablock_playerspritehandle=%imghandle;
animationdatablock_playerspritehandle=%animhandle;
sprite=%spritehandle;
execpath="~/data/playersprites/jillvalentine/jillvalentine.cs";
//0=up 1=down 2=left 3=right
keysdown[0]=false;keysdown[1]=false;keysdown[2]=false;keysdown[3]=false;
animframeindices[0]="0 0";//down stand
animframeindices[1]="1 1";//up stand
animframeindices[2]="2 2";//right stand
animframeindices[3]="3 3";//left stand
animframeindices[4]="4 6";//down walk
animframeindices[5]="7 9";//up walk
animframeindices[6]="10 12";//right walk
animframeindices[7]="13 15";//left walk
curdir=1;//0=up 1=down 2=left 3=right
};

sceneWindow2D.mount(%spritehandle,0.5,0.5,0.5,1);

exec("./playeronframechange.cs");

%spritehandle.playAnimation(%spritehandle.animationName,false,%handle.animframeindices[0].X,false);

return %handle;
}

$players[$myclient]=a_player();

exec("./keycleanup.cs");

function moveplayerup()
{
$players[$myclient].sprite.setLinearVelocityY(-40);
$players[$myclient].keysdown[0]=true;
$players[$myclient].sprite.setAnimationFrame($players[$myclient].animframeindices[5].X);
$players[$myclient].curdir=0;
}
function moveplayerupstop()
{
$players[$myclient].keysdown[0]=false;
if ($players[$myclient].keysdown[1]){$players[$myclient].curdir=1;}
else if ($players[$myclient].keysdown[2]){$players[$myclient].curdir=2;}
else if ($players[$myclient].keysdown[3]){$players[$myclient].curdir=3;}
keycleanup();
}

function moveplayerdown()
{
$players[$myclient].sprite.setLinearVelocityY(40);
$players[$myclient].keysdown[1]=true;
$players[$myclient].sprite.setAnimationFrame($players[$myclient].animframeindices[4].X);
$players[$myclient].curdir=1;
}
function moveplayerdownstop()
{
$players[$myclient].keysdown[1]=false;
if ($players[$myclient].keysdown[0]){$players[$myclient].curdir=0;}
else if ($players[$myclient].keysdown[2]){$players[$myclient].curdir=2;}
else if ($players[$myclient].keysdown[3]){$players[$myclient].curdir=3;}
keycleanup();
}

function moveplayerleft()
{
$players[$myclient].sprite.setLinearVelocityX(-40);
$players[$myclient].keysdown[2]=true;
$players[$myclient].sprite.setAnimationFrame($players[$myclient].animframeindices[7].X);
$players[$myclient].curdir=2;
}
function moveplayerleftstop()
{
$players[$myclient].keysdown[2]=false;
if ($players[$myclient].keysdown[0]){$players[$myclient].curdir=0;}
else if ($players[$myclient].keysdown[1]){$players[$myclient].curdir=1;}
else if ($players[$myclient].keysdown[3]){$players[$myclient].curdir=3;}
keycleanup();
}

function moveplayerright()
{
$players[$myclient].sprite.setLinearVelocityX(40);
$players[$myclient].keysdown[3]=true;
$players[$myclient].sprite.setAnimationFrame($players[$myclient].animframeindices[6].X);
$players[$myclient].curdir=3;
}
function moveplayerrightstop()
{
$players[$myclient].keysdown[3]=false;
if ($players[$myclient].keysdown[0]){$players[$myclient].curdir=0;}
else if ($players[$myclient].keysdown[1]){$players[$myclient].curdir=1;}
else if ($players[$myclient].keysdown[2]){$players[$myclient].curdir=2;}
keycleanup();
}

function debug()
{
for (%x=0;%x<8;%x++)
{
echo("frameindices:"@$players[$myclient].animframeindices[%x]);
}
echo("sprite:"@$players[$myclient].sprite);
echo("sprite.animationName:"@$players[$myclient].sprite.animationName);
echo("sprite.animationName.animationFrames:"@$players[$myclient].sprite.animationName.animationFrames);
}

moveMap.bindCmd(keyboard,"w","moveplayerup();","moveplayerupstop();");
moveMap.bindCmd(keyboard,"s","moveplayerdown();","moveplayerdownstop();");
moveMap.bindCmd(keyboard,"a","moveplayerleft();","moveplayerleftstop();");
moveMap.bindCmd(keyboard,"d","moveplayerright();","moveplayerrightstop();");
moveMap.bindCmd(keyboard,"space","debug();","");

Code for onFrameChange callback:
playeronframechange.cs:
function a_playersprite::onFrameChange(%this,%frameIndex)
{
if ($players[$myclient].curdir==0)
{
if ($players[$myclient].keysdown[0])
{
if (%frameIndex>$players[$myclient].animframeindices[5].Y||%frameIndex<$players[$myclient].animframeindices[5].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[5].X);
}//end went past last frame check
}//end keydown check (running)
else
{
if (%frameIndex>$players[$myclient].animframeindices[1].Y||%frameIndex<$players[$myclient].animframeindices[1].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[1].X);
}//end went past last frame check
}//end keyup check (standing)
}
else if ($players[$myclient].curdir==1)
{
if ($players[$myclient].keysdown[1])
{
if (%frameIndex>$players[$myclient].animframeindices[4].Y||%frameIndex<$players[$myclient].animframeindices[4].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[4].X);
}//end went past last frame check
}//end keydown check (running)
else
{
if (%frameIndex>$players[$myclient].animframeindices[0].Y||%frameIndex<$players[$myclient].animframeindices[0].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[0].X);
}//end went past last frame check
}//end keyup check (standing)
}
else if ($players[$myclient].curdir==2)
{
if ($players[$myclient].keysdown[2])
{
//if (%frameIndex>$players[$myclient].animframeindices[7].Y)
if (%frameIndex>$players[$myclient].animframeindices[7].Y||%frameIndex<$players[$myclient].animframeindices[7].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[7].X);
}//end went past last frame check
}//end keydown check (running)
else
{
if (%frameIndex>$players[$myclient].animframeindices[3].Y||%frameIndex<$players[$myclient].animframeindices[3].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[3].X);
}//end went past last frame check
}//end keyup check (standing)
}
else if ($players[$myclient].curdir==3)
{
if ($players[$myclient].keysdown[3])
{
if (%frameIndex>$players[$myclient].animframeindices[6].Y||%frameIndex<$players[$myclient].animframeindices[6].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[6].X);
}//end went past last frame check
}//end keydown check (running)
else
{
if (%frameIndex>$players[$myclient].animframeindices[2].Y||%frameIndex<$players[$myclient].animframeindices[2].X)
{
%this.setAnimationFrame($players[$myclient].animframeindices[2].X);
}//end went past last frame check
}//end keyup check (standing)
}
}//end onframechange() callback

Code that modifies the frame animation values:
malboro.cs:
echo("loading malboro");
$players[$myclient].imagemapdatablock_playerspritehandle.imageName="~/data/playersprites/malboro/malboro.png";
$players[$myclient].imagemapdatablock_playerspritehandle.imageMode="CELL";
$players[$myclient].imagemapdatablock_playerspritehandle.frameCount="-1";
$players[$myclient].imagemapdatablock_playerspritehandle.filterMode="NONE";
$players[$myclient].imagemapdatablock_playerspritehandle.filterPad="1";
$players[$myclient].imagemapdatablock_playerspritehandle.preferPerf="1";
$players[$myclient].imagemapdatablock_playerspritehandle.cellRowOrder="1";
$players[$myclient].imagemapdatablock_playerspritehandle.cellOffsetX="0";
$players[$myclient].imagemapdatablock_playerspritehandle.cellOffsetY="0";
$players[$myclient].imagemapdatablock_playerspritehandle.cellStrideX="0";
$players[$myclient].imagemapdatablock_playerspritehandle.cellStrideY="0";
$players[$myclient].imagemapdatablock_playerspritehandle.cellCountX="-1";
$players[$myclient].imagemapdatablock_playerspritehandle.cellCountY="-1";
$players[$myclient].imagemapdatablock_playerspritehandle.cellWidth="29";
$players[$myclient].imagemapdatablock_playerspritehandle.cellHeight="32";
$players[$myclient].imagemapdatablock_playerspritehandle.preload="1";
$players[$myclient].imagemapdatablock_playerspritehandle.allowUnload="1";
$players[$myclient].imagemapdatablock_playerspritehandle.force16Bit="0";
$players[$myclient].imagemapdatablock_playerspritehandle.compile();
$players[$myclient].animationdatablock_playerspritehandle.animationFrames="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19";
$players[$myclient].animationdatablock_playerspritehandle.animationTime="2.0";
$players[$myclient].animationdatablock_playerspritehandle.animationCycle="1";
$players[$myclient].animationdatablock_playerspritehandle.randomStart="0";
$players[$myclient].animationdatablock_playerspritehandle.startFrame="0";
$players[$myclient].animationdatablock_playerspritehandle.animationPingPong="0";
$players[$myclient].animationdatablock_playerspritehandle.animationReverse="0";
$players[$myclient].sprite.size="29 32";
$players[$myclient].execpath="~/data/playersprites/malboro/malboro.cs";
$players[$myclient].animframeindices[0]="0 2";
$players[$myclient].animframeindices[1]="3 5";
$players[$myclient].animframeindices[2]="6 8";
$players[$myclient].animframeindices[3]="9 11";
$players[$myclient].animframeindices[4]="12 13";
$players[$myclient].animframeindices[5]="14 15";
$players[$myclient].animframeindices[6]="16 17";
$players[$myclient].animframeindices[7]="18 19";

#1
08/06/2012 (12:56 pm)
To see the console message you get would probably be more helpful than to see your whole project. Now it looks like you have no slightest idea of what is going on there and expect us to figure it out for you. Which in most cases means you get no help.


Now, if it say that frame index is out of range, it probably really is. It should also print out the frame you requested if I remember correct, and the number of frames that image actually has.
If I am to guess, your image map will still have 16 frames or less, because compile() doesn't necessarily load new image, and jillvalentine is too small for twenty 29x32 frames. I think the only correct way to load new image is to create another image map.
#2
08/06/2012 (5:14 pm)
Thanks for responding. The console message says: tdAnimationController::setAnimationFrame() - Animation Frame-Index Invalid (frame#16 of 15 in 1353). Before that is the debug echo displaying that the variable containing the frame data and calling setAnimationFrame() does indeed contain the proper indices.

pic of console: http://i.imgur.com/NQ6I2.jpg

This is happening when I switch character sprites. It changes the .png's correctly so i'm not sure what you meant by "compile() doesn't necessarily load new image". I'll look into deleting and remaking the variables between loads to see if that works.
#3
08/06/2012 (6:20 pm)
Edit #2: I gave up on using setanimationframe() and onframechange(). i successfully achieved animations following this tutorial: http://tdn.garagegames.com/wiki/Torque_2D/GenreTutorials/PlatformerAnimation thanks all who viewed the thread.

Edit #1: messing with t2dAnimationDatablock.animationTime and using playAnimation instead of setAnimationFrame fixes the animations and all frames run properly. Why did this fix this? I don't want modders to be forced into figuring out which frame speed works for their sprites, worse if it ends up being too fast or too slow.
I'll keep looking for an alternative solution. Also, I echo what %frameIndex is when onFrameChange() is called and I notice that it always goes past the frames i tell it not to go past (this when i don't mod animationTime). Is the animationController processing things regardless of what the callback tells it to do (like setting frames)?

Deleting and remaking the objects works 90%. I don't get the invalid-index error and 3 of the 4 animations work. I don't know why the animation for moving upwards doesn't work, I'll keep looking into it.

//deleted code because it got messed up during editing