My frames are not acting right

BlitzPlus Forums/BlitzPlus Programming/My frames are not acting right

En929(Posted 2011) [#1]
I'm still a beginner in game programming. It has been a long time since I have posted here. My question regards animation. In my game code below, I'm wondering why when I press a button (key 25), the character does other things in the frame before it does what I want it to do (punch)?

While I'd also like to know why my character doesn't do what I wanted instantly, I also would like to know how to get it so that I can just press one key for my character to punch (in the code below, I got it so that one key [key 25] is used to punch in the right direction and another key [key 24] is used to punch in the left direction - but, I'd like to eventually change that and make it all be done with one key). Thanks





Graphics 1640, 1000


Global HENRY

;load images
HENRY = LoadAnimImage ("HenryMoveAroundIII.PNG",400,370,0,14)
LADDER = LoadImage ("Ladder.png")
GOUPLADDER = LoadSound ("Thump.wav")


;define types

Type HENRY
	Field x,y	
	Field frame 
End Type 

Type LADDER
	Field x,y
End Type 


;set where the characters will start on screen
h.HENRY = New HENRY

h\x = 500
h\y = 200
h\frame = 0


l.LADDER = New LADDER
l\x = 500
l\y = 25




While Not KeyDown(1)

		Cls 
		
		
;these lines below initiate the punch, but everytime key (25) is hit, Henry doesn't instantly punch. He cycles through other 
;standstill frames before actually punching. I wonder why?		
		
If KeyHit(25)
		
		h\frame = h\frame + 1
				
				 If  h\frame > 7 
					h\frame = 6			
		 
	 
				EndIf  		
												
EndIf 							
								
								
					
					
					
;I have the same problem here as I do with Key (25). When key (25) is pressed, Henry goes through other still frames instead of 
;doing only the punch frame.
												
							
If KeyHit(24) Then 
										
		
		h\frame = h\frame +1
		
				If h\frame > 9    
					h\frame = 8
							
				EndIf 	
EndIf 							
		
		
;This works perfectly. When key (205) e.g. the arrow key is pressed, Henry instantly walks across the screen and show him walking 
;the first time the arrow key is pressed. Thus, there's no problem here
		
		
If KeyDown(205)			
		
		h\x = h\x + 3
		
		h\frame = h\frame + 1
		
		If h\frame > 2 Then 
		h\frame = 1
		
		EndIf 
		
		
EndIf

;this also works perfectly. So thus, I wonder why Keys (24) and (25) are not executing as instant as keys (205) and (206) are.

If KeyDown(203)

		h\x = h\x - 3									;
		
		h\frame = h\frame + 1
		
        If h\frame > 5 Then
		h\frame = 4


        EndIf 

EndIf  	
		
	
		
		

;finally, I'd like for the punches to be done with only one key (e.g. key 25). I will elimnate key (24) eventually,
;but I still want to know why it isn't working the way I want it to work?		
		
		
		
		
		
		
		If ImagesCollide (HENRY, h\x, h\y,0,LADDER, l\x, l\y,0) Then 
		

							
		
		
							If KeyHit (200) Then 
							
								PlaySound (GOUPLADDER)
	
								h\y = h\y - 40
		
								h\frame = h\frame + 1
							
								If h\frame > 11 Then 
								h\frame = 10
								
								EndIf 
	
	
							EndIf
							
							
							If KeyHit (208) Then 
							
								PlaySound (GOUPLADDER)
	
								h\y = h\y + 40
		
								h\frame = h\frame + 1
							
								If h\frame > 13 Then 
								h\frame = 12
								
								EndIf 
	
	
							EndIf

							
						
		EndIf 
		
							
							


							
		
		
		
		
		
		
		
		

DrawImage (LADDER, l\x,l\y)

DrawImage (HENRY,h\x,h\y,h\frame)



Flip

Wend 




Rob the Great(Posted 2011) [#2]
Ok, I'm going to work with you and you're code a little bit. Definitely the right direction, but it's a little on the sloppy side, so I've cleaned it up a little bit. I've also made some changes below, please read the comments to know more about what I did.
Graphics 1640, 1000 ;Wow! Mega-screen...

Global HENRY

;load images
HENRY = LoadAnimImage ("HenryMoveAroundIII.PNG",400,370,0,14)
LADDER = LoadImage ("Ladder.png")
GOUPLADDER = LoadSound ("Thump.wav")

;define types

Type HENRY
	Field x,y
	Field frame
End Type

Type LADDER
	Field x,y
End Type 

;set where the characters will start on screen
h.HENRY = New HENRY

h\x = 500
h\y = 200
h\frame = 0

l.LADDER = New LADDER
l\x = 500
l\y = 25

While Not KeyDown(1)

   Cls 
		
		
   ;these lines below initiate the punch, but everytime key (25) is hit,
   ;Henry doesn't instantly punch. He cycles through other 
   ;standstill frames before actually punching. I wonder why?		

   If KeyHit(25)	
      h\frame = h\frame + 1
      If  h\frame > 7
         h\frame = 6	
      EndIf
      ;This ensures that you do not start with earlier frames
      ;than the punch frames (e.g. 0,1,2,3,4,5)
      ;This will cycle back and forth between 6,7,6,7,6,7,ect...
      If h\frame < 6
         h\frame = 6
      EndIf					
   EndIf					
				
   ;I have the same problem here as I do with Key (25).
   ;When key (25) is pressed, Henry goes through other still frames
   ;instead of doing only the punch frame.

   If KeyHit(24)	
      h\frame = h\frame + 1
      If  h\frame > 9
         h\frame = 8	
      EndIf
      ;This ensures that you do not start with earlier frames than the
      ;punch frames (e.g. 0,1,2,3,4,5,6,7)
      ;This will cycle back and forth between 8,9,8,9,8,9,ect...
      If h\frame < 8
         h\frame = 8
      EndIf					
   EndIf	

   ;This works perfectly. When key (205) e.g. the arrow key is pressed,
   ;Henry instantly walks across the screen and show him walking 
   ;the first time the arrow key is pressed. Thus, there's no problem here

   If KeyDown(205)
      h\x = h\x + 3
      h\frame = h\frame + 1
      If h\frame > 2 Then 
         h\frame = 1
      EndIf
      ;This one works because h\frame should never be below 0. Nonetheless,
      ;you will learn very quickly in programming that whenever you assume
      ;it will work, that's the perfect situation for it to fail. Remember,
      ;when you assume, you make an A** out of U and Me.
      ;As a safeguard, use the lines below
      If h\frame < 0
         h\frame = 0
      EndIf
   EndIf

   ;this also works perfectly. So thus, I wonder why Keys (24) and (25)
   ;are not executing as instant as keys (205) and (206) are.

   ;Are you sure this is working? What happens if you push Key(203)
   ;when you first run the program?
   ;Think of the frame order. What you programmed would go like this:
   ;0,1,2,3,4,5,4,5,4,5,4,5,ect...
   ;Try this instead...

   If KeyDown(203)
      h\x = h\x - 3
      h\frame = h\frame + 1
      If h\frame > 5 Then 
         h\frame = 4
      EndIf
      ;Remember, the lines below make sure you start with the loop region
      If h\frame < 4
         h\frame = 4
      EndIf
   EndIf

   ;finally, I'd like for the punches to be done with only one key
   ;(e.g. key 25). I will elimnate key (24) eventually,
   ;but I still want to know why it isn't working the way I want it to work?

   ;Don't worry about the above concept for now. You can get that later.
   ;I've made no more changes other than spacing to my preferences

   If ImagesCollide (HENRY, h\x, h\y,0,LADDER, l\x, l\y,0) Then 
      If KeyHit (200) Then
         PlaySound (GOUPLADDER)
         h\y = h\y - 40
         h\frame = h\frame + 1
         If h\frame > 11 Then 
            h\frame = 10
         EndIf 
      EndIf
      If KeyHit (208) Then 
         PlaySound (GOUPLADDER)
         h\y = h\y + 40
         h\frame = h\frame + 1
         If h\frame > 13 Then 
            h\frame = 12
         EndIf 
      EndIf
   EndIf 

   DrawImage (LADDER, l\x,l\y)

   DrawImage (HENRY,h\x,h\y,h\frame)

   Flip

Wend 



En929(Posted 2011) [#3]
Rob, thanks. It worked and I'm sorry that my game code was a bit sloppy. I have one more question. Let's take this game code below for instance:


If KeyHit(25)	
      h\frame = h\frame + 1
      If  h\frame > 7
         h\frame = 6	
      EndIf
      ;This ensures that you do not start with earlier frames
      ;than the punch frames (e.g. 0,1,2,3,4,5)
      ;This will cycle back and forth between 6,7,6,7,6,7,ect...
      If h\frame < 6
         h\frame = 6
      EndIf					
   EndIf			



The above worked well. Now I'm trying to figure out how to add something to this game code so that after punching my character's arm automatically goes back down when the (25) button is released (e.g. go from frame 7 to frame 6 automatically when button 25 has been released). I tried the "If not keyhit (25)" command but it didn't work. Maybe I'm doing something wrong. Thanks again.


Serpent(Posted 2011) [#4]
If you want a press/release thing you need to use key down.
KeyDown(X) is true while the user holds X down, and false when released.
To detect when they release it, KeyHit(X) should work (it returns true one time, after the user has released X).

Try this (and see comments):

;If the user is holding down the key:
If KeyDown(25)
      h\frame = h\frame + 1
      If  h\frame > 7
         ;h\frame = 6  ;Uncomment this for repetitive punching (i.e. 6,7,6,7,6,7...)
         h\frame = 7  ;Use this for one punch per press (i.e. 6,7,7,7,7,7...)
      EndIf
      ;This ensures that you do not start with earlier frames
      ;than the punch frames (e.g. 0,1,2,3,4,5)
      ;This will cycle back and forth between 6,7,6,7,6,7,ect...
      If h\frame < 6
         h\frame = 6
      EndIf					

   EndIf

;If the user has just pressed and released the key:
If KeyHit(25)
    h\frame = 0 ;reset the frame (change the value to what you want)
EndIf



En929(Posted 2011) [#5]
Hi Serpent. Thanks for the help. It worked.