Player screen transition to the wrong side of the screen

This has been driving me crazy for the past few days, and I cannot figure why it is happening. I commented the lines of code that kill you when you touch the bottom of the screen. I don't know if it has anything to do with that, especially because this only happens on certain screens. On these certain screens when I transition from an above screen to a below screen my player loads at the bottom of the screen, when it should be falling in from above. So some screens you jump down a hole and fall to the below screen properly, and other screens it does not work and the player ends up on the opposite side that it should be appearing. I've messed around with all kinds of things and have had no luck figuring out what exactly is causing it. Deleting and re-designing screens sometimes temporarily fixes it, but then it will end up happening on another screen. removing the HUD got rid of the bug completely but messed up all the graphics of the game really bad, so it might have to do with the HUD. I changed the HUD size around with no luck. My project is just at a stand still for a while until I can get the screens to transition properly.
 

dale_coop

Moderator
Staff member
Weird...
did you try reducing the speed of your player?
Or maybe you have a warp tile on your screen?
 
Oohhh, good idea about the changing the speed, I read in Joes comments in the Handle Bounds that the transitions has something to do with reading the speed. but it's still weird that it only happens on certain screens. It is not a warp tile, I actually tried to think of how to use warp tiles to avoid screen transitions if i couldnt fix the problem.
 
No luck, tried a few different speeds, and still the same thing. I think there is something funky going on in the Handle Bounds script, which is really really long and I don't think I should post it here, or the HUD because removing the HUD removed the transition bug, it just glitched out the graphics cuz I don't know how to properly remove the HUD.
 
Code:
HandleHorizontalBounds:
	LDA gameHandler
	BNE checkForHbounds
	RTS
checkForHbounds:

	LDY Object_type,x
	
	;; check, are we moving right or left?
	;LDA Object_movement,x
	;AND #%01000000
	LDA Object_h_speed_hi,x
	BMI checkLeftPosition
	;BEQ checkLeftPosition
	;; check right position

	LDA xHold_hi
	
	STA temp
	LDA #BOUNDS_RIGHT
	SEC
	SBC ObjectBboxLeft,y
	SEC
	SBC ObjectWidth,y
	CMP temp
	BCc RightBoundsReached
	JMP noBoundsReached
	
checkLeftPosition:
	;;;;
	LDA xHold_hi
	CLC
	ADC ObjectBboxLeft,y
	CLC
	ADC ObjectWidth,y
	STA temp
	LDA #BOUNDS_LEFT
	ADC ObjectBboxLeft,y
	CLC
	ADC ObjectWidth,y
	
	CMP temp
	BCS LeftBoundsReached
	JMP noBoundsReached
	;;;;;
gotHposition_BoundsCheck:
	
RightBoundsReached:
	
	CPX player1_object
	BEQ doScreenRightUpdate
	;; do screen edge action for monster
	JSR doMonsterAtEdge
	JMP noBoundsReached
doScreenRightUpdate:	
	LDA Object_status,x
	AND #%00000001 ;; is it hurt?
	BEQ playerIsNotHurtForRightUpdate
	JSR StopAtEdge
	JMP noBoundsReached
playerIsNotHurtForRightUpdate:
	JSR updateScreenRight
	JMP noBoundsReached
LeftBoundsReached:
	
	CPX player1_object
	BEQ doScreenLeftUpdate
	;; do screen edge action for monster
	JSR doMonsterAtEdge
	;JSR doMonsterAtEdge
	JMP noBoundsReached
doScreenLeftUpdate:
LDA Object_status,x
	AND #%00000001 ;; is it hurt?
	BEQ playerIsNotHurtForLeftUpdate
	JSR StopAtEdge
	JMP noBoundsReached
playerIsNotHurtForLeftUpdate:
	JSR updateScreenLeft
	JMP noBoundsReached
noBoundsReached:


	RTS
	

	
HandleVerticalBounds:
	LDA gameHandler
	BNE checkForVbounds
	RTS
checkForVbounds:
	LDY Object_type,x
	
	;; check, are we moving up or down?
	;LDA Object_movement,x
	;AND #%00110000
	;CMP #%00100000
;; WHERE A TOP DOWN GAME CHECKS MOVEMENT BITS TO SEE WHAT IT SHOULD DO AT THE V EDGE
;;;A PLATFORM GAME CHECKS THE VSPEED
	LDA Object_v_speed_hi,x
	BMI checkTopPosition
	;; check bottom position
	LDA yHold_hi
	
	STA temp
	LDA #BOUNDS_BOTTOM
	SEC
	SBC ObjectBboxTop,y
	SEC
	SBC ObjectHeight,y
	CMP temp
	BCc BottomBoundsReached
	JMP noBoundsReachedv
	
checkTopPosition:
	;;;;
	LDA yHold_hi
	CLC
	ADC ObjectBboxTop,y
	CLC
	ADC ObjectHeight,y
	STA temp
	LDA #BOUNDS_TOP
	ADC ObjectBboxTop,y
	CLC
	ADC ObjectHeight,y
	CLC
	CMP temp
	BCS TopBoundsReached
	LDA #$00
	STA temp
	JMP noBoundsReachedv
	;;;;;
	
BottomBoundsReached:

	LDA Object_type,x
	CMP #$08 ;; is it death?
	BNE notDeathObjectAtScreenBottom
	LDA #STATE_START_GAME
	STA change_state
	LDA #$00
	STA DrawHudBytes
	
	JMP noBoundsReachedv
notDeathObjectAtScreenBottom:
	CPX player1_object
	BEQ doScreenBottomUpdate
	;; do screen edge action for monster
	JSR doMonsterAtEdge
	JMP noBoundsReachedv
doScreenBottomUpdate:	
	;;;;;;;;;;;;;;; THIS IS A PLAYER
	;;;;;;;;;;;;;;; AT THE BOTTOM OF THE SCREEN.
	;;;;;;;;;;;;;;; IF YOU WANT HIM TO GO TO THE NEXT SCREEN DOWN, LIKE MEGAMAN
	;;;;;;;;;;;;;;; COMMENT OUT EVERYTHING UNTIL changeMapScreenDown
	;;;;;;;;;;;;;;; THIS CODE WILL CAUSE PLAYER DEATH AT BOTTOM OF SCREEN
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;JSR HandlePlayerDeath
		
		;RTS
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;; IF YOU WANT BOTTOM OF THE SCREEN TO BE DEATH, ALL BELOW CODE WILL NEVER BE REACHED
	;;;;; IF YOU WANT BELOW CODE TO BE REACHED, COMMENT OUT THE ABOVE LINES
changeMapScreenDown:
	LDA Object_status,x
	AND #%00000001 ;; is it hurt?
	BEQ playerIsNotHurtForBottomUpdate
	JSR StopAtEdge
	JMP noBoundsReachedv
playerIsNotHurtForBottomUpdate:
	JSR updateScreenBottom
	JMP noBoundsReachedv
TopBoundsReached:
	CPX player1_object
	BEQ doScreenTopUpdate
	;; do screen edge action for monster
	JSR doMonsterAtEdge
	;JSR doMonsterAtEdge
	JMP noBoundsReachedv
doScreenTopUpdate:
	LDA Object_status,x
	AND #%00000001 ;; is it hurt?
	BEQ playerIsNotHurtForTopUpdate
	JSR StopAtEdge
	JMP noBoundsReachedv
playerIsNotHurtForTopUpdate:
	
	;;;; TO USE TOP AS A BOUNDARY, UNCOMMENT THESE LINES
	;;; == TOP IS A BOUNDARY
	;LDA #$00
	;STA Object_v_speed_hi,x
	;STA Object_v_speed_lo,x
	;LDA #$02
	;STA temp
	;RTS
	;;;;=======END TOP IS A BOUNDARY
	;;;;; TO USE TOP BOUNDS TO GO TO ABOVE MAP SCREEN, COMMENT OUT ABOVE AND UNCOMMENT THESE LINES
	;;;== TOP LEADS TO ABOVE MAP SCREEN
	JSR updateScreenTop
	LDA #$01
	STA temp
	rts
	;;;;====== END TOP LEADS TO ABOVE MAP SCREEN.
noBoundsReachedv:
	LDA #$00
	STA temp
	RTS
	
	
	
	
	
	
	
	
	
	
	
doMonsterAtEdge:
	LDA Object_status,x
	ORA #%00000100 ;; on edge.
	STA Object_status,x
	LDA Object_status,x
	AND #%00000001
	BEQ doNormalMonsterEdgeSolidAction
	JSR StopAtEdge
	rts
doNormalMonsterEdgeSolidAction:
	
	JSR StopAtEdge
	LDA Object_edge_action,x
	AND #%00001111
	BEQ doNothingAtEdge
	STA temp
	LDA currentBank
	STA prevBank
	LDY #DATABANK1
	JSR bankswitchY
	
	LDY temp
	LDA AI_ReactionTable_Lo,y
	STA temp16
	LDA AI_ReactionTable_Hi,y
	STA temp16+1
	

	
	JSR doReactionTrampoline
	JMP pastReactionTrampoline
doReactionTrampoline:
	JMP (temp16) ;;; this now does the action
			;; and when it hits the RTS in that action,
			;; it will jump back to the last JSR it saw,
			;; which was doNewActionTrampoline...which will immediately
			;; jump to pastDoNewActionTrampoline.
pastReactionTrampoline:
	
	LDY prevBank
	JSR bankswitchY
doNothingAtEdge:
	RTS
	

StopAtEdge:
	LDA yPrev
	STA Object_y_hi,x
	STA yHold_hi
	LDA #$00
	STA Object_y_lo,x
	STA yHold_lo
	
	LDA xPrev
	STA Object_x_hi,x
	STA xHold_hi
	LDA #$00
	STA Object_x_lo,x
	STA xHold_lo
	
	STA Object_h_speed_hi,x
	STA Object_h_speed_lo,x
	STA Object_v_speed_hi,x
	STA Object_v_speed_lo,x
	
	LDA Object_movement,x
	AND #%00001111
	STA Object_movement,x
	RTS
	
	
	
	
	
	
updateScreenRight
	
	;;; check if side triggers change screen...for instance, if hurt, wouldn't, and would instead return *solid*
	LDA #BOUNDS_LEFT
	CLC
	ADC #$8
	
	STA xHold_hi
	STA newX
	LDA #$00
	STA xHold_lo
	
	LDA Object_y_hi,x
	STA newY
	LDA #$00
	STA Object_y_lo,x
	
	LDA #%11000000
				;7 = active
				;6 = 8 or 16 px tiles
			ORA #GS_MainGame
			ORA #%01000000
			STA update_screen
			LDA #%00000001
			STA update_screen_details ;; load from map 1
			LDA currentScreen
			ADC #$01
			STA newScreen
			STA currentScreen
			LSR
			LSR
			LSR
			LSR
			LSR
			STA screenBank
			LDA #$01
			STA screen_transition_type
	LDA #$01
	STA tile_solidity
	LDA #$00
	STA gameHandler
doneWithUpdateRightScreen:
	rts
	
	
updateScreenLeft:	

	LDA #BOUNDS_RIGHT
	SEC
	SBC ObjectWidth,y
	SEC
	SBC ObjectBboxLeft,y
	SEC 
	SBC #$8
	CLC 
	ADC Object_h_speed_hi,x
	STA xHold_hi
	STA newX
	LDA #$00
	STA xHold_lo
	
	LDA Object_y_hi,x
	STA newY
	LDA #$00
	STA Object_y_lo,x
	
	LDA #%11000000
				;7 = active
				;6 = 8 or 16 px tiles
			ORA #GS_MainGame
			ORA #%01000000
			STA update_screen
			LDA #%00000001
			STA update_screen_details ;; load from map 1
			LDA currentScreen
		
			SEC
			SBC #$01
			STA newScreen
			STA currentScreen
			LSR
			LSR
			LSR
			LSR
			LSR
			STA screenBank
			LDA #$01
			STA screen_transition_type
	LDA #$01
	STA tile_solidity
		LDA #$00
	STA gameHandler
	RTS
	

updateScreenBottom:
	
	LDA #BOUNDS_TOP
	STA yHold_hi
	STA newY
	LDA #$00
	STA yHold_lo
	
	LDA Object_x_hi,x
	STA newX
	
	LDA #%11000000
				;7 = active
				;6 = 8 or 16 px tiles
			ORA #GS_MainGame
			ORA #%01000000
			STA update_screen
			LDA #%00000001
			STA update_screen_details ;; load from map 1
			LDA currentScreen
			ADC #$0F
			STA newScreen
			STA currentScreen
			LSR
			LSR
			LSR
			LSR
			LSR
			STA screenBank
			LDA #$01
			STA screen_transition_type
	LDA #$01
	STA tile_solidity		
	LDA #$00
	STA gameHandler
	rts

updateScreenTop:
	
	LDA #BOUNDS_BOTTOM
	SEC
	SBC ObjectHeight,y
	SEC
	SBC ObjectBboxTop,y
	SEC 
	SBC #$08
	
	STA yHold_hi
	STA newY
	;;; probably because of the jump speed, we need to force the y to be this as well
	;; for platforming.
	STA Object_y_hi,x
	LDA #$00
	STA yHold_lo
	
	LDA Object_x_hi,x
	STA newX
	
	
	LDA #%11000000
				;7 = active
				;6 = 8 or 16 px tiles
			ORA #GS_MainGame
			ORA #%01000000
			STA update_screen
			LDA #%00000001
			STA update_screen_details ;; load from map 1
			LDA currentScreen
			SEC
			SBC #$10
			STA newScreen
			STA currentScreen
			LSR
			LSR
			LSR
			LSR
			LSR
			STA screenBank
			LDA #$01
			STA screen_transition_type
	;LDA #$00
	;STA tile_solidity
	LDA #$00
	STA gameHandler
	RTS
topBoundsNotReached:
	RTS
 

dale_coop

Moderator
Staff member
What did you comment on the script?
Just these 2 lines:
Code:
		;;JSR HandlePlayerDeath
		
		;;RTS
On another part of the scripts?
 
and this
Code:
;;;; TO USE TOP AS A BOUNDARY, UNCOMMENT THESE LINES
	;;; == TOP IS A BOUNDARY
	;LDA #$00
	;STA Object_v_speed_hi,x
	;STA Object_v_speed_lo,x
	;LDA #$02
	;STA temp
	;RTS
	;;;;=======END TOP IS A BOUNDARY
	;;;;; TO USE TOP BOUNDS TO GO TO ABOVE MAP SCREEN, COMMENT OUT ABOVE AND UNCOMMENT THESE LINES
	;;;== TOP LEADS TO ABOVE MAP SCREEN
 
ok, I just tried something weird , I removed some solid blocks that were along the edges of the screen and the player is now loading on the correct side of the screen, I don't see why blocks around the edge of the screen would change where the player spawns. that is weird.
 
I think I just want the HUD removed without messing up all the graphics, that seems to fix it. I can put the death counter in a game over screen.
 

dale_coop

Moderator
Staff member
Ok so it might be related to that issue:
http://nesmakers.com/viewtopic.php?f=19&t=429
Maybe ?

The collision data of the first tile on the new screen loaded is wrong (the engine use the old screen data, instead of the new screen, so your player hurt the solid
Tiles that was at the exact same place, but on the previous screen).
I don’t know when/if this issue will be fix.
 
hmmm, yea, it looks related, but different in a way. death blocks do not seem to affect the problem , I removed the solids that seems to be causing the problem and replaced with Null tiles, player spawns at the top of the screen, put death blocks in the same place and no difference, put the solids back in place and the player transitions to the bottom instead of the top. Is this a bug in NESMaker?
 

dale_coop

Moderator
Staff member
The problem is not death tile in particular... it’s any bloc on the side of the screen.
The engine test the wrong screen for the collision (only the first tile when the player comes in a new screen).

(I just discovered the problem when I was using a death tile)
 

jorotroid

Member
I've been having this trouble, too. Your discovery is helpful. I'm going to dive into the code and see if I can move the placement of the player to occur after the screen collision data has been updated. I'll be back if I find anything useful.
 
Currently I'm just working around it with screen design, I made some null walkable tiles that look the same as the solid tiles and just making sure you cant actually get to those tiles, they are just for looks, the solid tiles at the edge are causing this somehow. Eventually when pause screens are available I will probably just go No HUD, and put all that HUD stuff into the pause menu. Joe said we may have to re-build our projects from the ground up eventually at some point anyways, so it's not a big deal just yet, I'm just seeing what I can play around with for the time being.
 

dale_coop

Moderator
Staff member
This is related to this problem:
http://nesmakers.com/viewtopic.php?p=5523#p5523

Whenre a new screen is loaded (after the transition, the collision data used to check the first tile is not the good one (the engine use the previous screen data, instead of the nex one).
 
Yeah, I saw that. Do you think Joe is working on any fix for it? Or is it something we're going to have to deal with ourselves?
 

dale_coop

Moderator
Staff member
I don't know if he's working on that bug, or if he already fixed it...
I think we will see with the next update.
Else we will have to dig in and try to find a fix ourselves ;)
 
Top Bottom