exiting animation loop

Blitz3D Forums/Blitz3D Programming/exiting animation loop

Ruz(Posted 2004) [#1]
for example if you have an idle animation looping.
when the conditions are met to end the loop( probably you pressed another key), the animation cycles until the end of the idle sequence
how can you exit the loop instantly.
the upshot of this is that if you are standing and idleing, when you walk off, the idle animation is still playing.
look really crap


fredborg(Posted 2004) [#2]
You could probably use AnimTime to find out when the animation is done.


jhocking(Posted 2004) [#3]
I've never noticed the behavior you describe. Whenever I use the Animate command whatever animation is currently playing is cut-off immediately. Could you perhaps post code showing how you are playing the animation?


Rambus(Posted 2004) [#4]
you could probably just increase the tween value and it will make a smooth transition regardless.


jhocking(Posted 2004) [#5]
Huh? For a minute I was actually thinking that was his problem, that he had the optional tween value set really high and should therefore decrease or simply eliminate that value. I'm not sure how INCREASING the tween value would solve his problem.


Ruz(Posted 2004) [#6]
increasing the tween value will make it worse.

I have it so the idle plays when you are not pressing any keys. I included walk code so you can see what i am doing


;walking forward

If KeyDown(200) And walkflag=False
MoveEntity p\entity,0,0,.2
If Animating(p\model)=p\walk
Animate p\model,3,.7,1 walkflag=True

EndIf
EndIf

If Not KeyDown(200) Then walkflag= False

;Idle

If Not Animating (p\model)

If Animating(p\model)=p\idle
Animate p\model,3,.2,2 ;this is the idle animation

EndIf
EndIf


I tried idle with flags and still is does the same thing.
idle loops, then plays the extra cycle when i break out of the loop by walking/jumping or whatever
it only happens with idle .


Ruz(Posted 2004) [#7]
Fredborg have you any examples of how to use this


fredborg(Posted 2004) [#8]
Something like this should show you how it would work.
Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,20,-100 ; position camera so that robot will be in view when loaded

AmbientLight 132,132,132
light=CreateLight()
LightRange light,20
RotateEntity light,90,0,0

; Load anim mesh
robot = LoadAnimMesh("media\makbot\mak_running.3ds")
anim0 = 0
anim1 = LoadAnimSeq(robot,"media\makbot\mak_robotic.3ds")

Animate robot,1,1,anim1,10.0

While Not KeyDown(1)
	TurnEntity robot,0,1,0
	UpdateWorld 
	RenderWorld 

	If KeyHit(57) ; If space is hit
		IWantToRun = True
	End If

	; Show which frame of total we are showing
	Text 0,0,AnimTime(robot)+" of "+AnimLength(robot)
	
	; If this is the last frame
	If AnimTime(robot) => AnimLength(robot)-1
		Text 0,10,"Animation Re-Started"
		
		; Switch to running
		If IWantToRun = True
			Animate robot,1,1,anim0,10.0
			IWantToRun = False
		End If
	End If

	; If we should switch to running
	If IWantToRun = True
		Text 0,20,"I Want To Run, but I can't until this animation sequence is done!"
	End If
	
	Flip
Wend



Ruz(Posted 2004) [#9]
cheers fredborg, i will look through it when i have had some sleep.
I have got to the stage where everyhting is working apart from this one damn glitch.
bit frustrated now


Tom(Posted 2004) [#10]
Have you tried SetAnimTime(), try setting it to say 5 frames before the end of the previous animation.


Ruz(Posted 2004) [#11]
I had thought about using set animtime(), but again I wasn't sure how to use it since there are no relevant examples included with The blitz docs, just brief descriptions.
when you say set it to five frames etc ,how is that done
why is n't just 'frames' rather than 'time'


FYI, my idle sequence is from frame 31-45
suppose I have to use animtime() to find this out?


Tom(Posted 2004) [#12]
Sorry yes, it's Time not Frames.

Try setting the anim time to 45, the end of your idle sequence, then immediately start the next anim. There will probably be a slight jump in the character though.

We could do with some nice functions for more control over Blitzs animation. For example, the current Tween is just that, not a true Blend which would look much better.

Tom


Ruz(Posted 2004) [#13]
still no luck .whatever I do the frames just play out.
tried this:

If KeyDown(30) ; forward
SetAnimTime p\model ,45,2;(2 is the idle sequence)
If Animating(p\model)=p\walk
Animate p\model,3,.7,1
EndIf
MoveEntity p\entity,0,0,.3
EndIf

I wonder of its because i have the controls set like this:
If Animating(p\model)=p\walk
Animate p\model,3,.7,1
EndIf

normally to loop this sequence you would just have

Animate p\model,1,.7,1

Unfortunately

If keydown(30)
Animate p\model,1,.7,1
Move entity p\entity,0,0,1
EndIf

just makes the animation stick on the first frame
key hit would be better, but then I wouldn't move forward unless I kept hitting the key

In any case nothing seems to work.


Ruz(Posted 2004) [#14]
good god I have done it.
i will post the solution later tonight, not that its that interesting he he

Its actually worked due to a little quirk in the way animation works

ended up using setanimtime()

cheers tom and fredborg , I learned quite bit today


jhocking(Posted 2004) [#15]
I'm not sure what you did using SetAnimTime or why you are checking animation frames, but this is how I do it (assuming "idle" is sequence 2 and "walk" is 1):


If KeyDown(30)

If AnimSeq(p\model)<>1
Animate p\model,1,.5,1,.5
EndIf
MoveEntity p\model,0,0,.3

Else

If AnimSeq(p\model)<>2
Animate p\model,1,.5,2,.5
EndIf

EndIf


Basically I have nested If statements to check first if the key for walking is being held down. If so it then checks if the character is already in the walk animation; if not then start playing the walk animation. A similar check happens for the idle animation if the key is not being held down.

Oh, and MoveEntity happens inside of the check for the key pressed down but outside the check if the walk animation is already playing.


Ruz(Posted 2004) [#16]
cheers for that. i wll look in to it today. I have a tendency to make things more complicated than need be sometimes.
I got my code working, but its created more problems now.


jhocking(Posted 2004) [#17]
Heh, my laziness pays off a lot when I'm programming. I always seem to figure out ways to do things without writing lots of code.


Ruz(Posted 2004) [#18]
yeah i jsut never thought of dong that:

If AnimSeq(p\model)<>2

can't see the wood for trees sometimes


jhocking(Posted 2004) [#19]
So, did my code work? You never mentioned and I just typed that from memory (ie. I haven't actually run it.)


Ruz(Posted 2004) [#20]
just tested it and yup it worked.
Thanks for that, saved me a lot of hassle


Ruz(Posted 2004) [#21]
although there are still problems when for example if no keys are down you have have the idle as the default sequence
just reinserting

If AnimSeq(p\model)<>2 ;(depending on animation)
Animate p\model,1,.5,2,.5
EndIf

EndIf

after every sequence dosn't work.


dangerdave(Posted 2004) [#22]
Ruz,

I raped and pillaged the castle demo. Well, pillage anyway.
Check near the middle.
Does this help?


Function UpdatePlayer( p.Player )
	If KeyHit(56)	;fire?
		CreateBullet( p )
	EndIf
	
	If KeyDown(203)	;left/right
		TurnEntity p\entity,0,6,0	;turn player left/right
	Else If KeyDown(205)
		TurnEntity p\entity,0,-6,0
	EndIf
	
	If KeyDown(30)		;forward
		If p\anim_speed<=0
			p\anim_speed=1.75
			Animate p\model,1,p\anim_speed
		EndIf
		MoveEntity p\entity,0,0,1
	Else If KeyDown(44)	;back
		If p\anim_speed>=0
			p\anim_speed=-1.75
			Animate p\model,1,p\anim_speed
		EndIf
		MoveEntity p\entity,0,0,-1
	Else If p\anim_speed	;stop animating
		p\anim_speed=0
		Animate p\model,0
	EndIf

	Goto skip	
	ex#=EntityX(p\entity):ez#=EntityZ(p\entity)
	PositionEntity p\entity,ex,TerrainY( land,ex,0,ez )+1.5,ez
	Return
	.skip
	
	ty#=EntityY(p\entity)
	y_vel#=(ty-p\player_y)
	p\player_y=ty
	
	If KeyHit(57)	;jump?
		y_vel=5	;2.4
	Else
		y_vel=y_vel-.5	;2
	EndIf
	TranslateEntity p\entity,0,y_vel,0
	
End Function



Ruz(Posted 2004) [#23]
unfortunately no dave because the castle demo does n't have an idle sequence,just 'stop animating' i believe

I have almost got it cracked now(using mr hockings method).
The only problem is that when i move forward and turn, the 'static turn' sequence plays which looks stupid. he should walk in this situation.

same with move forward and jump.

I tried something like
if keydown (200) and keydown(203) then turnflag= false

but it just doesn't work


Ruz(Posted 2004) [#24]
update . everything works now apart from i can't work out how to disable running animation whilst jumping forward and running
I want to have a simple jump animation for running jump as distinct from the animation for standing jump.
here is the code so far
suggestions greatly appreciated

;walking backward ################################
If AnimSeq(p\model)<>1
Animate p\model,1,.7,1
EndIf
MoveEntity p\entity,0,0,.1;p\entity is the parent of p\model
EndIf
;EndIf

;walking backward ################################
If KeyDown(208)

If AnimSeq(p\model)<>1
Animate p\model,1,-.7,1,.5
EndIf
MoveEntity p\entity,0,0,-.1

EndIf

;idle #####################################################################

If Not KeyDown(200)
If Not KeyDown(203)
If Not KeyDown(205)

If Not KeyDown(208)
If Not KeyHit(184)
idleflag=True

EndIf
EndIf
EndIf
EndIf
EndIf

If idleflag=True
If AnimSeq(p\model)<>2
Animate p\model,1,.2,2,7

EndIf
EndIf

;idle ############################################################

;turning####################################################

If KeyDown(203)

If AnimSeq(p\model)<>4

Animate p\model,1,.05,4,5

EndIf


TurnEntity p\entity,0,2,0

EndIf

If KeyDown(205)

If AnimSeq(p\model)<>5

Animate p\model,1,.05,5,5
EndIf

TurnEntity p\entity,0,-2,0

EndIf


;jumping ############################################################

ty#=EntityY(p\entity);from castle demo
y_vel#=(ty-p\player_y)
p\player_y=ty

If KeyDown(184) And EntityCollided(p\entity,TYPE_SCENERY>1

Animate p\model,3,.5,6

y_vel=1

Else
y_vel=y_vel-.05 ;from castle demo
EndIf


jhocking(Posted 2004) [#25]
You're using lots of separate and/or nested If statements for checking key presses. I'd actually use one overarching If statement with lots of ElseIf for checking key presses. Pseudocode:

If KeyDown(1)
(handle walking)
ElseIf KeyDown(2)
(handle running)
ElseIf KeyDown(3)
(handle turning)
Else
(idle)
EndIf


Ruz(Posted 2004) [#26]
yeah i was trying to seperate them so it would be clearer to me.ok I will give it a try that way


Ruz(Posted 2004) [#27]
well even thiough my code looks a bit 'newbyish' , it works now , so i am sticking with it.
I have seperate animations for, walk,turn left, turn right, stilljump ,dying.

When jumping and running at the same time the run animation plays which looks ok.
when walking and turning the walk animation plays which again looks fine.

I would like to add random idle sequences next but am not quite sure how to handle that.

anyway thnks for the advice guys.


RemiD(Posted 2017) [#28]
What jhocking suggests will not work if you add a keyhit() which triggers a one time animation (like an attack or shoot or throw or isdamaged animation), because the idle animation will automatically replace the one time animation if no key is held/hit during a loop. To prevent this you need to have another variable (like "AnimationState" (true or false)) which you set to true when a one time animation is triggered, and when you set to false when the one time animation is finished (to know this, check what is the current frame/pose using animtime()), and only allow a new movement/animation when the animationstate is false...