Prize tile not always dissappearing [4.5.9]

m8si

Active member
Prize tiles work well most of the time but sometimes I get this bug when the tile stays on the screen. However I think the collision is removed correctly because the prize cannot be collected after it's bugged.

I'm using LR_Platformer module.



Code is pretty straightforward:

;;; prize tile LDA updateScreenData AND #%00000100 BEQ +doScript RTS +doScript LDA scrollOffsetCounter BEQ +doIt RTS +doIt CPX player1_object BEQ +isPlayer JMP +notPlayer +isPlayer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BELOW WILL CHANGE TILE AT COLLISION. ; arg0 = metatile to change into ; arg1 = collision to change into. ChangeTileAtCollision #$00, #$00 INC myPrizes UpdateHudElement #$01 PlaySound #sfx_note +notPlayer
 

m8si

Active member
Ok... I can confirm that the collision changes to the right value. But sprite randomly ceases to change. Does anybody have a clue what might be happening here?


Maybe it has something to do with ChangeTileAtCollision?


Code:
MACRO ChangeTileAtCollision arg0, arg1
    ; arg0 = metatile to change into
    ; arg1 = collision to change into.
    LDY temp1
    LDA temp2
    BEQ +isEvenCt
        ;; is an odd ct, so looking in collisionTable2
        LDA arg1
        STA collisionTable2,y
        JMP +doneWithTileUpdate
    +isEvenCt
        LDA arg1
        STA collisionTable,y
        
    +doneWithTileUpdate

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
;;;; This part will actually update the tile with tile 0 in the tile set.
;;; ys is carried over from above.

;;; GET THE HIGH BYTE OF THE TILE TO CHANGE
    LDA temp2
    BEQ +isEvenNt
        ;; is odd nt
        LDA #$24
        JMP +gotNt
    +isEvenNt
        ;; is even nt
        LDA #$20
    +gotNt
        STA temp1
;;; GET THE LOW BYTE OF THE TILE TO CHANGE
        TYA
        STA temp
        LSR
        LSR
        LSR
        LSR
        LSR
        LSR
        clc
        ADC temp1
        STA temp2 ;;;temp16+1
        TYA
        AND #%11110000
        ASL
        ASL
        STA tempz
        TYA
        AND #%00001111
        ASL
        ORA tempz
        STA temp3 ;temp16
        
;;; SET THE TILE NUMBER TO CHANGE TO.   
    LDA arg0 ;; the tile to change.
            ;;; this is in tiles, so if you wanted the second "metatile",
            ;;; use 2, not 1.  If you wanted the tile in the next row,
            ;;; use #$20, not #$10.  Etc.
    STA tempA
    CLC
    ADC #$01
    STA tempB
    CLC
    ADC #$0F
    STA tempC
    CLC
    ADC #$01
    STA tempD
    
    
    LDY #$00
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        STA scrollUpdateRam,y
        INY
        LDA tempA
        STA scrollUpdateRam,y
        INY
        
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        CLC
        ADC #$01
        STA scrollUpdateRam,y
        INY
        LDA tempB
        STA scrollUpdateRam,y
        INY
        
            LDA temp3
            CLC
            ADC #$20
            STA temp3
            LDA temp2
            ADC #$00
            STA temp2
        
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        STA scrollUpdateRam,y
        INY
        LDA tempC
        STA scrollUpdateRam,y
        INY
        
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        CLC
        ADC #$01
        STA scrollUpdateRam,y
        INY
        LDA tempD
        STA scrollUpdateRam,y
        INY
    
    TYA
    STA maxScrollOffsetCounter
    
    
            
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Turn on update screen on next frame.
        LDA updateScreenData
        ORA #%0000100
        STA updateScreenData
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    
    
    ENDM
 

mouse spirit

Well-known member
I know that ive had that issue in nonscrolling 4.1.5. I think sometimes you are hitting 2 tiles, or you and an enemy are.
And since nesmaker doesnt handle collisions in the best way,that may be why.
But yes, it may have to do with the macro itself.

My example was mostly when shooting a projectile that interacted with some background tiles.
My tiles would turn from lava to ice.BUT sometimes the image would NOT change,even though the tile actually changed.
BUT also sometimes it completely missed the tile,and i could shoot again and change it.

Could be the speed in which youre interacting or changing stuff too. Like player speed.
Or the macro, or nesmaker's way of handling collisions or even/odd screens.
Could be you hitbox size...

Sounds like im no help,just wanted to give my input and bump this.

EDIT: Is it ever the same tile?
Try moving that tile to a different spot. Like 1 spot down and 1 spot right.

If i could play the demo and test,i could atleast see when its happening.
 

TolerantX

Active member
I know that ive had that issue in nonscrolling 4.1.5. I think sometimes you are hitting 2 tiles, or you and an enemy are.
And since nesmaker doesnt handle collisions in the best way,that may be why.
But yes, it may have to do with the macro itself.

My example was mostly when shooting a projectile that interacted with some background tiles.
My tiles would turn from lava to ice.BUT sometimes the image would NOT change,even though the tile actually changed.
BUT also sometimes it completely missed the tile,and i could shoot again and change it.

Could be the speed in which youre interacting or changing stuff too. Like player speed.
Or the macro, or nesmaker's way of handling collisions or even/odd screens.
Could be you hitbox size...

Sounds like im no help,just wanted to give my input and bump this.

EDIT: Is it ever the same tile?
Try moving that tile to a different spot. Like 1 spot down and 1 spot right.

If i could play the demo and test,i could atleast see when its happeni
Ok... I can confirm that the collision changes to the right value. But sprite randomly ceases to change. Does anybody have a clue what might be happening here?


Maybe it has something to do with ChangeTileAtCollision?


Code:
MACRO ChangeTileAtCollision arg0, arg1
    ; arg0 = metatile to change into
    ; arg1 = collision to change into.
    LDY temp1
    LDA temp2
    BEQ +isEvenCt
        ;; is an odd ct, so looking in collisionTable2
        LDA arg1
        STA collisionTable2,y
        JMP +doneWithTileUpdate
    +isEvenCt
        LDA arg1
        STA collisionTable,y
      
    +doneWithTileUpdate

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;;; This part will actually update the tile with tile 0 in the tile set.
;;; ys is carried over from above.

;;; GET THE HIGH BYTE OF THE TILE TO CHANGE
    LDA temp2
    BEQ +isEvenNt
        ;; is odd nt
        LDA #$24
        JMP +gotNt
    +isEvenNt
        ;; is even nt
        LDA #$20
    +gotNt
        STA temp1
;;; GET THE LOW BYTE OF THE TILE TO CHANGE
        TYA
        STA temp
        LSR
        LSR
        LSR
        LSR
        LSR
        LSR
        clc
        ADC temp1
        STA temp2 ;;;temp16+1
        TYA
        AND #%11110000
        ASL
        ASL
        STA tempz
        TYA
        AND #%00001111
        ASL
        ORA tempz
        STA temp3 ;temp16
      
;;; SET THE TILE NUMBER TO CHANGE TO. 
    LDA arg0 ;; the tile to change.
            ;;; this is in tiles, so if you wanted the second "metatile",
            ;;; use 2, not 1.  If you wanted the tile in the next row,
            ;;; use #$20, not #$10.  Etc.
    STA tempA
    CLC
    ADC #$01
    STA tempB
    CLC
    ADC #$0F
    STA tempC
    CLC
    ADC #$01
    STA tempD
  
  
    LDY #$00
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        STA scrollUpdateRam,y
        INY
        LDA tempA
        STA scrollUpdateRam,y
        INY
      
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        CLC
        ADC #$01
        STA scrollUpdateRam,y
        INY
        LDA tempB
        STA scrollUpdateRam,y
        INY
      
            LDA temp3
            CLC
            ADC #$20
            STA temp3
            LDA temp2
            ADC #$00
            STA temp2
      
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        STA scrollUpdateRam,y
        INY
        LDA tempC
        STA scrollUpdateRam,y
        INY
      
        LDA temp2
        STA scrollUpdateRam,y
        INY
        LDA temp3
        CLC
        ADC #$01
        STA scrollUpdateRam,y
        INY
        LDA tempD
        STA scrollUpdateRam,y
        INY
  
    TYA
    STA maxScrollOffsetCounter
  
  
          
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Turn on update screen on next frame.
        LDA updateScreenData
        ORA #%0000100
        STA updateScreenData
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  
  
    ENDM

Prize tiles work well most of the time but sometimes I get this bug when the tile stays on the screen. However I think the collision is removed correctly because the prize cannot be collected after it's bugged.

I'm using LR_Platformer module.



Code is pretty straightforward:

;;; prize tile LDA updateScreenData AND #%00000100 BEQ +doScript RTS +doScript LDA scrollOffsetCounter BEQ +doIt RTS +doIt CPX player1_object BEQ +isPlayer JMP +notPlayer +isPlayer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BELOW WILL CHANGE TILE AT COLLISION. ; arg0 = metatile to change into ; arg1 = collision to change into. ChangeTileAtCollision #$00, #$00 INC myPrizes UpdateHudElement #$01 PlaySound #sfx_note +notPlayer
Did you try putting "ChangeTileAtCollision , #$00, #$00" at the beginning of the script and remove the change at the end of the script and see how that goes?
 

m8si

Active member
I know that ive had that issue in nonscrolling 4.1.5. I think sometimes you are hitting 2 tiles, or you and an enemy are.
And since nesmaker doesnt handle collisions in the best way,that may be why.
But yes, it may have to do with the macro itself.

My example was mostly when shooting a projectile that interacted with some background tiles.
My tiles would turn from lava to ice.BUT sometimes the image would NOT change,even though the tile actually changed.
BUT also sometimes it completely missed the tile,and i could shoot again and change it.

Could be the speed in which youre interacting or changing stuff too. Like player speed.
Or the macro, or nesmaker's way of handling collisions or even/odd screens.
Could be you hitbox size...

Sounds like im no help,just wanted to give my input and bump this.

EDIT: Is it ever the same tile?
Try moving that tile to a different spot. Like 1 spot down and 1 spot right.

If i could play the demo and test,i could atleast see when its happening.
Thanks! I tried to change all the values as you suggested but it didn't help.

Here is the game so far. It is still a work in progress with some bugs here and there. Despite the bugs it is quite playable though at least until the boss on level 2 which is invincible. xD
 

m8si

Active member
Did you try putting "ChangeTileAtCollision , #$00, #$00" at the beginning of the script and remove the change at the end of the script and see how that goes?
Tried that. Sadly it didn't help. It made up some weird glitched tiles all over the place.
 

mouse spirit

Well-known member
EDIT:My bad,ityped this then saw that you solved it!

I realy like the game first off. Iwill say i played at 75 % speed.But it really added something to it.
Anyway, i couldnt force the problem to occur,it did happen a couple times,but maybe try something like......
On the tile type it changes to,have THAT tile type also change to, itself basically.
Or if graphic of that tile doesnt match what you want it to,then change to self again but with the correct graphic.
 

m8si

Active member
Cool thanks! =D

Do you think the game is too fast? I thought it would end up being a boring game if it would run slower. Maybe I was wrong?
 

5kids2feed

Well-known member
Got it working!!! =D

I guess there is just too much happening at once. All i had to do was to wait a frame after removing the block.

Code:
    ChangeTileAtCollision #$00, #$00
    JSR doWaitFrame
Clever! I had the same issue in my last game, but found a weird workaround. Only had that problem when I had a palette swap going on in the background. The waiting a frame seems like a simpler option.
 

m8si

Active member
Found another bug that maybe somehow related. When collecting a pickup next to a "seam" between screens all my other code gets executed repeatedly except the tile isn't removed. That causes player to get infinite score just by staying in the middle of the seam. :) Fixed that by removing all the pickups near the seams. But that is not really a fix.

There is something strange happening in Nesmaker collision detection. And I hope there was a better solution to my original problem than WaitFrame because well... It waits a frame and game becomes laggy.
 

mouse spirit

Well-known member
Found another bug that maybe somehow related. When collecting a pickup next to a "seam" between screens all my other code gets executed repeatedly except the tile isn't removed. That causes player to get infinite score just by staying in the middle of the seam. :) Fixed that by removing all the pickups near the seams. But that is not really a fix.

There is something strange happening in Nesmaker collision detection. And I hope there was a better solution to my original problem than WaitFrame because well... It waits a frame and game becomes laggy.
Nesmakers hit detection..... isn't the greatest. Neither are it's seams or
odd/even screen code.
Your situation uses all that. I'd say you've found a good workaround,as the fixes would be a task.Like a huge task.

Maybe use a variable, and manipulate it.
Like, if the tile is touched,flip varibale on.
If variable on,don't do the tiles code. Reset variable in a good way after that .
Maybe on next screen,or do a timer or something.
 

m8si

Active member
Is there a direct command to update Screen Data? I believe calling it would solve the problem.

Here is a small fix to performance, but despite that if player collects two prizes at once the game will lag.

Code:
MACRO ChangeTileAtCollision arg0, arg1
    ; arg0 = metatile to change into
    ; arg1 = collision to change into.
    
    LDA updateScreenData
    AND #%00000100
    BEQ +isUpdated
    JSR doWaitFrame
    +isUpdated:
 
Prize tiles work well most of the time but sometimes I get this bug when the tile stays on the screen. However I think the collision is removed correctly because the prize cannot be collected after it's bugged.

I'm using LR_Platformer module.



Code is pretty straightforward:

;;; prize tile LDA updateScreenData AND #%00000100 BEQ +doScript RTS +doScript LDA scrollOffsetCounter BEQ +doIt RTS +doIt CPX player1_object BEQ +isPlayer JMP +notPlayer +isPlayer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BELOW WILL CHANGE TILE AT COLLISION. ; arg0 = metatile to change into ; arg1 = collision to change into. ChangeTileAtCollision #$00, #$00 INC myPrizes UpdateHudElement #$01 PlaySound #sfx_note +notPlayer
I feel for you bud... while not the same I had a similar issue with my game... I can TRY to help this week if you want. just DM me on discord. @Lord_Klump
 

SciNEStist

Well-known member
If you are having problems with scrolling and updating tiles at the same time, the accepted fix for it is to check if the screen is scrolling that frame, and not doing the tile collision at all if it is. This way, it will execute the tile collision as soon as it can without messing up anything else.

To do this, here is the code you put at the top of your tile script:
Code:
LDA updateScreenData
AND #%0000100
BEQ +
    RTS
+
 
Top Bottom