I think you've inspired me to do something ridiculous and over the top, but ah well.
I've written a small library of functions to help put tilesheet animations on planes. I'll paste the code below, but I've also attached the source file itself. I recommend including the file into whatever project you intend to use it in as opposed to copying and pasting it below your main source file code.
remstart
Library for Using Tilesheet Animations on 3D Planes v1.0
thrown together at 2:00AM by Kira Vakaan :P
Functions:
InitAnimations()
-This function must be called before any other parts of the library can be used.
MakeAnimation(AnimNumber,ImageNumber,FramesAcross,FramesDown,CyclesPerFrame,ObjectNumber)
-Sets up an animation
Parameters:
-AnimNumber: The number of the animation to setup
-ImageNumber: The number of the image containing the animation
-FramesAcross: The number of frames across the image horizontally
-FramesDown: The number of frames down the image vertically
-CyclesPerFrame: The number of ticks to wait before switching frames. Typically updated once every main loop cycle
by calling UpdateAnimations().
-ObjectNumber: The number of the plane to put the animation on
UpdateAnimations()
-Increments each animation's internal timers and will forward animation frames where necessary. It is recommended to
place this command at the end of the main loop.
DeleteAnimation(AnimNumber)
-Deletes the specified animation. Animation numbers that are deleted may safely be reused.
SetAnimationCPF(AnimNumber,CyclesPerFrame)
-Sets the animation's Cycles Per Frame. Logically, the larger the number, the slower the animation will play.
If the others weren't self-explanatory enough, I'm sure the following are:
SetAnimationFrame(AnimNumber,Frame)
IncAnimationFrame(AnimNumber)
PlayAnimation(AnimNumber)
StopAnimation(AnimNumber)
PauseAnimation(AnimNumber)
ResumeAnimation(AnimNumber)
remend
end
function InitAnimations()
global AnimationCount : AnimationCount=0
#constant CURRENT_FRAME 1
#constant FRAME_COUNT 2
#constant FRAMES_ACROSS 3
#constant FRAMES_DOWN 4
#constant CPF 5 `Cycles Per Frame
#constant CURRENT_TIME 6
#constant IMAGE_NUMBER 7
#constant OBJECT_NUMBER 8
#constant ANIM_PLAYING 9
#constant ANIM_SETUP 10
#constant FIELDS 10
#constant ALREADY_EXISTS 1
#constant DOES_NOT_EXIST 2
#constant FRAME_OOB 3 `Frame Out Of Bounds
#constant INVALID_CPF 4
dim Animations(AnimationCount,FIELDS)
endfunction
function MakeAnimation(AnimNumber,ImageNumber,FramesAcross,FramesDown,CyclesPerFrame,ObjectNumber)
if AnimNumber>AnimationCount
AnimationCount=AnimNumber
dim Animations(AnimationCount,FIELDS)
endif
if Animations(AnimNumber,ANIM_SETUP) then ThrowError(ALREADY_EXISTS)
Animations(AnimNumber,CURRENT_FRAME)=0
Animations(AnimNumber,FRAME_COUNT)=FramesAcross*FramesDown
Animations(AnimNumber,FRAMES_ACROSS)=FramesAcross
Animations(AnimNumber,FRAMES_DOWN)=FramesDown
Animations(AnimNumber,CPF)=CyclesPerFrame
Animations(AnimNumber,CURRENT_TIME)=0
Animations(AnimNumber,IMAGE_NUMBER)=ImageNumber
Animations(AnimNumber,OBJECT_NUMBER)=ObjectNumber
Animations(AnimNumber,ANIM_PLAYING)=1
Animations(AnimNumber,ANIM_SETUP)=1
texture object ObjectNumber,ImageNumber
scale object texture ObjectNumber,1.0/FramesAcross,1.0/FramesDown
endfunction
function SetAnimationFrame(AnimNumber,Frame)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if Frame>=Animations(AnimNumber,FRAME_COUNT) then ThrowError(FRAME_OOB)
CXPos=Animations(AnimNumber,CURRENT_FRAME)%%Animations(AnimNumber,FRAMES_ACROSS)
CYPos=Animations(AnimNumber,CURRENT_FRAME)/Animations(AnimNumber,FRAMES_ACROSS)
NXPos=Frame%%Animations(AnimNumber,FRAMES_ACROSS)
NYPos=Frame/Animations(AnimNumber,FRAMES_ACROSS)
UVdX#=(NXPos-CXPos)*(1.0/Animations(AnimNumber,FRAMES_ACROSS))
UVdY#=(NYPos-CYPos)*(1.0/Animations(AnimNumber,FRAMES_DOWN))
scroll object texture Animations(AnimNumber,OBJECT_NUMBER),UVdX#,UVdY#
Animations(AnimNumber,CURRENT_FRAME)=Frame
endfunction
function IncAnimationFrame(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
Frame=Animations(AnimNumber,CURRENT_FRAME)+1
if Frame>=Animations(AnimNumber,FRAME_COUNT) then Frame=0
SetAnimationFrame(AnimNumber,Frame)
endfunction
function UpdateAnimations()
for a=0 to AnimationCount
if Animations(a,ANIM_SETUP) and Animations(a,ANIM_PLAYING)
inc Animations(a,CURRENT_TIME)
if Animations(a,CURRENT_TIME)>=Animations(a,CPF)
Animations(a,CURRENT_TIME)=0
IncAnimationFrame(a)
endif
endif
next a
endfunction
function PlayAnimation(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_PLAYING)
Animations(AnimNumber,ANIM_PLAYING)=1
SetAnimationFrame(AnimNumber,0)
Animations(AnimNumber,CURRENT_TIME)=0
endif
endfunction
function PauseAnimation(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if Animations(AnimNumber,ANIM_PLAYING) then Animations(AnimNumber,ANIM_PLAYING)=0
endfunction
function ResumeAnimation(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_PLAYING) then Animations(AnimNumber,ANIM_PLAYING)=1
endfunction
function StopAnimation(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if Animations(AnimNumber,ANIM_PLAYING)
Animations(AnimNumber,ANIM_PLAYING)=0
SetAnimationFrame(AnimNumber,0)
Animations(AnimNumber,CURRENT_TIME)=0
endif
endfunction
function SetAnimationCPF(AnimNumber,CyclesPerFrame)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
if CyclesPerFrame<=0 then ThrowError(INVALID_CPF)
Animations(AnimNumber,CPF)=CyclesPerFrame
if Animations(AnimNumber,CURRENT_TIME)>=CyclesPerFrame
Animations(AnimNumber,CURRENT_TIME)=0
IncAnimationFrame(AnimNumber)
endif
endfunction
function DeleteAnimation(AnimNumber)
if AnimNumber>AnimationCount then ThrowError(DOES_NOT_EXIST)
if not Animations(AnimNumber,ANIM_SETUP) then ThrowError(DOES_NOT_EXIST)
Animations(AnimNumber,ANIM_SETUP)=0
scale object texture Animations(AnimNumber,OBJECT_NUMBER),Animations(AnimNumber,FRAMES_ACROSS),Animations(AnimNumber,FRAMES_DOWN)
endfunction
function ThrowError(ErrorNumber)
Message$=""
select ErrorNumber
case ALREADY_EXISTS:
Message$="Error: Animation already exists"
endcase
case DOES_NOT_EXIST:
Message$="Error: Animation does not exist"
endcase
case FRAME_OOB:
Message$="Error: Specified frame number out of bounds"
endcase
case INVALID_CPF:
Message$="Error: Invalid cycles per frame"
endcase
endselect
exit prompt Message$,"Error"
end
endfunction
And so, with this library, you can now do something like this:
set display mode 1024,768,32,1
sync on
InitAnimations()
make object plane 1,10,10
load image "TileSheet.jpg",1
MakeAnimation(1,1,4,4,10,1)
do
UpdateAnimations()
sync
loop
There's a description of all of the commands in the library in the comments at the top of the source file.
I hope this is useful to someone.