tokumaru wrote:
I think that the problem is that your current design is still based on the NES screen and the name tables. Most people start out that way, because it's simpler to move objects around that small area, but once you start messing with scrolling, you have to see things differently: the screen and the name tables are not the containers of the objects anymore, they are merely used as a viewport, to show a representation of part of the level, and the level is the actual container of the objects.
You should forget about the screen and the name tables for a moment, and think of the level map as the basis for your game world. Your objects exist in the level, so everything about them is relative to the level map. Sprite coordinates are not restricted to 8 bits anymore, since levels can be much wider than 256 pixels. To test for collisions, you have to do some math with the object coordinates (like we discussed before), and since the sprite coordinates are in the same domain as level map coordinates, scrolling is absolutely irrelevant to collisions.
To make things easier, ideally you'd have access to the whole map, either by decompressing it to WRAM or storing it uncompressed (or compressed in a way that allows for random access) in the ROM. Having access to the complete level makes it easy to move objects around and have them collide with the level regardless of what the screen and the name tables are showing.
Don't think of scrolling as "the level going by", but rather as "a camera panning across the level". The level is stationary, but a virtual "camera" moves around in order to display different parts of the level, and it's this camera that dictates what gets written to the name tables and the OAM. You camera must have its own coordinates, which are used to convert level coordinates into screen coordinates (i.e. level coordinates - camera coordinates = screen coordinates), and you'll have to perform this conversion whenever you render sprites to OAM or metatile to the name tables.
I know it sounds complicated, but nobody said that scrolling was easy, specially if done right. If you do it the wrong way and keep everything oriented to screen coordinates, things will surely get out of hand (like the problem you are having now, where objects aren't aligning with the collision data).
Wow, Awesome! Thank you so very much tokumaru!!
Your words speak to me; they've spoken to me about this new way of thinking about the level staticly... it will all be accessable just like collision is? I'll probably see that answer when I read these important words once again. Thank you very
incredibly much for them!
! tepples wrote:
You can't fit a 16-bit number in one byte, but you can fit it in two. Here's how to do 16 bit addition, using the example of 508 + 8 = 516 ($01FC + $0008 = $0204):
Code:
position_hi = $0701
position_lo = $0700
; set the position to $01FC
lda #$01
sta position_hi
lda #$fc
sta position_lo
; now add eight ($0008) to this position
clc
lda #$08 ; add the low byte first
adc position_lo
sta position_lo
lda #$00
adc position_hi
sta position_hi
When you add two 8-bit numbers and the result is more than 256, the CPU subtracts 256 and turns on the carry flag. The carry flag tells the CPU to add one extra the next time it adds anything, just as you'd carry the 1 when adding multi-digit base 10 numbers in first grade. Most of the time, an addition will start with the carry off; that's what the
clc does. (Clearing a flag means turning it off; setting means turning it on.)
Thank you so much tepples!
This explains how to do 16 bit math on an 8 bit cpu; it will help me alot.
It has simplified and enritched the way I think about the CPU subtraction! ...And I will continue to keep 3gengames' "Set subtract. Clear add." in my head too! tokumaru wrote:
What tepples said. We only have 10 different digits for representing numbers (0 to 9) but that doesn't mean it's impossible to count to 10: if we use more places for digits, we can represent bigger numbers.
With one digit we can only represent 10 different numbers (0 to 9), but with one more digit we have a total of 100 combinations (0 to 99: each new digit multiplies the number of possible combinations by 10). With bytes it's the same thing. A single byte can only represent 256 different numbers (0 to 255), but if we use a second byte we get a total of 65536 possible combinations (0 to 65535: each new byte multiplies the number of possible combinations by 256).
16, 32 and 64-bit CPUs make the whole thing easier (and faster) by manipulating multiples bytes at a time, while 8-bit CPUs have to do it byte by byte, but they can still perform math with big numbers.
This is so excellent
and helpful to me too tokumaru... THANK YOU!!!
edit.edited again.last edit.