fantomEngine, Why are my objects not updating?

Monkey Forums/Monkey Beginners/fantomEngine, Why are my objects not updating?

underdrummer(Posted 2014) [#1]
I am very new to Monkey X and fantomEngine so please be gentle.
I am making a simple game for HTML 5. I create some spider images objects and have them move across the screen. When a spider obj crosses a certain point on the X-axis I want each individual object to be removed. My code only removes the last object created. I probably need to use a list or something but I'm not sure how. Below is code from my spawnenemy method and the onobjectupdate methods

'SpawnEnemy Method
Method SpawnEnemy:ftObject()

'y = the highest Y pos lane first
Local y:Int = 102

'for loop to create a spider in each lane
For Local spawn:Int = 1 To 5

'spawn enemy in lanes 1 - 5

enemy = eng.CreateImage(atlas, 0, 0, 64, 64, -32, y)
enemy.SetLayer(layerGame)
enemy.SetRadius(10)
enemy.SetSpeedX(Rnd(0.5, 3))
enemy.SetColGroup(grpEnemy)
enemy.SetColWith(grpShot, True)
'raise spider count
spiderCount += 1
'raise Y pos 64 eachtime it loops
y += 64
'enemyArray[spawn] = enemy
Print("I SPAWNED AN ENEMY")

Next
Endif
Return enemy
End

'OnObjectUpdate Method
Method OnObjectUpdate:Int(obj:ftObject)
' This method is called when an object finishes its update

'when object equals enemy object
If obj = g.enemy Then
If obj.GetPosX() > 400 Then
g.lP -= 1
'increase # of spiders that made it through
g.spiderGotThroughCount += 1
obj.Remove()
Endif
Endif

What am I doing wrong here? Thanks.


MikeHart(Posted 2014) [#2]
Do you call the Update method or your engine instance? How does your OnUpdate method looks like.

please put your code next into code tags.
What is IP?

Another problem is that you only store the latest object inside your global enemy field. You shoudl give the object a tag or ID and check it against that. Then it should work. I will post a sample later. Need to go out.


underdrummer(Posted 2014) [#3]
Hi MikeHart,

Thanks for the reply. lP is lifePoints variable. I don't know how to assign tag or Id. Looking forward to an example.
I have posted my OnUpdate Method section that deals with the enemies. There are only enemies on the night screen.
Method OnUpdate:Int()
		
		' Determine the delta time and the update factor for the engine
		Local d:Float = Float(eng.CalcDeltaTime())/60.0
		
		If isSuspended = False Then
			Select gameMode
				'player is in the night screen
				Case gmPlayNight
					'play night background music (looping) 
					If playNightSound = True Then
						sndDayBackGround.Stop()
						sndNightBackGround.SetVolume(0.3)
						sndNightBackGround.Play(2)
						playNightSound = False
						playDaySound = True
					Endif
						
							
					
					
					'If TouchHit(0) Then
						'eng.TouchCheck(layerTitle)
					'Endif
					'collision check the game layer
					eng.CollisionCheck(layerGame)
					eng.Update(Float(d))
						'during play mode, allow player to exit wwith ESCAPE key
						If KeyHit(KEY_ESCAPE) Then
							'stop any music if playing
							sndNightBackGround.Stop()
							sndDayBackGround.Stop()
							g.layerDayBackGround.SetActive(False)   
						    g.layerNightBackGround.SetActive(False) 
						    g.layerGame.SetActive(False)           
							g.layerDirections.SetActive(False) 
						    g.layerTitle.SetActive(True) 
						    gameMode = gmMenu
						Endif
						'TESTING ONLY!
						'Print("MouseX: "+MouseX()+" MouseY: "+MouseY())
						
						If spidersRemaining <= 0 And lP > 0 Then
							
						
							'start a timer before fading out to day screen
							eng.CreateTimer(tmEndOfNightPause, 3000)
							If endOfNightPause = True Then
								'g.layerDirections.SetAlpha(0.0)
								'g.layerTitle.SetAlpha(0.0)
								g.layerGame.SetActive(False)           
								g.layerDirections.SetActive(False) 
							    g.layerTitle.SetActive(False) 
								'MAKES SCREEN FADE IN AND OUT
								'layer transition of 2000 milliseconds
								
								layerNightBackGround.CreateTransAlpha(0.01, 1000, False, tmFadeOutNight)
								
							Endif
							
						Endif
					UpdateInfoText()
...


Thanks.


underdrummer(Posted 2014) [#4]
HI MikeHart,
Still looking forward to a reply from you. I tried this per your suggestions but I guess I'm not doing it right.
SpawnEnemy Method...
For Local spawn:Int = 1 To 5
			
				'spawn enemy in lanes 1 - 5
					
					enemy = eng.CreateImage(atlas, 0, 0, 64, 64, -32, y)
					enemy.SetLayer(layerGame)
					enemy.SetRadius(10)
					enemy.SetSpeedX(Rnd(speedMin, speedMax))    'set this speed according to level
					enemy.SetColGroup(grpEnemy)
					enemy.SetColWith(grpShot, True)
					 
					enemyId += 1
					enemy.SetTag(enemyId)
					'raise spider count
					spiderCount += 1
					'raise Y pos 64 eachtime it loops
					y += 64
					'enemyArray[spawn] = enemy
					Print("I SPAWNED AN ENEMY and it's id is: "+enemy.GetTag())
					
			Next


OnObjectUpdate Method...
'when object equals enemy object
		If obj = g.enemy Then
			'loop through enemies 
			For Local loop:Int = 1 To g.spiderCount
				'check each ones X position and tag
				If obj.GetTag() = loop And obj.GetPosX() > 400 Then 
					
					g.lP -= 1
					'increase # of spiders that made it through
					g.spiderGotThroughCount += 1
					obj.Remove()
                               'Endif
			'Next
		'Endif


It still only updates the final enemy. ???


MikeHart(Posted 2014) [#5]
Sorry, was very busy. I will try later this day. Have to go to work now.


MikeHart(Posted 2014) [#6]
Sorry for the delay. But here you go. If you have questions, just ask. My preferred location would be the fantomEngine support forum.

Strict

#rem
	Script:			UpdateObjects.monkey
	Description:	Sample script to show how to update objects based on their category
	Author: 		Michael Hartlef
	Version:      	1.0
#End

' Set the AutoSuspend functionality to TRUE so OnResume/OnSuspend are called
#MOJO_AUTO_SUSPEND_ENABLED=True

' Import the fantomEngine framework which imports mojo itself
Import fantomEngine

' The _g variable holds an instance to the cGame class
Global _g:cGame

'***************************************
' The cGame class controls the app
Class cGame Extends App
	' Create a field to store the instance of the cEngine class, which is an instance
	' of the ftEngine class itself
	Field fE:cEngine
	
	' Define a constant for a timer	
	Const engineTimer:Int = 1
	
	' Define 2 constants to identify each type of object
	Const ENEMY:Int = 100
	Const FRIEND:Int = 101

	'------------------------------------------
	Method SpawnObject:Void()
		' Create a simple circle
		Local tmpObj := fE.CreateCircle(20,fE.GetCanvasWidth()-20,Rnd(20,fE.GetCanvasHeight()-20))
		' Give it a random speed facing left
		tmpObj.SetSpeed(Rnd(5,10),270)
		' Give it a random size
		tmpObj.SetScale(Rnd(0.2,1.0))
		' Now create a timer to spawn the next object
		fE.CreateTimer(engineTimer, Rnd(200,1000))
		
		' Tag the object with a 50% chance to be a FRIEND or an ENEMY, and give it a color.
		If Rnd(10)>5
			tmpObj.SetTag(ENEMY)
		Else
			tmpObj.SetTag(FRIEND)
			tmpObj.SetColor(255,0,255)
		Endif
	End
	'------------------------------------------
	Method OnCreate:Int()
		' Set the update rate of Mojo's OnUpdate events to be determined by the devices refresh rate.
		SetUpdateRate(60)
		
		' Create an instance of the fantomEngine, which was created via the cEngine class
		fE = New cEngine
		
		' Create a timer without a connection to an object which creates new circles at every second
		fE.CreateTimer(engineTimer, 500)
		
		' Create tweo lines to mark where each object type will be removed
		fE.CreateLine(20,0,20,fE.GetCanvasHeight())
		fE.CreateLine(200,0,200,fE.GetCanvasHeight())

		Return 0
	End
	'------------------------------------------
	Method OnUpdate:Int()
		' If the CLOSE key was hit, exit the app ... needed for GLFW and Android I think. 
		If KeyHit( KEY_CLOSE ) Then fE.ExitApp()
		
		' Determine the delta time and the update factor for the engine
		Local timeDelta:Float = Float(fE.CalcDeltaTime())/60.0

		' Update all objects of the engine
		If fE.GetPaused() = False Then
			fE.Update(timeDelta)
		Endif
		Return 0
	End
	'------------------------------------------
	Method OnRender:Int()
		' Check if the engine is not paused
		If fE.GetPaused() = False Then
			' Clear the screen 
			Cls 0,255,0
		
			' Render all visible objects of the engine
			fE.Render()
			' Draw some debugging info on the screen
			SetColor(255,255,0)
			DrawText("FPS: "+ fE.GetFPS(), 20,20)
			DrawText("ObjCount: "+ fE.GetObjCount(), 20,40)
			' Restore the current color of the engine
			fE.RestoreColor()
		Endif
		Return 0
	End
End	

'***************************************
' The cEngine class extends the ftEngine class to override the On... methods
Class cEngine Extends ftEngine
	Method OnObjectUpdate:Int(obj:ftObject)
		' This method is called when an object finishes its update. You can deactivate the event via ftObject.ActivateUpdateEvent.
		
		' Remove the enemy object depending on its tag and X-Position
		If obj.GetTag()=_g.ENEMY And obj.GetPosX() < 20
			obj.Remove()
		Endif
		' Remove the friend object depending on its tag and X-Position
		If obj.GetTag()=_g.FRIEND And obj.GetPosX() < 200
			obj.Remove()
		Endif
		Return 0
	End
    '------------------------------------------
	Method OnTimer:Int(timerId:Int)
		' This method is called when an engine timer was being fired.
		If timerId = _g.engineTimer
			_g.SpawnObject()
		Endif
		Return 0
	End	
End

'***************************************
Function Main:Int()
	' Create an instance of the cGame class and store it inside the global var 'g'
	_g = New cGame
	
	Return 0
End




MikeHart(Posted 2014) [#7]
The problem you had was that g.enemy online stores the last enemy object you have created. That is why your code only updates the last object. You need to identify an object via GetTag, GetID, GetName, GetColGroup, whatever... which you have set before. Or store it differently before.


underdrummer(Posted 2014) [#8]
MikeHart,

Awesome! It's working great now. I used obj.SetTag(ENEMY) like you suggested. Now my OnObjectUpdate updates EACH enemy. Thank you for your time.


MikeHart(Posted 2014) [#9]
No problem. :-)