Updateing Framecount individually?

BlitzMax Forums/BlitzMax Beginners Area/Updateing Framecount individually?

Amon(Posted 2007) [#1]
I have an array. The Array is of Type TTile. TTile has an image field and a frame field.

if Array[x,y].frame = 0
DrawBomb , blah, blah, 0

if Array[x,y].frame = 1
DrawBomb , blah, blah, Frame

Frame:+1

Now, what I want to do is to have the frame update seperately for each Bomb when the mouse is on it.

So, if there are 5 bombs in a row and I move the mouse on the first bomb, I want its frame to update. When I move the mouse on the second bomb I want it frame to update but from the begining. The first Bombs frame could be half way through and when I start the second bombs frame it starts from the begining for the second bomb.


Currently I create a bomb wherever there is one in the array by using "local b:bomb = new Bomb.

then I assign the frames "b.frame = 0" and timer "b.Timer = millisecs()"

am I making sense?

[edit] It's 4 am here in London and I'm still up. I'm watching StarTrek the Motion Picture and trying to code a game with the new platform skills I've been tought :)


degac(Posted 2007) [#2]
If I have unterstand correctly what you want, something like this?

Type ttile
	Field x:Int , y:Int
	Field frame:Int , frame_start:Int , frame_end:Int , frame_delay:Int
	Field frame_timer:Int
	
	Field mouse_is_over:Int=0
	
	Function create:ttile(xx:Int , yy:Int , fstart:Int = 0,fend:Int=5)
		Local t:ttile = New ttile
		t.x = xx
		t.y = yy
		t.frame = fstart
		t.frame_start = fstart
		t.frame_end=fend
		t.frame_delay = 125
		t.frame_timer = MilliSecs()

		Return t
	End Function
	
	Method Update()
		
		If MouseX() > x And MouseX() < x + 15 And MouseY() > y And MouseY() < y + 15 mouse_is_over = 1 Else mouse_is_over = 0รน
		
		If mouse_is_over=1
		'the mouse is on the tile
		If MilliSecs() > frame_timer + frame_delay
		
			frame:+ 1
			
			If frame > frame_end frame = frame_start
		
			frame_timer = MilliSecs()
		End If
		End If
	'drawmimage frame....
	SetColor 128 , 128 , 128
	DrawRect x , y , 15 , 15
	SetColor 255 , 255 , 255
	
	DrawText frame , x , y
	
	End Method
End Type

Graphics 640 , 480
Local arr:ttile[10 , 10]

'initialize new array

For x1 = 0 Until 10
	For y1 = 0 Until 10
		arr[x1 , y1] = ttile.Create(x1*16 , y1*16)
	Next
Next

While Not AppTerminate() 
	Cls
	For x1 = 0 Until 10
	For y1 = 0 Until 10
		arr[x1 , y1].update
	Next
Next
Flip
Wend


When the mouse is over the tile (which size I fixed in 16x16 pixels - see the MOuseX()... line) the frame counter is activated else is stopped.


Amon(Posted 2007) [#3]
Hi! Thanks for the reply. I have created some very messy code to show you what I want doing.

You can download here: http://www.kamikazekrow.com/storage/bombtest.zip

Basically it draws bombs to screen. When the mouse is clicked and it is over a bomb it activates the anim.

Notice that when a second or third bomb is activated the animation starts from the same position as the last one. ie it doesn't start from the begining for the newly activated bomb.

heres the code

SuperStrict


Graphics 800, 600

Global bomb:TImage = LoadAnimImage("bomb.png", 32, 32, 0, 14) 


Global MapWidth:Int = 25
Global MapHeight:Int = 600 / 32

Global MapArray:TTile[MapWidth, MapHeight]

Type TTile
	Field x:Int
	Field y:Int
	Field image:TImage
	Field Frame:Int
	Field BombFRame:Int
	Field BombFrameTimer:Int
	
	Global List:TList
	
	Function Create:TTile() 
		Return New TTile
	End Function
	
	Function PrefillMapArray() 
		For Local y:Int = 0 Until MapHeight
			For Local x:Int = 0 Until MapWidth
				MapArray[x, y]= TTile.Create() 
				MapArray[x, y].Frame = 0
				If MapArray[x, y].Frame = 0
					TTile.CreateBomb
				End If
			Next
		Next
	End Function
	
	Function Draw() 
		For Local x:Int = 0 Until MapWidth
			For Local y:Int = 0 Until MapHeight
				Select MapArray[x, y].Frame
					Case 0
						DrawImage bomb, X * 32, Y * 32, 0
					Case 1
						' This bit below. I want the bombs to animate seperetaly when the character is on it.
						' Useing the mouse position to activate the anim would be fine for this example.
						For Local b:TTile = EachIn TTile.List
							DrawImage bomb, x * 32, y * 32, b.BombFRame
							b.UpdateBomb
						Next
				End Select
			Next
		Next
	End Function

	Function CreateBomb() 
		If not TTile.List
			TTile.List = CreateList() 
		End If
		Local b:TTile = New TTile
		b.BombFRame = 0
		b.BombFrameTimer = MilliSecs() 
		TTile.List.AddLast(b) 
	End Function
	
	Method UpdateBomb() 
		If MilliSecs() > BombFRameTimer + 200
			BombFrame:+1
			If BombFrame > 13 Then BombFrame = 0
			BombFrameTimer = MilliSecs() 
		End If
	End Method
	
	Function ActivateBomb() 
		If MapArray[MouseX() / 32, MouseY() / 32].Frame = 0
			If MouseHit(MOUSE_LEFT) 
				MapArray[MouseX() / 32, MouseY() / 32].Frame = 1
			End If
		End If
	End Function
End Type


TTile.PrefillMapArray

While not KeyHit(KEY_ESCAPE) 
	Cls
		TTile.Draw
		TTile.ActivateBomb
	Flip
	
WEnd


I know the codes a mess.


Czar Flavius(Posted 2007) [#4]
I'm not sure what you're asking. You create a bomb, and each time the mouse goes over the bomb, its frame resets to 0?


degac(Posted 2007) [#5]
Case 1
' This bit below. I want the bombs to animate seperetaly when the character is on it.
' Useing the mouse position to activate the anim would be fine for this example.
'For Local b:TTile = EachIn TTile.List
'	DrawImage bomb, x * 32, y * 32, b.BombFRame
'		b.UpdateBomb
'Next

Local amap:ttile = MapArray[x , y]
amap.UpdateBomb()
DrawImage bomb, x * 32, y * 32, amap.BombFRame

This?

I dont' see any reason to use a list...


Amon(Posted 2007) [#6]
No. The map array is filled with bombs.

if MapArray[x,y].frame = 0 then Draw Bomb but dont animate

if MapArray[x,y].frame = 1 then Draw Bomb and animate.

I want the bombs to animate individually when clicked. Try out the code I posted by downloading the zip.

If i click on a bomb it starts animating. If I click on another bomb it doesn't start animating from the begining. Instead it flicks to the saem frame as the previously clicked bomb.

[edit] I'll try your method Degac. thanks :)


Amon(Posted 2007) [#7]
Nope. I can't seem to get it to work. I don't know how to update each bombs frames individually.


tonyg(Posted 2007) [#8]
Amon, where do you ever populate b.bombframe to be used in your draw function?
The 'b' variable used in Createbom is local to that function.


Amon(Posted 2007) [#9]
I don't think I understand. I create bombs with this.

	Function CreateBomb() 
		If not TTile.List
			TTile.List = CreateList() 
		End If
		Local b:TTile = New TTile
		b.BombFRame = 0
		b.BombFrameTimer = MilliSecs() 
		TTile.List.AddLast(b) 
	End Function


And if MapArray[x,y].frame = 0, I TTile.createbomb()


degac(Posted 2007) [#10]
How? Doen't it work?

I post you source (I deleted some thing unused)
When you click with the mouse on a bomb it starts to animate (from frame 1). If you click on another bomb it starts to animate from frame 1 too!


SuperStrict


Graphics 800, 600

Global bomb:TImage = LoadAnimImage("bomb.png", 32, 32, 0, 14) 


Global MapWidth:Int = 25
Global MapHeight:Int = 600 / 32

Global MapArray:TTile[MapWidth, MapHeight]

Type TTile
	Field x:Int
	Field y:Int
	Field image:TImage
	Field Frame:Int
	Field BombFRame:Int
	Field BombFrameTimer:Int
	
		

	Function PrefillMapArray() 
		For Local y:Int = 0 Until MapHeight
			For Local x:Int = 0 Until MapWidth
				MapArray[x, y]= TTile.CreateBomb() 
			Next
		Next
	End Function
	
	Function Draw() 
		For Local x:Int = 0 Until MapWidth
			For Local y:Int = 0 Until MapHeight
				Select MapArray[x, y].Frame
					Case 0
						DrawImage bomb, X * 32, Y * 32, 0
					Case 1
						Local amap:ttile = MapArray[x , y]
						amap.UpdateBomb()
						DrawImage bomb, x * 32, y * 32, amap.BombFRame

				End Select
				
			Next
		Next
	End Function

	Function CreateBomb:ttile() 
		Local b:TTile = New TTile
		b.BombFRame = 0
		b.BombFrameTimer = MilliSecs() 
		Return b
		End Function
	
	Method UpdateBomb() 
		If MilliSecs() > BombFRameTimer + 200
			BombFrame:+1
			If BombFrame > 13 Then BombFrame = 0
			BombFrameTimer = MilliSecs() 
		End If
	End Method
	
	Function ActivateBomb() 
		If MapArray[MouseX() / 32, MouseY() / 32].Frame = 0
			If MouseHit(MOUSE_LEFT) 
				MapArray[MouseX() / 32, MouseY() / 32].Frame = 1
			End If
		End If
	End Function
End Type


TTile.PrefillMapArray

While Not KeyHit(KEY_ESCAPE) 
	Cls
		TTile.Draw
		TTile.ActivateBomb
	Flip
	
Wend



Czar Flavius(Posted 2007) [#11]
Can't you just create a global field for the current animation frame, and give each bomb and invidial "ticking"/"active" frame set to true or false?


Jesse(Posted 2007) [#12]
I commented out all of the "redundant" stuff. you don't need to create a list if you are storing the values in the arrays.



Amon(Posted 2007) [#13]
Hi Degac. Thanks for your help. Tha works perfectly.

What is this doing though?

						Local amap:ttile = MapArray[x , y]
						amap.UpdateBomb()
						DrawImage bomb, x * 32, y * 32, amap.BombFRame



degac(Posted 2007) [#14]
I could write
MapArray[x , y].UpdateBomb()
DrawImage bomb, x * 32, y * 32, MapArray[x , y].BombFRame


It was only for clear reading


Amon(Posted 2007) [#15]
Ahh!. That actually makes sense.

Thanks very much for your help. I really appreciate it. :)