CreateObject is glitching everything out [4.5.6]

LOKIOLR

New member
I've been trying to put together a system to randomly spawn monsters from my screen's monster group on a given time delay. I've setup a timer script to increment a timer about once a second until it reaches the spawn delay (1 second for testing currently). Once that happens it calls a subroutine that randomly selects one of the 4 monsters from the group, randomly picks an edge to spawn on, and randomly selects a position on that edge to spawn. It was checking for solid tiles on the edge and if it fails that check it proceeds again with the whole process the next time the spawn timer reaches the delay. So far not much of anything has worked. I wasn't getting anything to spawn so I've walked back my code to skip the random portion of the script and manually create an object in a specific location. Now, when that happens I get the following below.

[media]https://imgur.com/a/WNndYgK[/media]

I've used CreateObject before in the tutorials and I don't remember this being such a hassle. I've been banging my head against the wall try to figure out what is causing the issue, and what would be a better way to do what I need if this is wrong. I'm assuming it could be too much code to throw into a timer loop, but I don't know.

Timer script
Code:
+UpdateSecondsTimer
	INC secondsTimer
	LDA secondsTimer
	CMP #$3C ;60 frames?
	BNE +skipSpawnTimer
		INC spawnTimer
		LDA #$00
		STA secondsTimer
	+skipSpawnTimer

+UpdateP1CooldownTimer
	LDA P1Timer ;Player 1 Poop Cooldown
	CMP #$00
	BEQ +skipP1Timer
		DEC P1Timer
	+skipP1Timer

+UpdateP2CooldownTimer	
	LDA P2Timer ;Player 2 Poop Cooldown
	CMP #$00
	BEQ +skipP2
		DEC P2Timer
	+skipP2

+UpdateMonsterSpeed
	LDA spawnCount
	CMP userScreenByte3 ;Compare to number of spawns needed until monster speed increase.
	BNE +skipSpeedUpdate
		LDA currentMonsterSpeed ; Current Monster Speed
		CMP userScreenByte2 ; Max Monster Speed
		BEQ +skipMonsterSpeedIncrease ;If current monster speed hasn't hit the max yet, increase.
			INC currentMonsterSpeed ;Increase current Monster Speed
		+skipMonsterSpeedIncrease
		LDA #$00 ;reset spawn count
		STA spawnCount
	+skipSpeedUpdate
+SpawnTimerCheck
	
	
	

+SpawnTimerExpired
	LDA userScreenByte4
	STA tempA
	LDA spawnTimer
	CMP tempA
	BNE +
		JMP +DoSomeSpawning
	+
	JMP +TheVeryEnd
	
+DoSomeSpawning
	
	
	JSR doRandomEdgeSpawn
	
	;LDA #$06
	;STA spawnTimer
	;CountObjects #%00001000
	
	
	;CMP #MAX_MOB_CAP
	;BNE +	
	;	RTS
	
	;DoRandomEdgeSpawn

+TheVeryEnd


doRandomEdgeSpawn (bit of a mess because of testing at the moment)
Code:
doRandomEdgeSpawn:
;;Timer will run check if OK to spawn enemy.
;;This macro will do the actual spawn logic.

;picks a monster from loaded monster group
	STX tempx
	STY tempy
	LDA #$00
	TAX
	JSR doGetRandomNumber
	AND #%00000011 ;pick random number 0-3
	BNE +notMonster1
	;monster1
	LDA mon1_type
	STA ObjectToLoad
	JMP +PickEdgeToSpawn
	
+notMonster1
	CMP #$01
	BNE +notMonster2
	;monster2
	LDA mon2_type
	STA ObjectToLoad
	JMP +PickEdgeToSpawn

+notMonster2
	CMP #$02
	BNE +notMonster3
	;monster3
	LDA mon3_type
	STA ObjectToLoad
	JMP +PickEdgeToSpawn

+notMonster3
	;monster4
	LDA mon4_type
	STA ObjectToLoad

+PickEdgeToSpawn
		
	
	
	STA tempA
	;JSR doGetRandomNumber
	;AND #%00000011 ;pick random number 0-3
	;; this will determine which side to spawn on: bottom, right, top, left
	LDA #$02
	
	BNE +notDownForEdgeSpawn
	
	;; Bottom Edge Spawn
	LDA #$DE ;224 pixels Y ( 2 pixel offset of Y max)
	STA tileY
	STA spawnY
	JMP findFreeSpawnPosLoopX ;Pick random position along bottom of the screen
		
	STA tileX
	STA spawnX
	;JSR GetAttributePosition ;Get tile attribute at X,Y coordinates
	JSR GetTileAtPosition ;Get tile at X,Y coordinates
	LDA collisionTable,y ;Check tile type
	CMP #$01 ;is the tile solid?
	BEQ + ;Can't spawn into solid, skip spawning for this frame.
		JMP +doRandomSpawnFacingUp ;Location OK to Spawn Monster
	+
	JMP +doneSpawningRoutine
	
+notDownForEdgeSpawn
	
	CMP #$01
	BNE +notRightForEdgeSpawn
	
	;; Right Edge Spawn
	LDA #$E8 ;232 pixels x (8 pixel offset from x max)
	STA tileX
	STA spawnX
	JMP findFreeSpawnPosLoopY
	
	STA tileY
	STA spawnY
	;JSR GetAttributePosition ;Get tile attribute at X,Y coordinates
	JSR GetTileAtPosition ;Get tile at X,Y coordinates
	LDA collisionTable,y ;Check tile type
	CMP #$01 ;is the tile solid?
	BEQ +
		JMP +doRandomSpawnFacingLeft ;Location OK to Spawn Monster
	+
	JMP +doneSpawningRoutine ;Can't spawn into solid, skip spawning for this frame.
	

+notRightForEdgeSpawn	
	
	CMP #$02
	BNE +notUpForEdgeSpawn
	
	;; Top Edge Spawn
	;LDA #$2E ;46 pixels ( 2 pixel offset from bottom of top tile in playfield)
	;LDA #$60
	;STA tileY
	;STA spawnY
	;JMP findFreeSpawnPosLoopX ;Pick random position along bottom of the screen
		
	;STA tileX
	;STA spawnX
	;JSR GetAttributePosition ;Get tile attribute at X,Y coordinates
	;JSR GetTileAtPosition ;Get tile at X,Y coordinates
	;LDA collisionTable,y ;Check tile type
	;CMP #$01 ;is the tile solid?
	;BEQ +
	;	JMP +doRandomSpawnFacingDown ;Location OK to Spawn Monster
	;+
	LDA #$00
	STA spawnTimer
	CreateObject #$60, #$60, #$17, #$00;, currentNametable
	;AddValue #$03, trappedCount, #$01, #$00
	;UpdateHudElement #$07
	JMP +doneSpawningRoutine ;Can't spawn into solid, skip spawning for this frame.
	

+notUpForEdgeSpawn

	;; Right Edge Spawn
	LDA #$08 ;8 pixels x (8 pixel offset from x min)
	STA tileX
	STA spawnX
	JMP findFreeSpawnPosLoopY
	
	STA tileY
	STA spawnY
	;JSR GetAttributePosition ;Get tile attribute at X,Y coordinates
	JSR GetTileAtPosition ;Get tile at X,Y coordinates
	LDA collisionTable,y ;Check tile type
	CMP #$01 ;is the tile solid?
	BEQ +
		JMP +doRandomSpawnFacingRight ;Location OK to Spawn Monster
	+
	JMP +doneSpawningRoutine ;Can't spawn into solid, skip spawning for this frame.
	


findFreeSpawnPosLoopX:
	
	JSR doGetRandomNumber
	AND #%11110000 ;; get the high 16 bits of random number. Select Random value between 0 - 240
	STA tileX
	ADC #$08 ; offset into middle of tile.
	STA spawnX
	RTS
findFreeSpawnPosLoopY:
	JSR doGetRandomNumber
	AND #%11110000 ;; get the high 16 bits of random number. Select Random value between 0 - 240
	CMP #$F0
	BCS +
		JMP +doneSpawningRoutine
	+
	ADC #$08 ; offset into tile.
	STA temp
	RTS

+doRandomSpawnFacingUp
	
	
	CreateObject spawnX, spawnY, ObjectToLoad, #$00
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	;created object returns spawned object in x
	LDA #$01 ; setting direction to up in monster movement script.
	STA Object_health,x ;object health to toggle direction of movement in Action 0 script.
	LDA userScreenByte5
	STA ObjectMaxSpeed,x
	LDA #$00 ;Reset spawn timer
	STA spawnTimer
	INC spawnCount
	
	JMP +doneSpawningRoutine
+doRandomSpawnFacingLeft
		
	CreateObject spawnX, spawnY, ObjectToLoad, #$00
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	;created object returns spawned object in x
	LDA #$02 ; setting direction to left in monster movement script.
	STA Object_health,x ;object health to toggle direction of movement in Action 0 script.
		
	LDA userScreenByte5
	STA ObjectMaxSpeed,x
	
	LDA #$00 ;Reset spawn timer
	STA spawnTimer
	INC spawnCount
	
	JMP +doneSpawningRoutine
+doRandomSpawnFacingDown
	AddValue #$03, trappedCount, #$01, #$00
	UpdateHudElement #$07
	
	CreateObject spawnX, spawnY, ObjectToLoad, #$00
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	;created object returns spawned object in x
	LDA #$03 ; setting direction to down in monster movement script.
	STA Object_health,x ;object health to toggle direction of movement in Action 0 script.
	
	
	
	LDA userScreenByte5
	STA ObjectMaxSpeed,x
	
	LDA #$00 ;Reset spawn timer
	STA spawnTimer
	INC spawnCount
	
	JMP +doneSpawningRoutine
+doRandomSpawnFacingRight
	AddValue #$03, trappedCount, #$01, #$00
	UpdateHudElement #$07
	
	CreateObject spawnX, spawnY, ObjectToLoad, #$00
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	;created object returns spawned object in x
	LDA #$04 ; setting direction to right in monster movement script.
	STA Object_health,x ;object health to toggle direction of movement in Action 0 script.
	LDA userScreenByte5
	STA ObjectMaxSpeed,x
	LDA #$00 ;Reset spawn timer
	STA spawnTimer
	INC spawnCount
	
+doneSpawningRoutine
	LDX tempx
	LDY tempy
	RTS
 

LOKIOLR

New member
Switched out CreateObject with CreateObjectOnScreen, added a check to get the current screen, and it's not crashing anymore...so far. So is there something I'm missing with CreateObject that would cause these issues?
 

Pauldalyjr

Active member
I unfortunately have no valuable input on this but lol at "poop cooldown"

Only think I could recommend is tracing the logic backwards on createobject and createobjectonscreen and see what differences are between the two
 

TakuikaNinja

Active member
CreateObject and CreateObjectOnScreen aren't even that different anyway, have a look:
CreateObject:
Code:
MACRO CreateObject arg0, arg1, arg2, arg3
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	JSR FindFreeObjectSlot
	CPX #$FF
	BNE +CreateThisObject
	JMP +NoFreeSpaces
+CreateThisObject:
	
	LDA arg0
	STA arg0_hold
	LDA arg1
	STA arg1_hold
	LDA arg2
	STA arg2_hold
	LDA arg3
	STA arg3_hold
	
	
	TYA
	PHA
	LDA currentNametable
	STA Object_screen,x
	JSR doCreateObject
	
	PLA
	TAY
+NoFreeSpaces:
	ENDM

CreateObjectOnScreen:
Code:
MACRO CreateObjectOnScreen arg0, arg1, arg2, arg3, arg4
	;; arg0 = x
	;; arg1 = y
	;; arg2 = object
	;; arg3 = beginning state
	;; arg4 = what screen do youw ant to create this object on?
	JSR FindFreeObjectSlot
	CPX #$FF
	BNE +CreateThisObject
	JMP +NoFreeSpaces
+CreateThisObject:
	
	LDA arg0
	STA arg0_hold
	LDA arg1
	STA arg1_hold
	LDA arg2
	STA arg2_hold
	LDA arg3
	STA arg3_hold
	LDA arg4
	STA Object_screen,x
	
	TYA
	PHA
	
	JSR doCreateObject
	
	PLA
	TAY
+NoFreeSpaces:
	ENDM

I'm stumped as well; if using CreateObjectOnScreen with currentNametable as arg4 works fine, why doesn't CreateObject work??
By the way, the TYA, PHA, PLA and TAY instructions are pointless as doCreateObject never uses the Y register in the first place.
 
Top Bottom