Use MEL Scripting to Create Fun Sprite Animations

Brent Forrest shares a fun experiment. Brent created a small MEL script in Maya that stores spite animations as integers in a matrix. This is much like how games ran in the mid 80’s.

Using this script you can create sprite animations and store them as integers in a matrix. Brent’s script will playback the sprite animation as shown with his simple little NES example. Brent makes the script available if anyone wants to play around with it.

//I’ll just leave this here
//run “animate” for the magic
global int $cSprite[64];
global int $tSprite[144];
//5 animation frames, 64 pixels stored
global matrix $coinAn [5] [64];
//6 animation frames, 144 pixels stored
global matrix $turtleAn [6] [144];
global int $cT, $tT;
global string $shaders[];
global string $cPlane[], $tPlane[];

//assign names to new palette

$shaders = {
“red”,”orange”, “yellow”, “green”, “blue”, “purple”, “brown”, “black”, “white”, “grey”, “trans”, “hilite”
};
//assign rgba values to the new palette

float $r[] = {float(1),(1.0),(1.0),(0.0),(0.0),(0.5),(0.2),(0.0 ),(1.0),(0.5),(0.5),(1.0)};
float $g[] = {float(0),(0.5),(1.0),(1.0),(0.0),(0.0),(0.3),(0.0 ),(1.0),(0.5),(0.5),(1.0)};
float $b[] = {float(0),(0.0),(0.0),(0.0),(1.0),(1.0),(0.1),(0.0 ),(1.0),(0.5),(0.5),(1.0)};
float $a[] = {float(0),(0.0),(0.0),(0.0),(0.0),(0.0),(0.0),(0.0 ),(0.0),(0.0),(1.0),(0.0)};

//create the shaders

$i = 0;
for ($one in $shaders)
{
shadingNode -n $one -asShader lambert;
sets -renderable true -noSurfaceShader true -empty -name ($one + “SG”);
connectAttr -f ($one + “.outColor”) ($one + “SG.surfaceShader”);
setAttr ($one+”.colorR”) ($r[$i]) ;
setAttr ($one+”.colorG”) ($g[$i]) ;
setAttr ($one+”.colorB”) ($b[$i]) ;
addAttr -keyable true -ln “index” -at long -dv ($i) $one;
for ($rgb in {“R”,”G”,”B”}){
setAttr ($one+”.transparency”+$rgb) ($a[$i]) ;
}
$i++ ;
}
//create an 8 x 8 sprite as a polyPlane

$cPlane = `polyPlane -ch on -o on -w 8 -h 8 -sw 8 -sh 8 -cuv 2 -n “coinPlane”`;
move 0 4 0;
rotate -x -90;
$tPlane = `polyPlane -ch on -o on -w 12 -h 12 -sw 12 -sh 12 -cuv 2 -n “turtlePlane”`;
move 10 4 0;
rotate -x -90;

//the default animation cycles

$coinAn = << 10, 10, 11, 2, 2, 1, 10, 10, 10, 11, 2, 1, 2, 2, 1, 10, 10, 2, 2, 2, 1, 2, 1, 10, 10, 2, 2, 2, 1, 2, 1, 10, 10, 2, 2, 2, 1, 2, 1, 10, 10, 2, 2, 2, 1, 2, 1, 10, 10, 2, 2, 1, 2, 2, 1, 10, 10, 10, 2, 2, 2, 1, 10, 10;
10, 10, 10, 2, 1, 10, 10, 10, 10, 10, 2, 2, 2, 1, 10, 10, 10, 10, 2, 1, 2, 1, 10, 10, 10, 10, 2, 1, 2, 1, 10, 10, 10, 10, 2, 1, 2, 1, 10, 10, 10, 10, 2, 1, 2, 1, 10, 10, 10, 10, 2, 2, 2, 1, 10, 10, 10, 10, 10, 2, 1, 10, 10, 10;
10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10;
10, 10, 10, 11, 2, 10, 10, 10, 10, 10, 11, 2, 2, 2, 10, 10, 10, 10, 11, 2, 11, 2, 10, 10, 10, 10, 11, 2, 11, 2, 10, 10, 10, 10, 11, 2, 11, 2, 10, 10, 10, 10, 11, 2, 11, 2, 10, 10, 10, 10, 11, 2, 2, 2, 10, 10, 10, 10, 10, 11, 2, 10, 10, 10;
10, 10, 8, 2, 2, 2, 10, 10, 10, 8, 2, 2, 8, 2, 2, 10, 10, 8, 2, 1, 2, 8, 2, 10, 10, 8, 2, 1, 2, 8, 2, 10, 10, 8, 2, 1, 2, 8, 2, 10, 10, 8, 2, 1, 2, 8, 2, 10, 10, 8, 2, 2, 1, 2, 2, 10, 10, 10, 8, 2, 2, 2, 10, 10>>;

$turtleAn = << 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 3, 3, 10, 10, 1, 8, 8, 1, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 7, 1, 10, 10, 3, 11, 11, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 11, 6, 6, 6, 3, 1, 1, 1, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 8, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 0, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 7, 7, 6, 6, 6, 7, 7, 7, 7, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10;
10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 10, 3, 3, 10, 10, 1, 8, 8, 1, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 7, 1, 10, 10, 3, 11, 11, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 11, 6, 6, 6, 3, 1, 1, 1, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 8, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 0, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 7, 7, 6, 6, 6, 7, 7, 7, 7, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10;
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 8, 8, 10, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 11, 1, 10, 10, 3, 11, 11, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 11, 6, 6, 6, 3, 1, 11, 7, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 8, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 0, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 7, 7, 6, 6, 7, 7, 7, 7, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10;
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 8, 8, 10, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 11, 1, 10, 10, 3, 11, 11, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 11, 6, 6, 6, 3, 1, 11, 7, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 0, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 7, 7, 6, 6, 7, 7, 7, 7, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10;
10, 10, 10, 3, 3, 10, 10, 10, 11, 11, 10, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 8, 1, 10, 10, 3, 11, 11, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 11, 6, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 0, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 7, 6, 6, 7, 7, 7, 7, 6, 3, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10;
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 10, 10, 10, 10, 10, 3, 3, 10, 10, 1, 8, 8, 1, 10, 10, 10, 3, 11, 6, 3, 10, 1, 8, 7, 1, 1, 10, 3, 11, 8, 6, 6, 3, 1, 8, 7, 1, 1, 10, 3, 8, 6, 6, 6, 6, 3, 1, 1, 1, 1, 10, 3, 6, 6, 6, 6, 6, 3, 1, 0, 1, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 1, 3, 6, 6, 6, 6, 6, 6, 3, 1, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 1, 10, 10, 3, 6, 6, 6, 6, 6, 6, 6, 3, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 6, 3, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 10>>;

//save the animation frame

proc saveFrame(){
int $getIndex;
global string $cPlane[], $tPlane[];
global matrix $turtleAn [6] [144];
global matrix $coinAn [5] [64];
for ($i=0;$i<144;$i++){
select -r ($tPlane[0]+”.f[“+$i+”]”);
hyperShade -smn;
$obj = `ls – sl`;
$getIndex = `getAttr ($obj[0]+”.index”)`;
$turtleAn [3] [$i] = $getIndex;
}
}

global proc animGo(){
global string $shaders[];
global string $sPlane[];
global string $tPlane[], $cPlane[];
global int $cSprite[], $tSprite[];
global matrix $coinAn [5] [64];
global matrix $turtleAn [6] [144];
global int $cT, $tT, $i;
if (timerquery() > 0.05) {
if ($cT > 4) $cT = 0;
if ($tT > 5) $tT=0;
for ($i=0;$i<64;$i++){
$cSprite[$i] = $coinAn [$cT] [$i];
}
for ($it=0;$it<144;$it++){
$tSprite[$it] = $turtleAn [$tT] [$it];
}
for ($i=0;$i<(size($cSprite));$i++){
sets -e -forceElement ($shaders[($cSprite[$i])]+”SG”) ($cPlane[0]+”.f[“+$i+”]”);
}
for ($it=0;$it<(size($tSprite));$it++){
sets -e -forceElement ($shaders[($tSprite[$it])]+”SG”) ($tPlane[0]+”.f[“+$it+”]”);
}
$cT++;
$tT++;
timerstart;
}
}

global proc timerstart()
{
global float $GstartTime;
$GstartTime = `timerX`;
}
global proc float timerquery()
{
global float $GstartTime;
return (`timerX -startTime $GstartTime`);
}

global proc animate()
{
global int $anIndex;
if ($anIndex == 0)
$anIndex = -1;
if (!`scriptJob -ex $anIndex`)
{
$anIndex = `scriptJob -kws -e idle animGo`;
}else{
scriptJob -k $anIndex -f;
}
}

// animate;