Help with Animations for KeyHit?

BlitzMax Forums/BlitzMax Beginners Area/Help with Animations for KeyHit?

danielbritt95(Posted 2016) [#1]
Basically I am trying to make a Frogger game and I want it to go up when I press the up key and when I hit up it goes into one animation(legs extend) and to do the next animation I have to hit the up key again(legs retract) the code is ""
If KeyHit(Key_Up)
Player.y = Player.y - 20
DifficultyCursor.y = DifficultyCursor.y - 132
player.frame = player.frame + 1
If player.frame >1
player.frame = 0
EndIf
Endif"
How can I make it to where it will do the two frames, frame 1 is 0 and frame 2 is 1.
Also the difficulty cursor part is for a difficulty selection before starting the game.

EDIT : I know that it will either be frame 1 or frame 0 how do i make it to where it will do both frame 0 and frame 1 when hitting up.


Kryzon(Posted 2016) [#2]
You need to learn how to use a state machine in your code.
It's a way to change the behaviour of your game based on the value of a variable.

- https://www.scirra.com/tutorials/1139/how-to-simplify-your-ai-code-with-finite-state-machines

- http://howtomakeanrpg.com/a/state-machines.html

On one game state (like a game menu), pressing the up key changes the difficulty level.
On another game state (gameplay), pressing the up key changes the character state of the character from (whatever they're doing) to "moving". In the state processing code of the character you check to see what state the character is on (idle, moving, jumping etc.), and if it's in the "moving" state then you play the apropriate animation.


danielbritt95(Posted 2016) [#3]
Would the state machine make it do the full animation when i move the character?


Kryzon(Posted 2016) [#4]
You are free to program the state machine to do what you want on each state (such as changing frames of an animation), this is how you get different behaviours.
Please read those articles, they explain how it can help you.

To make a simple finite state machine you need to write code such as this:

Method processCharacterState()
	
	Select state
		Case STATE_IDLE
			'All the stuff you need to check on this idle state:
			'- Check if the idle animation is being played, and if not, change to it.
			'- Check if enough time has passed to advance the frame of the current animation (which is "idle").
			'- Check the keyboard keys being pressed, see if the character needs to change to another state (like, to jump or start moving).
			'- Check for collisions against the level and enemies.
		
		Case STATE_MOVING
			'All the stuff you need to check on this moving state:
			'- Check if the correct moving animation is being played based on the character direction, and if not, change to it.
			'- Check if enough time has passed to advance the frame of the current animation (which is "moving, to a certain direction").
			'- Check the keyboard keys being pressed to see if you need to change back to idle state or jump or keep moving.
			'- Check for collisions against the level and enemies.
			'If there are no collisions against the level, not even the ground, for example, the character should go to state STATE_FALLING where you apply gravity.
	End Select

End Method



danielbritt95(Posted 2016) [#5]
So do I need to download it?


Kryzon(Posted 2016) [#6]
No, it's a software design pattern, it's the way you structure your program.


danielbritt95(Posted 2016) [#7]
Oh okay,thanks but I was just really wondering how to do animations.


Midimaster(Posted 2016) [#8]
If you only have an animation with two frames, you could use a simply timestamp to reset the frame:
Type TPlayer
	Field X%, Y%, Frame%, AnimTime%, Frog:Timage

	
	Method Jump()
		Frame=1
		AnimTime=MilliSecs()+500
		Y = Y - 20
	End Method

	
	Method Draw()
		If  AnimTime<MilliSecs()
			Frame=0
		EndIf
		DrawImage Frog,X,Y,Frame
	End Method

End Type



Repeat
	Cls
		If KeyHit(Key_Up)
			Player.Jump
		EndIf
		
		Player.Draw()
	Flip
Until KeyHit(KEY_ESCAPE)



danielbritt95(Posted 2016) [#9]
If I was to have it be 3 frames I would just add Frame = 1 underneath frame =0?Thank you for the answer though.


Derron(Posted 2016) [#10]
You could just increase the frame each time your timer went to 0.

If AnimTime < Millisecs()
  Frame :+ 1
  AnimTime = Millisecs() + 500

  'variant 1
  if Frame = 4 then Frame = 0 'only Frame 0-3 would happen
  'variant 2
  Frame = Frame mod 4 'leading to 1 = 1, 2 = 2 ..., 4 = 0, 5 = 1, ...
Endif



bye
Ron


danielbritt95(Posted 2016) [#11]
Thanks,And for the first part could I put Field X%, Y%,
Field Frame%,
Field AnimTime%,
Field Frog:Timage


danielbritt95(Posted 2016) [#12]
Because at the top of my code I have Type TObject
Field x,y
Field image:TImage
Field frame
EndType


Midimaster(Posted 2016) [#13]
It does not matter ,if you write...
Type TObject
	Field X%, Y%, Frame%, AnimTime%, Image:Timage
...or ...
Type TObject
	Field x:Int, y:Int
	Field frame:Int
	Field AnimTime:Int
	Field image:Timage
But you should always define the variables, f.e. as INTEGER or FLOAT (good programming style)



To use more than two frames you should do it like this:
Type TObject
	Field X%, Y%, Frame%, AnimTime%, Frog:Timage

	
	Method Jump()
		Frame=1
		AnimTime=MilliSecs()+500
		Y = Y - 20
	End Method

	
	Method Draw()
		If ( Frame>0 ) AND ( AnimTime<MilliSecs() )
			Frame=Frame +1
			AnimTime = Millisecs() + 500
			If Frame=3 Then Frame=0
		EndIf
		DrawImage Frog,X,Y,Frame
	End Method

End Type

this stopps the animation, when the frog is returned to Frame 0


danielbritt95(Posted 2016) [#14]
Thanks, I usually do define them as an integer.But what is the purpose of % After some of the defined variables ( AnimTime% )


Midimaster(Posted 2016) [#15]
its the same... an old school version of ":INT"


danielbritt95(Posted 2016) [#16]
Oh okay thanks.Also what does Method do exactly?


Cocopino(Posted 2016) [#17]
Method is a function that only applies to the object/type.
E.g.

Type TMultiplicationTable

	Field number:Int
	
	Method ShowTable()

		Local i:Int
		For i = 1 To 10
			DebugLog(number * i)
		Next
		
	End Method

End Type

Local table:TMultiplicationTable = New TMultiplicationTable

table.number = 3
table.ShowTable()

table.number = 7
table.ShowTable()



Midimaster(Posted 2016) [#18]
You can compare the scope of METHOD versus FUNCTION with the type's variable scope GLOBAL versus FIELD:

If you create a member (instance) of a type it has its own variables called FIELDS. The type in total instead uses GLOBAL variables.

Analog to this a METHOD is a "function", which is only avaiable to the member (instance). The METHOD is used (written) like a field: with a point behind the member.

Global FrogA:TObject=New TObject
Global FrogB:TObject=New TObject

FrogA.X=3
FrogB.Jump()

Type TObject
	Field X%, Y%, Frame%, AnimTime%, Frog:Timage
	
	Method Jump()
		Frame=1
		AnimTime=MilliSecs()+500
		Y = Y - 20
	End Method
....
End Type

As you can see FrogA and FrogB are two members of the TObject. Only FrogA's X would become 3. Only FrogB would jump in this code.

Another advantage: All fields can be accessed directly inside the METHOD: You can also see, that inside the method the fields of FROGB like FRAME can be used without adding the word "FROGB".

There is a second possibility of writing methods, which may help you to understand. Same code like above:
Method Jump()
		Self.Frame=1
		Self.AnimTime=MilliSecs()+500
		Self.Y = Self.Y - 20
	End Method
....



Derron(Posted 2016) [#19]
A Method is like a Function with the added parameter "instance" (or "object")


Type TMyObject
  Field name:string

  Method PrintName(andNumber:int = 0)
    print name + andNumber
  End Method
End Type

Function PrintName(obj:TMyObject, andNumber:int = 0)
  if obj then print obj.name + andNumber
End Function

'alternative - if you want to have both ways
Function PrintNameAlternative(obj:TMyObject, andNumber:int = 0)
  if obj then obj.PrintName(andNumber)
End Function



global test:TMyObject = new TMyObject
test.name = "test"

test.PrintName(5)
PrintName(test, 6)
PrintNameAlternative(test, 7)



bye
Ron


danielbritt95(Posted 2016) [#20]
Do I have to call a method like I would for a function(as in putting the name of it in the main loop?


Kryzon(Posted 2016) [#21]
The syntax for calling a method and a function is explained well in this BlitzMax guide:
http://www.truplo.com/blitzmaxbeginnersguide/wave10.html


Midimaster(Posted 2016) [#22]
as you need an member (instance) of the type, you can only call the method with the instance's name in front:
Global FrogA:TObject=New TObject
Repeat
    FrogA.Jump()
    ....
Until...

Function CheckAll()
     ....
     FrogA.Jump()
End Function


Also very comfortable is to add all Objects to a list and the call each Object within a FOR/NEXT loop:
Global FrogA:TObject=New TObject
Global FrogB:TObject=New TObject

Global List:TList=New TList
List.AddLast FrogA
List.AddLast FrogB

For local locFrog:TObject= EachIn List
     locFrog.Jump()
Next

Until...

Function CheckAll()
     Frog.Jump()
End Function



danielbritt95(Posted 2016) [#23]
Why would I need to add the animation code in a method?


grable(Posted 2016) [#24]
You dont need to. One can do pretty much the same thing with bare functions.

The strength of Methods come into play when you start building type hierarchies by extending other types, where an extended type can override the behavior of its parent.

Something like what Midimaster posted, that Jump method can do something different for each type without the need for a second identifier tag and If-Else/Select-Case over it.


danielbritt95(Posted 2016) [#25]
Oh okay thanks.


danielbritt95(Posted 2016) [#26]
So I used the code that Midimaster posted " Type TObject
Field X%, Y%, Frame%, AnimTime%, Frog:Timage


Method Jump()
Frame=1
AnimTime=MilliSecs()+500
Y = Y - 20
End Method


Method Draw()
If ( Frame>0 ) AND ( AnimTime<MilliSecs() )
Frame=Frame +1
AnimTime = Millisecs() + 500
If Frame=3 Then Frame=0
EndIf
DrawImage Frog,X,Y,Frame
End Method

End Type

' And it for some reason isn't making the animations happen,why is that?


grable(Posted 2016) [#27]
Depends on how you call it i guess.. Heres an example using what you posted:



danielbritt95(Posted 2016) [#28]
What does "SetGraphicsDriver GLMax2DDriver()" do?


Midimaster(Posted 2016) [#29]
It is not necessary, remove it. Here is the same code with a more realistic jump:



danielbritt95(Posted 2016) [#30]
So I use the code that grable posted,but changed it to show the image I am trying to use and iit makes the player go up but it doesn't show the animations,why is that?Here is the code,it is the entire code,there is nothing else in it "

SuperStrict

Graphics 800,600,0

Global Frog:Tobject = New Tobject
Frog.X = 400
Frog.Y = 300

Repeat

If KeyHit(Key_Up) Then Frog.jump()

Frog.Draw()
Flip
Cls
Frog.image = LoadAnimImage ("Frogger 2.0 AnimTest.bmp",30,28,0,6)
DrawImage Frog.image,Frog.X,Frog.Y

Until KeyHit(Key_Escape) Or AppTerminate()
End

Type Tobject
Field X:Int,Y:Int,Frame:Int,AnimTime:Int,image:TImage,Frog:Int

Method Jump()
Frame = 1
AnimTime=MilliSecs()+500
Y = Y - 100
EndMethod

Method Draw()
If ( Frame >0 ) And ( AnimTime<MilliSecs() )
Frame = Frame + 1
AnimTime = MilliSecs() + 500
If Frame = 3 Then
Frame = 0
Y :+ 100
EndIf
EndIf
EndMethod
EndType

"


Midimaster(Posted 2016) [#31]
I would guess the 500msec are to long and the y-100 to big to see the animation.

The loading of the images should be before the REPEAT loop.

Does the images really contain 6 frames?

There is no need to have another DrawImage inside the REPEAT loop. Because you already call the FROG.DRAW method, which will also draw the frog.

Try this and report, what happened:



danielbritt95(Posted 2016) [#32]
Thanks for the reply,the reason it has 6 images is because I was making it for more than just going up the first 3 were for going up and the next three were for going left,but what happens with the game is that it goes up,then down an to the right but doesn't load the other animations.
EDIT:With the way I tried to make the animations,the first three images were for the frog to go up and the next three were so it can go left,so in the game it would be up would make it go up then left would make it go left.


danielbritt95(Posted 2016) [#33]
Thanks for the reply,the reason it has 6 images is because I was making it for more than just going up the first 3 were for going up and the next three were for going left,but what happens with the game is that it goes up,then down an to the right but doesn't load the other animations.
EDIT:With the way I tried to make the animations,the first three images were for the frog to go up and the next three were so it can go left,so in the game it would be up would make it go up then left would make it go left.


Midimaster(Posted 2016) [#34]
so do a first check about the frames are existing and the dimensions are ok. Test this as a new project (save it in the same folder like your original game) and report back

Download my image guitarl2.png and add it to this folder.



SuperStrict
Graphics 800,600,0
Local YourImage:TImage = LoadAnimImage ("Frogger 2.0 AnimTest.bmp",30,28,0,6)
Local MidiImage:TImage = LoadAnimImage ("GuitarL2.png",25,30,0,6)
SetColor 255,255,255
Repeat
	Cls
	For Local i%=0 To 5	
		DrawImage YourImage, i*50, 100, i
		DrawImage MidiImage, i*50, 200, i
	Next
	Flip 1
Until KeyHit(KEY_ESCAPE)



danielbritt95(Posted 2016) [#35]
So I did what you said and it shows all 6 of your images side by side,going from the first to the last,and above yours is all 6 of my images side by side.


Midimaster(Posted 2016) [#36]
so the image is OK and the frames are well dimensioned. Did you forget to add the FRAME% parameter in the DRAWIMAGE command?

DrawImage Frog.image, Frog.X, Frog.Y, Frog.Frame


or if you put the drawing into the method Draw:

Method Draw()
		If ( Frame>0 ) And ( AnimTime<MilliSecs() )
			..... 
		EndIf
		DrawImage Image, X, Y, Frame
....



danielbritt95(Posted 2016) [#37]
I didn't use Frog.Frame,I did just have it be frame:Int.Was that the problem?


Midimaster(Posted 2016) [#38]
In your post #30 you wrote:
DrawImage Frog.image,Frog.X,Frog.Y
here you forgot the Frame parameter!


And you defined Frame as a field of TObject. So you have to use it as a property of the objects:
Frog.Frame
It is is the same like X and Y

So please try the code in my post #31. It should work.


danielbritt95(Posted 2016) [#39]
But your post at 31 doesn't have frog.frame?


danielbritt95(Posted 2016) [#40]
Never mind I used the code at 31 and it worked,thank you.But the weird thing is that it doesn't have frog.frame,instead it is "DrawImage Image, X,Y, Frame"


Midimaster(Posted 2016) [#41]
Yes, this is because a Method is already "inside" of each object (member) of a type: No need to additional write the objects name to the field variables.


So your Method DrawImage() is inside the Frog-Object: No need to additional write "Frog." to the field variables like X, Y or Frame. (Look: You will also find no Frog.X in my code)


What you could do inside a method is to add "Self." to all field variables. But it is unnecessary:
	Method Draw()
		If ( Self.Frame>0 ) And ( Self.AnimTime<MilliSecs() )
			Self.Frame=Self.Frame +1
			Self.AnimTime = MilliSecs() + 200
			If Self.Frame=3 Then
				Self.Frame=0
				Self.Y :+ 15
				Self.X :+ 15
			EndIf
		EndIf
		DrawImage Self.Image, Self.X,Self.Y, Self.Frame
	End Method



danielbritt95(Posted 2016) [#42]
What exactly would adding self to everything do?


Midimaster(Posted 2016) [#43]
Nothing! It is only a second possibility to write the code. Some prefer to add "self.". I prefer only to write the field names.


FireballStarfish(Posted 2016) [#44]
"Self" is needed inside a method if you want to acquire the object itself that the method was called on, the "Frog" in your case. If you don't need a reference the object itself, only to members of it (like in the code in #41 above), you can still add "Self." in front of their names. If there's a local variable of the same name as the member, this will make sure you get the member and not the local var, otherwise it's optional.


danielbritt95(Posted 2016) [#45]
Oh okay thanks.But now I have a new problem with it,all of the animations work perfectly if I make it to where the only thing that you can do is that animation(for key up,down,left right)but when I include them all in the code,the only one that works how it is supposed to work is key_up and the rest just go through all the animations nonstop until it goes past the last animation(in this case it is number 12) the code will be in the next reply.


danielbritt95(Posted 2016) [#46]
Graphics 800,600,0

Local Frog:TObject = New TObject
Frog.X = 400
Frog.Y = 250
Frog.image = LoadAnimImage ("Frogger 2.0 AnimTest.bmp",30,28,0,12)
Repeat
	If KeyHit(Key_Up) Then Frog.Up()
	If KeyHit(Key_Left) Then Frog.Left()
	If KeyHit(Key_Right) Then Frog.Right()
	If KeyHit(Key_Down) Then Frog.Down()
		Frog.Draw()
	Flip
	Cls
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End

Type TObject
	Field X%, Y%, Frame%, AnimTime%, Image:TImage	
	
	Method Up()
		Frame = 1
		AnimTime=MilliSecs()+200
		Y = Y - 20
	End Method

	Method Left()
		Frame = 5
		AnimTime=MilliSecs()+200
		X = X - 20
	End Method

	Method Right()
		Frame = 7
		AnimTime=MilliSecs()+200
		X = X + 20
	EndMethod

	Method Down()
		Frame = 10
		AnimTime=MilliSecs()+200
		Y = Y + 20
	EndMethod
	

	
	Method Draw()		
	
					'Up
		If ( Frame>0 ) And ( AnimTime<MilliSecs() )
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200
			If Frame=3 Then
				Frame=0
	 		EndIf
		EndIf		

					'Left
		If ( Frame>4 ) And ( AnimTime<MilliSecs() )
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200
			If Frame=6 Then
				Frame=3
	 		EndIf
		EndIf	
		
					'Right
		If (Frame >6) And (AnimTime<MilliSecs() )
			Frame = Frame + 1
			AnimTime = MilliSecs() + 200
			If Frame = 9 Then
				Frame = 6
			EndIf
    	EndIf
		
					'Down
		If (Frame >9) And (AnimTime<MilliSecs() )
			Frame = Frame + 1
			AnimTime = MilliSecs() + 200
			If Frame > 11 Then
				Frame = 9
			EndIf
		EndIf
		DrawImage Image, X,Y, Frame
	End Method
End Type
	
	




Midimaster(Posted 2016) [#47]
your code looks good, but you need to change the order of conditions in the method Draw().

An example will show you the problem: You press KEY_DOWN and FRAME will become 10.

When the code now comes to Draw() the first condition will be fullfilled!
	Method Draw()		
					'Up
		If ( Frame>0 ) And ( AnimTime<MilliSecs() )

10 is greater than 0. So the code wil jump into the first condition ("up") . this is not what you want.

You can change the order of condition. Now the highest values are on the top:
Method Draw()		
		'Down
		If (Frame >9) And (AnimTime<MilliSecs() )
			...
		'Right
		If (Frame >6) And (AnimTime<MilliSecs() )
			...
		'Left
		If ( Frame>4 ) And ( AnimTime<MilliSecs() )
			...
		'Up
		If ( Frame>0 ) And ( AnimTime<MilliSecs() )
			...


Now a 10 will jump into "Down". And a 7 into "Right"...

But now you will have the next problem. At the end of a "Down" sequence the FRAME will become 9. And this fulfilles the condition for "Right", because 9 is greater than 6.

The best way is not to use FRAME for decisions any more, but add a new field ACTION%, which knows, that an animation is running.




danielbritt95(Posted 2016) [#48]
Okay so now I have a new problem lol,when I run the program it says "Missing function parameter 'Direction' on the part where it says "If KeyHit(Key_Up) Then Frog.Up()"I have no idea on how to fix it,please help.Edit : Here is the entire code of the program
Graphics 800,600,0

Local Frog:TObject = New TObject
Frog.X = 400
Frog.Y = 250
Frog.image = LoadAnimImage ("Frogger 2.0 AnimTest.bmp",30,28,0,12)
Repeat
	If KeyHit(Key_Up) Then Frog.Up()

	If KeyHit(Key_Left) Then Frog.Left()

	If KeyHit(Key_Right) Then Frog.Right()
	If KeyHit(Key_Down) Then Frog.Down()
		Frog.Draw()
	Flip
	Cls
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End

Type TObject
	Field X%, Y%, Frame%, AnimTime%, Image:TImage, Action%	

	
	Method Up (Direction%)
		Action=1   '************** add this to all four methods!
		Frame = 1
		AnimTime=MilliSecs()+200
		Y = Y - 20
	End Method

	Method Down(Direction%)
		Action=1
		Frame = 1
		AnimTime=MilliSecs()+200
		Y = Y - 20
	End Method
	
	Method Left(Direction%)
		Action=1
		Frame = 1
		AnimTime=MilliSecs()+200
		Y = Y - 20
	End Method
	
	Method Right (Direction%)
		Action=1
		Frame = 1
		AnimTime=MilliSecs() + 200
		Y = Y - 20
	End Method
	
	Method Draw()		
		If Action>0
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200
				If Frame=3 Then
					Frame=0
					Action=0
		 		ElseIf Frame=6 Then
					Frame=3
					Action=0
		 		ElseIf Frame = 9 Then
					Frame = 6
					Action=0
				ElseIf Frame =12 Then
					Frame = 9
					Action=0
				EndIf
		EndIf
		DrawImage Image, X,Y, Frame
	End Method
	End Type




Derron(Posted 2016) [#49]
Your functions declare a param "Direction%" - but when calling "bla.Up()" you do not provide one.

Either define "default params":

Method Right(Direction%=0)

or provide a param

bla.Up(0)


But the best is: just remove that param from the method/function definition at all - as within that methods you do not use that param-variable at all.


bye
Ron


danielbritt95(Posted 2016) [#50]
So instead of If KeyHit(Key_Down) Then Frog.Down()
use method right(Direction%= 0)???


Derron(Posted 2016) [#51]
For your current code:

If KeyHit(Key_Down) Then Frog.Down(1)
(the 1 could be any number as you do not work with the variable within the method "Down()")



If you changed "Method Down(Direction%)" to "Method Down()" you would not need to adjust the "If KeyHit..."-lines.


bye
Ron


danielbritt95(Posted 2016) [#52]
Okay so I got it to work,thanks to Derron and Midimaster,but the weird thing is,when I press up it does 1 and 3,if i press left 3 and 5 and so on for down and right,basically it doesn't do the middle animation,only the first and last.Here is the code
Graphics 800,600,0

Local Frog:TObject = New TObject
Frog.X = 400
Frog.Y = 250
Frog.image = LoadAnimImage ("Frogger 2.0 AnimTest.bmp",30,28,0,12)
Repeat
	If KeyHit(Key_Up) Then Frog.Up(1)

	If KeyHit(Key_Left) Then Frog.Left(1)

	If KeyHit(Key_Right) Then Frog.Right(1)
	If KeyHit(Key_Down) Then Frog.Down(1)
		Frog.Draw()
	Flip
	Cls
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End

Type TObject
	Field X%, Y%, Frame%, AnimTime%, Image:TImage, Action%	

	
	Method Up (Direction%)
		Action=1   '************** add this to all four methods!
		Frame = 0
		AnimTime=MilliSecs()+200
		Y = Y - 20
	End Method
	
	Method Left(Direction%)
		Action=4
		Frame = 4
		AnimTime=MilliSecs()+200
		X = X - 20
	End Method
	
	Method Right (Direction%)
		Action=7
		Frame = 6
		AnimTime=MilliSecs() + 200
		X = X + 20
	End Method
	
	Method Down(Direction%)
		Action=9
		Frame = 9
		AnimTime=MilliSecs()+200
		Y = Y + 20
	End Method

	Method Draw()
		If Action>0
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200
				If Frame=3 Then     	'UP
					Frame = 0
					Action=0
		 		ElseIf Frame=6 Then		'LEFT
					Frame=3
					Action=0
		 		ElseIf Frame = 9 Then	'RIGHT 
					Frame = 6
					Action=0
				ElseIf Frame =12 Then	'DOWN
					Frame = 9
					Action=0
				EndIf
		EndIf
		DrawImage Image, X,Y, Frame
	End Method
	End Type





Midimaster(Posted 2016) [#53]
sorry, my mistakes!

1.
"Direction%" is not necessary... I had an idea, tested it, discarded it, but forgot to remove the parameter "Direction%" from the code. Sorry!

Wrong:
Type TObject
	Method Up (Direction%)

Right:
Repeat
	If KeyHit(Key_Up) Then Frog.Up()
	If KeyHit(Key_Left) Then Frog.Left()
	If KeyHit(Key_Right) Then Frog.Right()
	If KeyHit(Key_Down) Then Frog.Down()
...
Type TObject
	Method Up()



2.
I removed "If Animtime<Millisecs()". But it is necessary. Sorry, I wrote the code in #47 without testing it.
Wrong:
	Method Draw()
		If Action>0
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200

Right:
	Method Draw()
		If ( Action>0 ) And ( AnimTime<MilliSecs() )
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200




So this would be correct:



danielbritt95(Posted 2016) [#54]
There is honestly no reason to apologize since you have helped me with the code and the knowledge of coding.But hat completely fixed it,after 53 posts it was finally resolved,thank you so much for your help,anyone and everyone who helped me out with this endeavor.I would have never have been able to do it without the people who told me what to do and gave me the code,mainly to Midimaster,I honestly had no idea on how to do it as I have never attempted animations before.

Now I have just one final question,when I impliment it into the code of the real game,that I have finished except for the animations,when I go to do collisions with other objects what do I do?

I sort of have an idea but I am pretty sure that I am wrong here is the code that I had set up without the animations "
If ImagesCollide(Frog.image,Frog.x,Frog.y,0,car.image,car.x,car.y,0)
		score = score - 1
			'Bring Frog back to starting location
	Frog.x = 300
	Frog.y = 550
EndIf


And what I think would be to replace the 0 that is after Frog.y with the number of total animations which in the case of the frog animation would be 12 and to add Action,but I am pretty sure that is wrong.


Midimaster(Posted 2016) [#55]
The number behind Frog.Y is not the total number of animation frames, but the current frame, which is visible at this moment. In case of the frog it is "Frog.Frame". If Car is a image without animation "0" is correct.
If ImagesCollide( Frog.image, Frog.x, Frog.y, Frog.Frame, car.image, car.x, car.y, 0 )
	score = score - 1
	'Bring Frog back to starting location
	Frog.x = 300
	Frog.y = 550
	Frog.Action=0 
EndIf
Don't forget to set Action to 0!


danielbritt95(Posted 2016) [#56]
okay thanks.


Kryzon(Posted 2016) [#57]
I feel the need to say some things.
I think you're being unhelpful to yourself by trying to program something like a game, which is not a trivial thing, without going through some basic study of the language you're using.

For example, you wrote:
it says "Missing function parameter 'Direction' (...) I have no idea on how to fix it
Parameters to functions are a fundamental concept in programming, you shouldn't go ahead without knowing how to use these.

I posted this earlier, I recommend that you read through this. It's a simple guide to programming in BlitzMax:
http://www.truplo.com/blitzmaxbeginnersguide/wave1.html

You can find more in the BlitzMax tutorial section:
http://www.blitzbasic.com/Community/topics.php?forum=112

- - - - - -
Some comments on the code being posted:
- That 'action' variable is only being used to control whether to update the animation or not, and this type of use is ideal for a boolean value. So instead of assigning several different values to 'action' as it is (which is misleading since those different values are not doing anything), use it in an "on" or "off" way like a boolean variable and rename it like a proper boolean, with the naming being "the question that is answered by the value of the boolean":

	Field isMoving:Byte

	Method Draw()
		If isMoving And ( AnimTime < MilliSecs() )
			Frame=Frame + 1
			AnimTime = MilliSecs() + 200

			If Frame = 3 Then     	'UP
				Frame = 0
				isMoving = False
		 	ElseIf Frame= 6 Then	'LEFT
				Frame=3
				isMoving = False
		 	ElseIf Frame = 9 Then	'RIGHT 
				Frame = 6
				isMoving = False
			ElseIf Frame = 12 Then	'DOWN
				Frame = 9
				isMoving = False
			EndIf
		EndIf
		'DrawText Frame,X,Y
		DrawImage Image, X,Y, Frame
	End Method

- You mentioned having trouble with changing the animations and frames, and I understand why. There's a lot of repetition going on in that Draw() method, for changing frames and checking whether the frame limits have been reached. It's a lot of places where something could go wrong.
You can help yourself here by using a separate class whose sole responsibility is to update frames and check for reaching the end of animations. You use a separate class because you can then write all the logic once and use instances of that class to control different frame sequences (up, down, left etc.) -- this is where knowing how to code in BlitzMax helps, you need to know how to use custom types.

Type FrameSequence
	Field startFrame:Int
	Field endFrame:Int
	Field frame:Int
	Field _isFinished:Byte
	
	Method begin()
		frame = startFrame
		_isFinished = False
	End Method

	Method advanceFrame()
		frame :+ 1
		If frame > endFrame Then 
			frame = startFrame
			_isFinished = True
		EndIf
	End Method

	Method getFrame:Int()
		Return frame
	End Method

	Method isFinished:Byte()
		Return _isFinished
	End Method
End Type

(...)
'To be used like this for example:

	Method Up()
		currentSequence = upSequence
		currentSequence.begin()
	End Method

	Method Draw()
		If isMoving And ( animTime < MilliSecs() ) Then
			animTime = Millisecs()
			currentSequence.advanceFrame()
			If currentSequence.isFinished() Then 
				currentSequence = idleSequence
				currentSequence.begin()
			EndIf
		EndIf

		DrawImage image, x, y, currentSequence.getFrame()
	End Method
See how simple and literal things get? If you read that code a few weeks from now when you don't remember anything about it, it'll be much easier to understand how it works.


Kryzon(Posted 2016) [#58]
double post