Breakable blocks code, how to make it break by multiple different types of objects? [Solved]

kainminter

New member
So the included script has this to check if its object 3 to break a block.


LDA Object_type,x
CMP #$03
BNE dontBreakThisBlock

Lets say I wanted a block that can be broken by multiple types of objects, for instance objects 1, 2 and 3 can all break it. How would one do that?
 

chronosv2

New member
To do this we'd reverse the condition.
You see, as it stands right now the Assembly code is checking with BNE -- "Not Equal".
Well, since we don't want to jump on the first instance where the object is wrong, we need to change it around a bit.

Code:
LDA Object_type,x ;This line loads the object type of the object that just collided with the block.
CMP #$03 ;Now we CoMPare to the number #$03 (03 in hex, 3 in decimal)
BNE dontBreakThisBlock ;If not equal, jump to dontBreakThisBlock
could be changed to
Code:
LDA Object_type,x
CMP #$03
BEQ breakThisBlock ;Branch if equal, rather than Branch if not equal that the old code uses.
;Below I mention the "branch distance limit." The line above is the first branch we're working with so this is where that limit comes in.
CMP #$04 ;Just need the object ID we want to check for changed.
BEQ breakThisBlock
CMP #$05 ;And we can do this as many times as we need up to the branch distance limit.
BEQ breakThisBlock
JMP dontBreakThisBlock ;If none of our jumps happened then it's not any of those object types.

breakThisBlock: ;But we need an extra label here so that we can jump to it if true!
;Rest of the code for the breakable block goes here.

The reason the code was written "Load object, check type, skip if not equal" is because it takes up less space that way.
But the moment you need to check for multiple situations you've got to do them one at a time, and suddenly just skipping the whole thing if not equal isn't an option.
So we rewrite it to check if it IS equal, and if so run our code.
If none of our options fire off (none of the object types are equal) then we do one last JuMP to the place the original code skipped to.

I hope this helps you understand the code and how it's working a little better, and I hope this solves your problem!

Edit: Explaining the "Branch Distance Limit"
The way the processor the NES uses keeps track of where it is in your code is a value called the "Program Counter." When you do a branch (like BNE or BEQ) the computer adds the distance of the jump to the program counter. The problem is, the program counter can only jump 126 bytes backward or 129 bytes forward. So if you try to squeeze too much code between branch statements you'll get a "Branch Out of Range" error.
Yeah this is a little technical, but I figured I'd explain what I meant by "branch distance limit" above.

I'm actually working on some assembly language tutorials if that's something you're interested in learning: http://nesmakers.com/viewtopic.php?f=16&t=953
Anyway, as before, I hope this information helps!
 

chronosv2

New member
Glad to have been of assistance.
There's one thing I did notice I got slightly wrong -- I keep on executing "LDA Object_type,x" before each CMP command, and you don't need to do that. CMP doesn't change the number we're checking so you could save a few bytes by just doing
CMP
BEQ
CMP
BEQ
etc.
 

kainminter

New member
Thanks man for posting those tutorials btw. Just got around to watching them, and took some notes. Everything you posted here makes so much more sense now because of it.
 

chronosv2

New member
I'm glad the tutorials are proving to be useful!

Did you get breakable blocks by multiple items working?
 

kainminter

New member
Yes indeed, thank you!
Just tested it by making a bush that was breakable by both horizontal melee and vertical melee, and that works. I assume it would work just as well if any other attacks or projectiles were added.

It has a bug though where if you are too close to the seam between the adjacent block, it will break that one instead regardless of what kind of block it was. Will have to figure out a workaround to prevent that eventually. X)

YXWihIn.gif
 

chronosv2

New member
Very strange, but that sounds like an issue with collisions rather than the original question. Glad to see you have it (mostly) working! It looks pretty cool!
There are going to be some changes in version 4.1.0 so maybe that'll fix that collision issue. If not, there's got to be something that can solve this. :)

If your questions have been successfully answered, would you mind editing your original post with "[Solved]" or something similar in the subject? If not, we can leave the topic as-is and see what others might chime in with.
There's no issue tracking stuff on the forums so it's the best way we've thought up to note to people seeking to solve problems that this one has been taken care of.

Thank you! :D

Edit: Off-topic but nice HP indicator boxes! I like the design of those.
 
Top Bottom