How to handle animations?
How to handle animations?
I've been browsing the anim library commands in the help documentation.
There is the BeginAnimStream command that lets you make a new anim file and add frames to it.
And the CreateAnim command which also makes a new anim file from a single brush
But how to add more frames to that anim file later?
Same if I load an animation file with LoadAnim, is there a way to edit (overwrite a frame) or to add new frames from a brush into it?
There is the BeginAnimStream command that lets you make a new anim file and add frames to it.
And the CreateAnim command which also makes a new anim file from a single brush
But how to add more frames to that anim file later?
Same if I load an animation file with LoadAnim, is there a way to edit (overwrite a frame) or to add new frames from a brush into it?
Re: How to handle animations?
ModifyAnimFrames() can add or remove frames
If you load anim tou need to create a new anim and apppend frame by frame there..
If you load anim tou need to create a new anim and apppend frame by frame there..
Christos
Re: How to handle animations?
I did read about ModifyAnimFrames() in the docs.
Although it can expand or shrink the number of frames it does not mention how to put content (eg. a brush) into the new frame you added.
To be honest I have a hard time seeing the point of adding frames to an anim if its just empty frames.
Although it can expand or shrink the number of frames it does not mention how to put content (eg. a brush) into the new frame you added.
To be honest I have a hard time seeing the point of adding frames to an anim if its just empty frames.
Re: How to handle animations?
i see your point, a function like AnimFrameFromBrush() would make sense to modify existing frames
btw jsut to point that CreateAnim() creates whole anims (all frames) from brush not just a single frame
here an example
so you can load frame by frame to a big brush, then create a BeginAnimStream() to save your "brushes" to disk in your order
definitely not convient !
btw jsut to point that CreateAnim() creates whole anims (all frames) from brush not just a single frame
here an example
Code: Select all
CreateBrush(1,200,20,#GREEN) ; Create a sprite sequence "old style"
SelectBrush(1)
For i=0 To 9
TextOut(i*20+5,5,i)
Next
EndSelect()
DisplayBrush(1,1,1) ; see it live how it looks
Wait(100)
Cls(#BLACK)
CreateAnim(1,1,20,20,10,10) ; create an anim from that "tape"
For i=1 To 10
DisplayAnimFrame(1,1,1,i) ; lets see it
Wait(50)
Next
definitely not convient !
Christos
Re: How to handle animations?
Similar to my thoughts, I was thinking since you have LoadAnimFrame() it would be nice to have SaveAnimFrame() as well.
Perhaps AnimFrameFromBrush() describes its purpose better.
Perhaps AnimFrameFromBrush() describes its purpose better.
Re: How to handle animations?
ok... my mistake too even not in anim library there is SelectAnim() which you can select ANY frame (the new blank or existing) and start drawing there
like DisplayBrush()...
so it is possible
i modify above example, creating anim, then add a new frame, and draw in new frame
like DisplayBrush()...
so it is possible
i modify above example, creating anim, then add a new frame, and draw in new frame
Code: Select all
CreateBrush(1,200,20,#GREEN) ; Create a sprite sequence "old style"
SelectBrush(1)
For i=0 To 9
TextOut(i*20+5,5,i)
Next
EndSelect()
DisplayBrush(1,1,1) ; see it live how it looks
Wait(100)
Cls(#BLACK)
CreateAnim(1,1,20,20,4,4) ; create an 4 frame anim from that "tape"
For i=1 To 4
DisplayAnimFrame(1,1,1,i) ; lets see it
Wait(50)
Next
CreateBrush(2,20,20,#RED) ; lets create a new brush
ModifyAnimFrames(1,1,3) ;add a frame in middle (frame 3 making it a 5 frame anim)
; draw the new brush
SelectAnim(1,3)
DisplayBrush(2,1,1) ; draw than new frame with the RED new brush
EndSelect()
For i=1 To 5
DisplayAnimFrame(1,1,1,i) ; lets see our new 5 frame anim
Wait(50)
Next
Christos
Re: How to handle animations?
Oh my 
I've been busy working on a workaround so I made this (messy) code to make a way to handle it.
This example can insert, replace or remove a frame in an anim file.
I will look into that SelectAnim() later. Perhaps it can be used in a similar function and do the same thing as my example with less resources.
I've been busy working on a workaround so I made this (messy) code to make a way to handle it.
This example can insert, replace or remove a frame in an anim file.
I will look into that SelectAnim() later. Perhaps it can be used in a similar function and do the same thing as my example with less resources.
Code: Select all
frametowrite = 2
task$ = "insert" ;options are "replace" (default"),"insert" or "remove".
brushtowrite = 2
;create a brush to insert or replace
CreateBrush(2, 640, 480, #RED)
;Create an example anim file with 7 frames
CreateBrush(1, 640, 480)
SelectBrush(1)
SetFillStyle(#FILLCOLOR)
BeginAnimStream(1, "anim_1.gif", 640, 480)
For Local k = 1 To 7
Box(50,200, 200, 30, #BLACK)
TextOut(50, 200, "FRAME NUMBER "..k)
WriteAnimFrame(1, 1)
Next
FinishAnimStream(1)
EndSelect
;f$ = FileRequest("Select an anim file", {Filters = "gif|avi|iff"})
f$ = "anim_1.gif"
If IsAnim(f$)
OpenAnim(1, f$)
Else
SystemRequest("Invalid anim file", "File "..f$.." is not a valid anim file", "OK")
End
EndIf
animwidth = GetAttribute(#ANIM, 1, #ATTRWIDTH)
animheight = GetAttribute(#ANIM, 1, #ATTRHEIGHT)
animframes = GetAttribute(#ANIM, 1, #ATTRNUMFRAMES)
CloseAnim(1)
Function BrushToAnimFrame(brushid, frameno, f$, msg$)
If msg$ <> "remove"
If frameno > animframes Then frameno = animframes+1
Else
If frameno > animframes Then frameno = animframes
EndIf
;Create a temporary brush to store the whole anim
If msg$ = "insert"
CreateBrush(9, animwidth*(animframes+1), animheight, #WHITE)
ElseIf msg$ = "remove"
CreateBrush(9, animwidth*(animframes-1), animheight, #WHITE)
Else
CreateBrush(9, animwidth*(Max(animframes, frameno)), animheight, #WHITE)
EndIf
SelectBrush(9)
Local addwidth = 0
For i = 1 To animframes
LoadAnimFrame(10, i, f$)
If i = frameno And msg$ = "insert" Then addwidth = 1
If i = frameno+1 And msg$ = "remove" Then addwidth = -1
DisplayBrush(10, ((i+addwidth)*animwidth)-animwidth, 0)
Next
If msg$ <> "remove" Then DisplayBrush(brushid, (animwidth*frameno)-animwidth, 0)
EndSelect()
BeginAnimStream(1, f$, 640, 480)
For i = 1 To Max(animframes+addwidth, frameno)
CopyBrush(9, 11)
If msg$ = "remove" And i = animframes
Else
CropBrush(11, (i*animwidth)-animwidth, 0, animwidth, animheight)
WriteAnimFrame(1, 11)
EndIf
Next
FinishAnimStream(1)
FreeBrush(9)
FreeBrush(10)
FreeBrush(11)
Return(frameno, Max(animframes+addwidth, frameno))
EndFunction
wrtto, frs = BrushToAnimFrame(brushtowrite, frametowrite, f$, task$); (brush id, frame, anim$)
SystemRequest("Done", "Finished updating anim file\nFrame "..wrtto.." updated.\nFrames in anim: "..frs, "OK")
OpenAnim(1, f$)
animframes = GetAttribute(#ANIM, 1, #ATTRNUMFRAMES)
;show the result
LoadAnim(1, f$)
For i = 1 To animframes
LoadAnimFrame(1, i, f$)
DisplayBrush(1, 0 , 0)
Wait(25)
Next
WaitLeftMouse()
Re: How to handle animations?
SelectAnim() did work well for most of my purposes.
Only case that need the BeginAnimStream() and WriteAnimFrame is when adding delay to the frames.
In the docs it says that only IFF and GIF formats supports frame delay. But I can not get it to work with GIF anims, only IFF.
For the example below I had this 7 frames 640x480 anim file. IFF will playback with the delay given in this script, but selecting GIT will result in no delay.
Also when saved as a GIF file in this case will give a much larger file. When I created the GIF animation earlier by using SaveAnim the gif file was 25kb, here it gets 211kb.
Did I miss something for getting this right?
Only case that need the BeginAnimStream() and WriteAnimFrame is when adding delay to the frames.
In the docs it says that only IFF and GIF formats supports frame delay. But I can not get it to work with GIF anims, only IFF.
For the example below I had this 7 frames 640x480 anim file. IFF will playback with the delay given in this script, but selecting GIT will result in no delay.
Also when saved as a GIF file in this case will give a much larger file. When I created the GIF animation earlier by using SaveAnim the gif file was 25kb, here it gets 211kb.
Did I miss something for getting this right?
Code: Select all
animfile$ = FileRequest("Select anim file", {Filters = "avi|iff|gif"})
sel = SystemRequest("Anim delay choice", "How to apply frame delay?\n Set individual frame delays\n or same delay for all frames","Individual|Common delay")
OpenAnim(1, animfile$)
Local animwidth = GetAttribute(#ANIM, 1, #ATTRWIDTH)
Local animheight = GetAttribute(#ANIM, 1, #ATTRHEIGHT)
Local animframes = GetAttribute(#ANIM, 1, #ATTRNUMFRAMES)
CreateBrush(9, animwidth*(Max(animframes, frameno)), animheight, #WHITE)
SelectBrush(9)
For i = 1 To animframes
LoadAnimFrame(10, i, animfile$)
DisplayBrush(10, (i*animwidth)-animwidth, 0)
Next
If sel = 0
framedelay = StringRequest("Frame delay","Enter the delay in ms for all frames", 200, #NUMERICAL)
framedelay = Val(framedelay)
EndIf
animformat = SystemRequest("Anim format", "Supported formats are:\n IFF Anim\n GIF Anim\n (AVI does not support delay)","IFF|GIF")
animfile$ = FileRequest("Enter anim file name", { Mode = #REQ_SAVEMODE, Filters = "iff|gif"})
Switch animformat
Case 1:
animformat = #ANMFMT_IFF
Case 0:
animformat = #ANMFMT_GIF
EndSwitch
BeginAnimStream(1, animfile$, animwidth, animheight, format = animformat)
For i = 1 To Max(animframes+addwidth, frameno)
CopyBrush(9, 11)
CropBrush(11, (i*animwidth)-animwidth, 0, animwidth, animheight)
If sel = 1
framedelay = StringRequest("Frame delay","Enter the delay in ms for this frame", 200, #NUMERICAL)
framedelay = Val(framedelay)
EndIf
WriteAnimFrame(1, 11, {Delay = framedelay})
Next
FinishAnimStream(1)
EndSelect()
FreeBrush(9)
FreeBrush(10)
FreeBrush(11)
LoadAnim(1, animfile$)
PlayAnim(1, 0, 0, {speed = #DEFAULTSPEED})
CloseAnim(1)
Re: How to handle animations?
intresting topic and experience new things
first you have wrong
its
not "format = xxxx" equation is needed only inside tables, not pure parameters
this lead to always create GIF anims
second manual is wrong in BeginAnimFormat() gif and iff DO support fps, and if you have not set FPS dealy isnt working either
setting fps delay is working (maybe its a bug and should work eithercase, but this seems to work for now)
first you have wrong
Code: Select all
BeginAnimStream(1, animfile$, animwidth, animheight, format = animformat)Code: Select all
BeginAnimStream(1, animfile$, animwidth, animheight, animformat)this lead to always create GIF anims
second manual is wrong in BeginAnimFormat() gif and iff DO support fps, and if you have not set FPS dealy isnt working either
setting fps delay is working (maybe its a bug and should work eithercase, but this seems to work for now)
Code: Select all
BeginAnimStream(1, animfile$, animwidth, animheight, animformat, {FPS=1})Christos
Re: How to handle animations?
Thanks for clearifying.
Getting the anim format argument correct solved it for both IFF and GIF.
For IFF and GIF the FPS argument is not needed in BeginAnimStream(), and the Delay argument will work as it should regardless if FPS is set or not.
So I would say the manual is correct.
On the other hand AVI (MJPEG) does use the FPS argument to set the playback rate.
But PlayAnim(1, 0, 0, {speed = #DEFAULTSPEED}) seem to ignore the FPS setting, it plays the video at full rate anyway.
If I play the AVI video in an external player like VLC the FPS setting is working.
The FPS setting does have huge impact on the AVI file size. The lower FPS, the bigger the file size gets.
That is strange since as a general rule the lower frame rate should result in smaller files (according to google).
From example below, 7 frame 640x480 anim file sizes:
GIF = 8 kb
IFF = 10 kb
AVI (25 FPS) = 156 kb
AVI (2 FPS) = 711 kb
AVI (1 FPS) = 1314 kb
This example which also generates a sample anim file for testing the various formats
Getting the anim format argument correct solved it for both IFF and GIF.
For IFF and GIF the FPS argument is not needed in BeginAnimStream(), and the Delay argument will work as it should regardless if FPS is set or not.
So I would say the manual is correct.
On the other hand AVI (MJPEG) does use the FPS argument to set the playback rate.
But PlayAnim(1, 0, 0, {speed = #DEFAULTSPEED}) seem to ignore the FPS setting, it plays the video at full rate anyway.
If I play the AVI video in an external player like VLC the FPS setting is working.
The FPS setting does have huge impact on the AVI file size. The lower FPS, the bigger the file size gets.
That is strange since as a general rule the lower frame rate should result in smaller files (according to google).
From example below, 7 frame 640x480 anim file sizes:
GIF = 8 kb
IFF = 10 kb
AVI (25 FPS) = 156 kb
AVI (2 FPS) = 711 kb
AVI (1 FPS) = 1314 kb
This example which also generates a sample anim file for testing the various formats
Code: Select all
CreateBrush(1, 640, 480)
SelectBrush(1)
SetFillStyle(#FILLCOLOR)
BeginAnimStream(1, "anim.gif", 640, 480)
For Local k = 1 To 7
Box(50,200, 200, 30, #BLACK)
TextOut(50, 200, "FRAME NUMBER "..k)
WriteAnimFrame(1, 1)
Next
FinishAnimStream(1)
EndSelect
animfile$ = "anim.gif"
;animfile$ = FileRequest("Select anim file", {Filters = "avi|iff|gif"})
OpenAnim(1, animfile$)
Local animwidth = GetAttribute(#ANIM, 1, #ATTRWIDTH)
Local animheight = GetAttribute(#ANIM, 1, #ATTRHEIGHT)
Local animframes = GetAttribute(#ANIM, 1, #ATTRNUMFRAMES)
CreateBrush(9, animwidth*(Max(animframes, frameno)), animheight, #WHITE)
SelectBrush(9)
For i = 1 To animframes
LoadAnimFrame(10, i, animfile$)
DisplayBrush(10, (i*animwidth)-animwidth, 0)
Next
animformat = SystemRequest("Anim format", "Supported formats are:\n IFF Anim\n GIF Anim\n (AVI doesn't handle individual\nframe delay.\nYou set the FPS rate.)","AVI|IFF|GIF")
animfile$ = FileRequest("Output anim file name", { Mode = #REQ_SAVEMODE, Filters = "avi|iff|gif"})
Switch animformat
Case 1:
animformat = #ANMFMT_MJPEG
animfps = StringRequest("Set FPS","Enter playback speed in FPS\nDefault speed is 25", 25, #NUMERICAL)
BeginAnimStream(1, animfile$, animwidth, animheight, animformat, {FPS=animfps})
Case 2:
animformat = #ANMFMT_IFF
sel = SystemRequest("Anim delay choice", "How to apply frame delay?\n Set individual frame delays\n or same delay for all frames","Individual|Common delay")
If sel = 0
framedelay = StringRequest("Frame delay","Enter the delay in ms for all frames", 200, #NUMERICAL)
framedelay = Val(framedelay)
EndIf
BeginAnimStream(1, animfile$, animwidth, animheight, animformat)
Case 0:
animformat = #ANMFMT_GIF
sel = SystemRequest("Anim delay choice", "How to apply frame delay?\n Set individual frame delays\n or same delay for all frames","Individual|Common delay")
If sel = 0
framedelay = StringRequest("Frame delay","Enter the delay in ms for all frames", 200, #NUMERICAL)
framedelay = Val(framedelay)
EndIf
BeginAnimStream(1, animfile$, animwidth, animheight, animformat)
EndSwitch
For i = 1 To Max(animframes+addwidth, frameno)
CopyBrush(9, 11)
CropBrush(11, (i*animwidth)-animwidth, 0, animwidth, animheight)
If sel = 1
framedelay = StringRequest("Frame delay","Enter the delay in ms for frame "..i, 200, #NUMERICAL)
framedelay = Val(framedelay)
EndIf
WriteAnimFrame(1, 11, {Delay = framedelay})
Next
FinishAnimStream(1)
EndSelect()
FreeBrush(9)
FreeBrush(10)
FreeBrush(11)
LoadAnim(1, animfile$)
PlayAnim(1, 0, 0, {speed = #DEFAULTSPEED})
CloseAnim(1)