Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.
Are you using $0200-$02XX for Sprite OAM? (I'm going to proceed in my code assessment as if you are. I think you are)
If so, you wouldn't typically use that address as your actual object location. Usually, game objects are made of multiple sprites, and the draw locations for the individual sprites are relative to the position of the object as a whole. The draw position would also vary from scrolling.
If you don't scroll at all and your objects are all 8x8 pixels, then I guess you could do it that way. I never thought about doing it way because other design aspects precluded it.
First, if you compare the X position of one object to the X position of another object and BNE, you will only catch collisions that occur when the objects have the exact same X position, not when they overlap. So 7/8 possible collisions locations will be missed.
A sprite with an X position of 00 will occupy pixels 00-07.
If you decrement, and then don't branch out, you proceed to also add following. DEC to a memory location performs a read, modify, and write, all in one step.
Basically, your program does this:
1. See if controller 1 pressed A, exit routine if not
2. Load X position of Sprite 00
3. Subtract 181 from X position of sprite 00, (not saving result and behaving as if carry is set) and if the answer of that subtraction is not zero, branching to DoneCollision
4. If the answer from that subtraction was exactly zero, the X position of sprite 00 is decremented (it will now be 180)
DoneCollision:
5. The value of the X position of sprite 00 is loaded into the accumulator
6. Carry flag is cleared.
7. 1 is added to this value (If the value originally equalled 181, it now equals 181. If the value originally equalled anything else, then it is now one greater than it's original value.
8. That value is stored back to the location that will be used for X position of sprite 00.
I'm new here too but hopefully that helps you move forward a bit.
Thank you very much, I read everything that concerns the collision of objects, but to me as a novice is difficult to understand.
I think you need to calculate the coordinates of both the player and the object with which the collision continue to make comparisons and if a player gets to the coordinates of the object to prohibit further movement until it will not go beyond.
What happens after collision is detected is up to you, whether stopping movement (and or pushing back a few pixels to avoid overlap), or bouncing back, etc. It's up to you.
nesdoug.com -- blog/tutorial on programming for the NES
The "#" in the LDA instruction means you're loading an immediate value. The problem is that A is an 8-bit register, and $0203 is a 16-bit value, so it simply isn't possible to put it in A. But this isn't even what you're trying to do, is it?
If you want to load the contents of memory position $0203 (the value of the constant/label PLAYER), just do LDA PLAYER, without the "#".
All labels are just memory locations
What I like to do is separate my labels into constants and variables.
For variables, I don't care about the address itself, but what's in it. For constants, since they never change, I use its address as an immediate value.
You, may already know that, but that confused the fuck out of me when I was first learning how to program in assembly.
So for a player's x position (In this case $0203), you'd want that to be a variable. If the object is moving, you'd want its coordinates to be variables too.
lda player_x
cmp object_x
bne + ;branch if they arent touching
;if they are touching
;do stuff
jmp @continue
+
;do stuff if they aren't touching
@continue:
;rest of code
I did as instructed but a collision with an object signal is not happening instead is a clash along the line of the screen in the fact of the matter is in lessons Nerdy Nights (Starting Pong) where there are clashes with lines but not with objects, and this is not enough.
The only thing that comes to mind is to record the contents of the accumulator in memory of STA #$30 in ReadA: 000030 and player movement will be set 01 if the player does not move it is reset to zero so check 00 is a background object if a player gets to the area where the other numbers, then the collision.
You're comparing $0203 (the sprite's X position) to the value in background label, whose address is $E000. The value of $E000 is #$00, which equates to the left edge of the screen. Are you trying to test collision with the plus sign made of zeros? Those aren't sprites.
The general way to do sprite collisions is to use hitboxes, which basically contain 4 variables: the positions of the 4 edges of the sprite.
I went ahead and modified your code slightly and just added a new sprite (To test collisions with), hitboxes for the 2 sprites, and routines to update the hitboxes and check for collision each frame.
The left and top edges of the 2 sprites' hitboxes are just their X and Y positions, and their right and bottom edges are just their X and Y positions plus 7. So this makes an 8 by 8 hitbox.
A really easy way to check for basic collision detection goes like this:
You are comparing your object's location against "background". So, when it does that compare, it goes to the location background and pulls the first byte, which in this case is 00. That's why it always beeps when you cross zero.
I'm not sure exactly what you're trying to do, or if this is your line of thinking, but you can't do something as simple as comparing the object to your background table to detect for collisions. If you're doing background collisions that are more complex than the outer edge bounding box of pong, you'd have to know your object's position, and then reference that to the corresponding background tile for that position on your map. So, let's say your object is at 128, 64. This is a somewhat simplified explanation, but you'd have to divide 128 by 8 , which tells you're in the 16th tile column, then divide 64 by 8 and you'll know you're in the 8th row. So, then check the collision data for the tile at the 16th column and 8th row.
Also, you're still comparing just one pixel. Consider this. Your ball is 8 pixels by 8 pixels. Your ball could touch something 7 pixels to the right of it's draw position and it should still be a hit. So, it could be said that your ball has an 8 pixel by 8 pixel hitbox.
In one way or another, you basically need to do this for object/object collisions:
See if object Y is to the right of the left side of object X's hitbox, if not, there's no collision
See if object Y is to the left of the right side of object X's hitbox, if not, there's no collision
See if object Y is to the below the top of object X's hitbox, if not, there's no collision
See if object Y is to the above the bottom of object X's hitbox, if not, there's no collision. If so, you have a collision.
There's at least one quicker way I know to do it, but it pretty much involves summing the above process into a smaller equation. Once you get to that point I can dig up the link for you.
That's for object/object collisions, which it at first what I thought you were doing but this program looks like you're trying to go for background collisions. Background collisions, like I mentioned above, have to do with checking against a table of collision data, and you do this when the object moves, only in the directions that it's moving. (For example, don't check the left side of your hitbox against background if your object is moving right.) If you find that you've crossed into a solid tile, then you have to calculate how far to "eject" your object, that is, how far it needs to move to be pushed out of the solid tile.
You allow all of your movements to happen, whether or not they're into a collision tile, and then correct them before they're drawn.
Side note: You have logic in your NMI that doesn't need to be there, but I see you're using the Nerdy Nights style, which simplifies teaching certain aspects by just putting everything in NMI and guaranteeing your logic will execute at a set rate. Once you move on to the next thing, I'd suggest moving your controller reading and collision out of your NMI, adding code to protect your registers when NMI hits, and a delay loop in your main logic so that your main game logic cycle executes once per vBlank (with the exception of lag frames which aren't a concern now)
Let me know if that makes sense and if you have any questions. If we can get the first few things figured out, I'll try to help you get some footing to move forward.
Edit: Sogona covered some of this while I was typing the post, but I'm going to go ahead and upload it as is anyway.
Thank you very much for your help is very good knowledge, they will be useful in the future for the creation of such a player or enemy bullets, and so on, I think understood the essence of the program will continue to do.
I did object detection background tile: $00 this background, other items: $01, $02, $03, and so on.
How good is this idea for the processor I do not know that's what happened:
I have been doing...
-allow the move
-check collision
-if collision, "eject", opposite the direction of movement.
But, apparently there are many ways to go about this...as the above thread shows.
If your game is non-scrolling, and has 16x16 objects...you could do something like...
ejecting left... X and #$f0 = X
ejecting right... X + #$10, and #$f0 = X
ejecting up... Y and #$f0 = Y
ejecting down...Y + #$10, and #$f0 = Y
or any similar algorithm. You might be misaligned by 1 pixel with this one, I don't remember.
nesdoug.com -- blog/tutorial on programming for the NES
I can take a variable for comparison at $2002 to create the effect of a collision but I still do not know how it can be easier to create one like something that: