Boundaries check when speed> 1 pixel

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Boundaries check when speed> 1 pixel
by on (#159935)
I want to stop the player from crossing the screen sides, I managed to do that when speed is 1. But when is over that I ran into this problem, if the player is at pixel 1 and it moves 2 pixels to left I cannot compare against -1. Same would go if I move right and cross up to say 257 which overflows the byte.

How is this managed?
Re: Boundaries check when speed> 1 pixel
by on (#159937)
sempressimo wrote:
if the player is at pixel 1 and it moves 2 pixels to left I cannot compare against -1. Same would go if I move right and cross up to say 257 which overflows the byte.

You can if you use signed 16-bit coordinates, which give you a range of -32768 to 32767. You don't have to though. As long as the player doesn't move 128 pixels at a time (even Sonic can only go up to 6 pixels per frame without power ups or slopes, so you should be fine :mrgreen:), it will suffice to check the direction of the movement and whether bit 7 changed. Look:

If bit 7 goes from 1 to 0 (e.g. 255 to 0), and the player is moving right, it's gone past the right edge of the screen.
If bit 7 goes from 0 to 1 (e.g. 0 to 255), and the player is moving left, it's gone past the left edge of the screen.

The other combinations shouldn't trigger anything, because they happen in the middle of the screen:

If bit 7 goes from 0 to 1 (e.g. 127 to 128), and the player is moving right, nothing happens (it just crossed from the left half of the screen to the right half).
If bit 7 goes from 1 to 0 (e.g. 128 to 127), and the player is moving left, nothing happens (it just crossed from the right half of the screen to the left half).
Re: Boundaries check when speed> 1 pixel
by on (#159948)
tokumaru wrote:
sempressimo wrote:
if the player is at pixel 1 and it moves 2 pixels to left I cannot compare against -1. Same would go if I move right and cross up to say 257 which overflows the byte.

You can if you use signed 16-bit coordinates, which give you a range of -32768 to 32767. You don't have to though. As long as the player doesn't move 128 pixels at a time (even Sonic can only go up to 6 pixels per frame without power ups or slopes, so you should be fine :mrgreen:), it will suffice to check the direction of the movement and whether bit 7 changed. Look:

If bit 7 goes from 1 to 0 (e.g. 255 to 0), and the player is moving right, it's gone past the right edge of the screen.
If bit 7 goes from 0 to 1 (e.g. 0 to 255), and the player is moving left, it's gone past the left edge of the screen.

The other combinations shouldn't trigger anything, because they happen in the middle of the screen:

If bit 7 goes from 0 to 1 (e.g. 127 to 128), and the player is moving right, nothing happens (it just crossed from the left half of the screen to the right half).
If bit 7 goes from 1 to 0 (e.g. 128 to 127), and the player is moving left, nothing happens (it just crossed from the right half of the screen to the left half).


Got that working thanks! Here is part of my implementation for future reference:

Code:
MovePlayerLeft:

  ; update player dir
  LDA #DIR_LEFT
  STA entity_dir

  LDA entity_x 
  STA old_entity_x

  ; move the player
  SEC
  SBC entity_speed
  STA entity_x
 
  ; check if the screen sides where crossed
  LDA old_entity_x
  AND #%10000000
  BNE EndMoveLeft
 
  LDA entity_x
  AND #%10000000
  BEQ EndMoveLeft
 
  ; if bit 7 was a 0 and it turned into a 1
  ; side crossed set it at 0
  LDA #$00
  STA entity_x