I don't mind helping at all if you actually pay attention and figure at least some things out.
There is one thing I'd like to say about one piece of code, though:
Code:
lda (map_add), y
sta stuff
lda stuff
bpl nocol
There is absolutelly no need to store the byte in "stuff". After you did "lda (map_add), y" the N flag was already altered by the loaded value, so there is no need to store it and load it again. Change to this and it will run just fine:
Code:
lda (map_add), y
bpl nocol
This is obviously faster. Not that speed is much of a problem for now, but avoiding unnecessary operations can only be a good thing, especially when you work on bigger projects where speed is really important.
Quote:
One is, that the collision areas act as collision columns, so I collide in the columns that the tiles are in.
I didn't understand this. Maybe you could take a screenshot or something, or explain better what's happening. What are you calling "collision areas"? A solid block? the collision points in the sprite? I didn't understand.
Quote:
and also, I can't think of a way to make it so it's like when you're on the right side of the object, you can still move right, up and down, but not left.
You just have to repeat the code you used for left collision with the other points: 3 in the top, 3 in the right and 3 in the bottom.
I suppose that the player coordinates refer to the top left as in my past examples. So, when you move to the left, there are 3 points to check for collision:
1. playX, playY (the one at the top left of the sprite)
2. playX, playY + 8 (the one in the middle, still in the left)
3. playX, playY + 15 (the bottom one, in the left)
These were the coordinates of the 3 points you have to check for collisions to the left. If you think a bit, the tree points to check for collisions ABOVE the player are:
1. playX, playY (same as the one we use for the left)
2. playX + 8, playY (the one in the middle, still in the top)
3. playX + 15, playY (the one to the right, stil in the top)
For the RIGHT:
1. playX + 15, playY (the one at the top right corner)
2. playX + 15, playY + 8 (the one below it)
3. playX + 15, playY + 15 (the one at the bottom)
For BELOW:
1. playX, playY + 15 (the one at the bottom left corner)
2. playX + 8, playY + 15 (the one next to it)
3. playX + 15, playY + 15 (the one at the bottom right corner)
These are all the points you have to check for each direction the player moves. No need to chack them all at once! Only check for right collisions if the player moved right. There is no way you'll collide in the left when moving right, so there is no need to check it. You'll at most check 2 collisions, if the player can move diagonally, wich means it can move in both axis at once.
I don't think you need lfcol, rtcol, upcol and dncol at all. The only thing you have to do after a collision is move the player back. You don't need to create a flag for that, just move the player back right when you detect the collision.
I suggest you do it like this:
Code:
moved_left:
;Set the first point.
LDA playX
STA pointX
LDA playY
STA pointY
;Check the first point.
JSR check_collision
;Jump if collision happened.
BMI left_collision
;Set the second point.
LDA playY
CLC
ADC #$08
STA pointY
;Check the second point
JSR check_collision
;Jump if collision happened.
BMI left_collision
;Set the third point.
LDA playY
CLC
ADC #$0F
STA pointY
;Check the third point
JSR check_collision
;Jump if collision happened.
BMI left_collision
;If you get here, no collision
;happened, so, skip the position
;correction step.
JMP end_left_collision
left_collision:
;Here we fix the player's Y position.
LDA playY
;Clear the lower 3 bits
AND #$F8
;Add 8 to place it to the right of the solid tile.
CLC
ADC #$08
STA playY
end_left_collision:
;If you make the checking of each direction
;as subroutines, you can just return now.
RTS
check_collision:
;do all that collision crap I
;explained befor in here. But
;use "pointX" and "pointY"
;instead, so you have a generic
;function that can check any
;points you want it to.
.
.
.
LDA (map_add), Y
;OK, if it was a solid block,
;the N flag is set.
;Return from the routine, having
;the N flag to indicate a collision.
RTS
That's it. Just do it to the other 3 directions (up, right down). I'll show you ONE more collision, but you have to find out how to do the rest of them!
Code:
moved_down:
;Set the first point.
LDA playX
STA pointX
LDA playY
CLC
ADC #$0F
STA pointY
;Check the first point.
JSR check_collision
;Jump if collision happened.
BMI bottom_collision
;Set the second point.
LDA playX
CLC
ADC #$08
STA pointX
;Check the second point
JSR check_collision
;Jump if collision happened.
BMI bottom_collision
;Set the third point.
LDA playX
CLC
ADC #$0F
STA pointX
;Check the third point
JSR check_collision
;Jump if collision happened.
BMI bottom_collision
;If you get here, no collision
;happened, so, skip the position
;correction step.
JMP skip_bottom_collision
bottom_collision:
;Here we fix the player's X position.
LDA playX
;Just clearing the 3 bits will
;do the trick this time.
AND #$F8
STA playX
skip_bottom_collision:
RTS
These functions are just clones of each other, with minor changes. you have to set the 3 correct points (the ones I listed before), and correct the position of the player accordingly. The 2 routines I posted should be more than enough for you to figure out the rest.
Now, I can't say this code will work for sure, as I have not tested it, and I just typed it all down. There may be errors. So don't just go and copy it and paste into your game. Read it carefully and try to understand what I'm doing here.
EDIT: Just to make it clear: The code I posted here should be run AFTER you moved the player. I'm assuming you already read the joypads AND already incremented the player coordinates accordingly. In fact, it wold be even better, in my opinion, if you include the "coord increment" step INSIDE the function that checks for collision (the ones I just posted). Just do it in the very beginning of each function. I see no reason to do it OUTSIDE the functions if you're going to jump to them right after updating the coords.