Ooops
August 04, 2020, 12:44:02 PM

Author Topic: How to make a one time animation ?  (Read 351 times)

Offline Gijsdemik

  • Jr. Member
  • **
  • Posts: 7
How to make a one time animation ?
« on: April 23, 2020, 04:33:18 PM »
Hi guys,
i am back at programming my game, and it goes well i am currently programming the combat system.
it took me almost 3 years of learning blitzmax and working on my game from time to time. since i have a lot of free time
i am finishing my game. you all helped me before and i really appreciate that
i have encounter a new issue that i cannot seem to get right.

How can i display one time animations? and how to properly time it. it got a kinda working when you press p the animation comes in display only random frames and disappears after a few tries the game crashes.
I want to display a one time animation like when creature a hits creature b a kaboom or a POW is shown.
Or if i click my mouse to move and so on.


I am really excited that i can actually play a round of combat after al these years. and when the test program works i can adept it easily to my world editor and other object info. sidenote: i mention every one that helped me in the source code and when the game is done they will be mention in the game to

Offline Matty

  • Hero Member
  • *****
  • Posts: 1068
    • MattiesGames
Re: How to make a one time animation ?
« Reply #1 on: April 23, 2020, 05:03:54 PM »
In a variable store,for each animation the following data:

Islooped,boolean
Currentframe, float
Currentmode, integer
Startframe, integer
Endframe, integer
Framespeed, float

So let us say that you have three modes that currentmode can store...idle, walk and attack.
Idle and walk are looped, attack is not.
Player pushes 'attack' button:
If currentmode = idle or walk then
Set currentmode to attack
Set currentframe to startframe of the attack
Endif

Then every drawing frame do this:
Currentframe increment by framespeed.
If currentframe bigger than endframe then:
If looped go back to startframe otherwise set currentmode to idle and currentframe to startframe

Before drawing set variable drawframe to a floored integer value of currentframe and draw.

That's a simple mechanism.

Offline Derron

  • Hero Member
  • *****
  • Posts: 3074
Re: How to make a one time animation ?
« Reply #2 on: April 23, 2020, 08:27:31 PM »
instead of "currentFrame, startFrame, endFrame" you could also have

currentIndex, frames[] (array), frameTimes[] (array)

so frames do not necessarily need to be 0,1,2,3,4.. they could also be 0,1,0,1,2,3,0,1,0 ...
This allows more complex animations to be "mixed" (maybe even randomly) from existing sprite frames.
the "frameTimes" allow individual frame speeds. So you could have a "blink" animation like this:
frames = [0,1] '(non blink, blink)
frameTimes = [1000, 75] '1 second non blinking, 75ms blinking


Instead of setting them to "idle" when finished (and non-looped you could just mark the animation as ended. It is up to the animation manager (except the animation does it) to chain things together.

if currentAnimation.Finished() then SetAnimation(idleAnimation)
(you could even add a "if rand(0,100)" there to randomize what animation is coming next - idle1, idle2, ...)

Next to "loop" you might also add "pingpong" - so an animation "1,2,3" would do "1,2,3,2,1,2,3,2,1...". Or "pingPongInclusive" for "1,2,3,3,2,1,1,2,3,3,2,1...".


bye
Ron

Offline Matty

  • Hero Member
  • *****
  • Posts: 1068
    • MattiesGames
Re: How to make a one time animation ?
« Reply #3 on: April 23, 2020, 11:43:25 PM »
Interesting Derron.  Your method is more flexible but of more interest to me is the mindset or philosophical difference behind the two approaches-why each of us gravitates to one type of solution or another.  I feel your method is better in the general case but that mine is extremely simple to implement.  And yet while I see your method as superior I am likely to stick for myself to the method I described.

Offline iWasAdam

  • Hero Member
  • *****
  • Posts: 1790
Re: How to make a one time animation ?
« Reply #4 on: April 24, 2020, 08:41:44 AM »
you're both sortof talking about the same thing in different ways...

for any timeline. movement/playback is usually always A > B > C > D, etc. The time it takes to get to the next FRAME could be different and frames could be looped E.G. [a,b,c,<] [a,b,c,<] [a,b,c,<]
You could also add pingping and reversed playback, but that would usually be for the entire timeline, or as with matty a start and end frame
 

What happen at a frame is where the fun begins
so with Matty you are just using the timeline directly and it is a simple process both in terms of programming and for the user to understand

with Derrons the complexity allows great freedom, but at the cost of programming - lots of different things would need to be handled - frames and time almost becomes individual entities themselves and the timeline concept breaks down. access for the user becomes complex as it is not really a timeline but a series of related frames.


Getting back to the original question:one time animation like when creature a hits creature b a kaboom
You have a timeline that runs for a specified amount of time lets assume 1 second
you have 4 frames of animation (swipe)
1000 (millisecs) / 4 = 250 millisecs
frame 1 = 0 millisecs
frame 2 = 250 millisecs
frame 3 = 500 millisecs
frame 4 = 750 millisecs
frame 5 = 1000 millisecs END condition

what you define into a frame (3d movement, sprite, etc) becomes your choice

What you do at the END condition is also up to you, you could loop the animation, or reverse play, or trigger another animation (say a kaboom animation)

The actual question then becomes 'how do I program a simple animation system'?

the simplist way is to have a number of frames that are triggered at a certain time. 25 or 30 per second is the standard. You just need to fill in the data in these frames to make it 'do' stuff. It's simple to program and simple to execute :)

Offline Derron

  • Hero Member
  • *****
  • Posts: 3074
Re: How to make a one time animation ?
« Reply #5 on: April 24, 2020, 12:19:38 PM »
frames are coupled to time ... so my approach still works with a timeline (albeit it is possible to break it up - of course).

Having custom "times" for a frame index can be expressed in multiple ways. Assume we have to define each millisecond indidually, you would define
frames: 1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3...
But if you instead would write the frame + the duration of this frame you would shorten this long line to:
frames: 1,2,3, ...
times: 7,8,5, ...

Still any algorithm could find out when which frame has to be used - also in the "future". So we still have a timeline.

Complexity of the whole thing is not that much more. It allows to split "animation logic" from "design logic" (when finishing scratch-your-backidling, play the find-a-booger-idle-anim). So it should not be hardcoded in the animation code - except maybe when just prototyping or if you know you _never_ will adjust that or reuse the code (I am of course doing too much for "code reusal"). If you know you are ever only simply looping over given frames with constant frame times, then go with Matty's code and keep it simple. But as soon as you might add in some more stuff here and there you could probably endup having a "field animation:TAnimation" in your type at the end.


Regarding "what happens". You could have registered "hooks" for certain steps in the animation - so eg hook into the timeline so when "2 seconds are gone" (might be 3 seconds already - if computer lagged a bit or so) a registered callback is executed. Should of course only be used for graphical stuff (logic needs to run separate from render - to avoid issues in gpu-heavy scenes).

Offline Gijsdemik

  • Jr. Member
  • **
  • Posts: 7
Re: How to make a one time animation ?
« Reply #6 on: July 30, 2020, 03:45:52 PM »
Hi guys, Thanks for helping me out
I know i am late in my response but i had not to the time to programm.
now i have a few weeks for my self so i am at it again.

I feel a bit dumb when it comes to this, i made two diff rant Types and decided on the last one which uses an external clock input for the frame time. i cant seem to really get a counter increment using the timerticks functions which counts when a timer ticks.

I have these two types set up and i tried a bunch of diff rant programmings could some one help me on how to add the external clock frame speed into my DoFx()?
In my program i already have a working external clock trough maxgui i tried adapting that same code to my Type but it would not work. so i have a frameclock thats based on 8 frames(wich is max for my game anyhow) so i thought of adding that
because creating a new clock for every effect uses more resources than really necessary. thing is it wont retrigger or start on first animation frame but that is something to work out later

Below here are the two types i tried
this is my old one
Code: [Select]
Type AnimationEffect
 
Field FileUrl:String
Field Size:Int
Field Frames:Int
Field FirstFrame:Int
Field LastFrame:Int
Field X:Int
Field Y:Int

Method AnimationLoad()
Global AttackAnimation:TImage=LoadAnimImage(FileUrl,Size,Size,Frames,FILTEREDIMAGE+MASKEDIMAGE)
End Method

Method DoFX()
Local AnimationTimer:TTimer=CreateTimer(30,Null)
Local PlayFrame=1
If TimerTicks(AnimationTimer) PlayFrame=++1
DrawImage AttackAnimation,X,Y,PlayFrame
If PlayFrame = LastFrame ;PLayFrame=0 ; StopTimer(AnimationTimer)
End Method
End Type
'load effect
Global Kaboom:AnimationEffect= New AnimationEffect
Kaboom.FileUrl="F:\Kapow.png"
Kaboom.Size=25
Kaboom.FirstFrame=1
Kaboom.LastFrame=8
Kaboom.x=120
Kaboom.y=120
'executed at gameloop/event
Kaboom.DoFX()
And the last one i think would be better it still needs an external clock timer i could not figure out how to add that

Code: [Select]
Type AnimationEffect
Field ThisPicture:TImage
Field FileUrl:String
Field Size:Int
Field Frames:Int
Field FirstFrame:Int
Field LastFrame:Int
Field X:Int
Field Y:Int
Field PlayFrame:Int


Method AnimationLoad()
ThisPicture=LoadAnimImage(Self.FileUrl,Size,Size,Frames,FILTEREDIMAGE+MASKEDIMAGE)
End Method

Method DoFX()

For Local I:Int =FirstFrame To LastFrame
DrawImage ThisPicture,X,Y,PlayFrame
If PlayFrame=> LastFrame ;PlayFrame=0;
Next

End Method
End Type
'load effect
Global Kaboom:AnimationEffect= New AnimationEffect
Kaboom.FileUrl="F:\Kapow.png"
Kaboom.Size=25
Kaboom.FirstFrame=1
Kaboom.LastFrame=8
Kaboom.x=120
Kaboom.y=120
'executed at gameloop/event
Kaboom.DoFX()

Thanks again for the help i must be missing something here


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal