Frames and timers

BlitzPlus Forums/BlitzPlus Beginners Area/Frames and timers

En929(Posted 2011) [#1]
1) I was still having trouble with frame animation (I’m learning slowly but surely). Thus for now, instead of having each frame done using the frame command, I drew out each frame manually and leave the unused frames off screen (500000 pixels away) until they are called up to be used (that is, they’ll come into play after key 25 is pressed). It seems to work well for now. Does anybody do it that way?

2) My main question is how do I get my different drawings to occur at precise times. For example, let’s say when key (25) is pressed the guy immediately shouts, 3 seconds later the guy punches, 5 seconds later the guy goes to a stance, and 5 seconds later the guy goes back to the stance that he had before the button was pressed (the first drawing). I’m basically trying to learn how to use the timer and make things happen at precise times. A simplified code of what I'm trying to do is below with notes there so it can be easy to find. Thank you.




SetBuffer FrontBuffer()
GameTimer = CreateTimer(60)


Global GUYSTAND = LoadImage ("HenryRightStand.png")
Global GUYSHOUTS = LoadImage ("Ball.png")
Global GUYPUNCH = LoadImage ("HenryPunchRight.png")
Global FIRSTSTANCE = LoadImage ("Henryagain34.png")

Type FIRSTSTANCE1 
	Field x,y
	Field image
	Field time
End Type 

Type GUYSHOUTS1
	Field x,y
	Field image
	Field time
End Type 

Type GUYSTANDBACK1
	Field x,y
	Field image 
	Field time
	
End Type 

Type GUYPUNCH1
	Field x,y
	Field image
	Field time
End Type  

	

first1.FIRSTSTANCE1 = New FIRSTSTANCE1 
first1\x = 500
first1\y = 300
first1\image = FIRSTSTANCE

gshts.GUYSHOUTS1 = New GUYSHOUTS1
gshts\x = 500000
gshts\y = 300
gshts\image = GUYSHOUTS

gp.GUYPUNCH1 = New GUYPUNCH1
gp\x = 500000
gp\y = 300
gp\image = GUYPUNCH

gstbk.GUYSTANDBACK1 = New GUYSTANDBACK1
gstbk\x = 500000
gstbk\y = 300
gstbk\image = GUYSTAND




While Not KeyDown (1);------ I'm trying to figure out how to have better control of the times in which some moves 
					 ; are performed when a key is pressed. That is, I'm trying to learn how to work with the timer.



Cls


DrawImage (first1\image,first1\x,first1\y)  ;this is his stance BEFORE key 25 is pressed

DrawImage (gshts\image,gshts\x,gshts\y)  ;he immediately shouts when key (25) is pressed (first move).

DrawImage (gp\image,gp\x,gp\y)  ;he throws a punch 3 seconds AFTER key (25) is pressed (second move).

DrawImage (gstbk\image,gstbk\x,gstbk\y) ; this is his (third move) AFTER key (25) is pressed (he goes to a stance and stays in it for 5 seconds)
		                       ; 5 seconds later (in his final move),he goes back To the FIRST drawing BEFORE key (25) is pressed.
 



If KeyDown (25) Then 
	

	;Thus I was trying to figure out how to make the four things (drawings) happen after this key is pressed 
	;using the timer.
	
	
EndIf 

	If Not KeyHit (25) Then
	
	
	
;moves related to the above still happen after key(25) is released,
;I actually don't know if it's necesary to have this "If Not Keyhit (25)"
;command here.
	
	
	
		
	EndIf 	





Flip

Wend 






Last edited 2011


Rob the Great(Posted 2011) [#2]
To answer your first question, if you want to manually draw the images instead of using frames, that should work ok without problems. If you're going to do this, however, you shouldn't draw the non-used images off the side of the screen. This probably takes up processing power, and if you get a lot of images for your character being drawn off screen, it might slow your game down.

Instead, you should come up with a really good trigger system to do all sorts of stuff, and then only draw 1 image based on the trigger. Just a brief example:
Global playerx# = 0.0 ;hold x location
Global playery# = 0.0 ;hold y location
Global standimage = LoadImage("Stand Image.png") ;the standing frame
Global walkleftimage = LoadImage("Walk Left Image.png") ;the left walk frame
Global walkrightimage = LoadImage("Walk Right Image.png") ;the right walk frame
Global punchimage = LoadImage("Punch Image.png") ;the punch frame
Global playersob$ ;make 1 string variable for your main character. "sob" stand for "state of being", in case anyone was wondering

While Not KeyDown(1) ;MAIN LOOP

   Cls

   If KeyDown(LEFT_KEY) ;Can't remember the scancodes, but you get the idea...
      playersob$ = "walk left" ;state of being is now "walk left"
   EndIf

   If KeyDown(RIGHT_KEY)
      playersob$ = "walk right" ;state of being is now "walk lright"
   EndIf

   If Not KeyDown(LEFT_KEY) And Not KeyDown(RIGHT_KEY)
      playersob$ = "stand"
   EndIf

   If KeyDown(LEFT_KEY) And KeyDown(RIGHT_KEY)
      playersob$ = "stand"
   EndIf

   If KeyHit(SPACE_KEY)
         playersob$ = "punch" ;state if being is now "punch"
   EndIf

   Select playersob$ ;Here's what I mean by a trigger system. This will only draw 1 image based on the state of being
      Case "walk left" ;if playersob$ = "walk left"
         DrawImage(walkleftimage,playerx#,playery#)
         playerx# = playerx# - 0.1
      Case "walk right"
         DrawImage(walkrightimage,playerx#,playery#)
         playerx# = playerx# + 0.1
      Case "punch"
         DrawImage(punchimage,playerx#,playery#)
      Case "stand"
         DrawImage(standimage,playerx#,playery#)
   End Select

   Flip

Wend

With a good trigger system, you can handle a whole sequence of events just by changing playersob$. So, how would you make timing specific events occur? Use the same process, and this time, we're going to use Millisecs() for a timer.
;...same situation as above
   Select playersob$
      Case "walk left"
         DrawImage(walkleftimage,playerx#,playery#)
         playerx# = playerx# - 0.1
      Case "walk right"
         DrawImage(walkrightimage,playerx#,playery#)
         playerx# = playerx# + 0.1
      Case "punch"
         DrawImage(punchimage,playerx#,playery#)
         punchtimer = Millisecs() ;here's where we start the timer...
         playersob$ = "punch wait" ;don't do anything else until the timer is done
      Case "punch wait"
         DrawImage(punchimage,playerx#,playery#)
         If Millisecs() >= punchtimer + 3000 ;if 3 seconds have gone by
            playersob$ = "punch return"
            punchtimer = Millisecs() ;start the timer again for the next phase
         EndIf
      Case "punch return"
         DrawImage(punchreturnimage,playerx#,playery#)
         If Millisecs() >= punchtimer + 5000 ;if 5 seconds have gone by
            playersob$ = "stand"
         EndIf
      Case "stand"
         DrawImage(standimage,playerx#,playery#)
   End Select
;...

I know for a fact that there's some holes in the code, such as the left or right key will override the "punch" state of beings, but this just gives an example of how a trigger system works. It might be easier to stay organized if you use this in your game.


En929(Posted 2011) [#3]
Rob the Great, thanks. It worked. I'll continue working with the code you gave me. I think it works better than what I was working with. I'll come back if I have anymore questions.

Last edited 2011