This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Projectiles and collision detection with NESASM

Projectiles and collision detection with NESASM
by on (#95140)
Are there any good tutorials on such topics? Or even just docs/examples?

by on (#95141)
It is unrelated to NESASM or any other particular assembler.

Here is a helpful article on the topic.

by on (#95142)
Fastest answer ever. Thanks, Shiru. But do you have anything NES-specific?

by on (#95143)
The code from pong1/2 in Nerdy nights is about as simple as it gets with the sprite colliding with all sides of the screen. He doesn't discuss collision detection much in the threads but there are notes in the code.

Not sure how basic/complex you're looking for. If you're having trouble with basic pong style collisions your best bet might be to post your specific questions here.

by on (#95144)
The thing that collision logic is not NES specific in general - it is the same for anything, be it NES, Flash, etc. You only need to implement it in programming language of your choice - 6502 assembler in your case, it will be just a bunch of conditional branches.

by on (#95149)
Shiru wrote:
The thing that collision logic is not NES specific in general - it is the same for anything, be it NES, Flash, etc.

Not necessarily. Different platforms need the geometry represented different ways.

Some platforms have the hardware or the CPU power to intersect pixel maps. Atari 2600 and Commodore 64 can intersect sprites in hardware, and PCs since the i486 era can quickly calculate which areas of a pixel map overlap. Other platforms, such as modern PCs and modern consoles and modern smartphones, have the CPU power to intersect of arbitrary polygonal areas or polyhedral volumes. NES has neither and must rely on low-computation software approximations.

My Pong clone approximates the ball as a circle and the paddles as rectangles with semicircles on the end (like the Nintendo racetrack logo, except rotated 90 degrees). That's because axis-aligned rectangles and circles are computationally easy to intersect.

by on (#95152)
So i guess it is just impossible to do a simple rect intersect in a PC game, because PC has so much power to waste. OK.

by on (#95156)
You won't find tutorials on such specific game topics for the NES. Like it's been said, these concepts are not platform-specific, and the same ideas can be implemented in a multitude of systems. Part of becoming a good programmer is reading about these concepts and making your own implementations in your language/system of choice.

by on (#95160)
That's pretty sad that the NES needs software collision. For that matter, I think the Genesis only has a collision register that is flagged by any sprite intersecting any other sprite. Utterly useless.

On topic I'm usually referred to this article when asking about collisions:
http://games.greggman.com/game/programming_m_c__kids/

Here's another guy working on collisions:
http://www.tummaigames.com/blog/page/2/

by on (#95162)
Hit boxes, learn to love them.

by on (#95163)
The only console I'm aware of that performs useful collision detection in hardware is the Atari 2600. It has bits to indicate collisions between any 2 objects out of the 6 it can display (playfield, player 0, player 1, missile 0, missile 1, ball). Collisions with the playfield might require additional software checking depending on the kind of game (e.g. you might need to tell apart a wall from the floor), but I'm sure lots of games get away with just using the collision bits provided by the TIA.

I'm not sure the same approach would work well on the NES, because of the 64 tiny sprites thing. To indicate collisions between any 2 sprites, we'd need 2016 bits. In addition to that, most objects are composed by several sprites, so in order to check for a collision between two objects you'd need to look at all the collision bits involving all the sprites of the first object and the second object. This wouldn't be practical at all, and I'm pretty sure it would be slower than the simple overlapping rectangles technique that's commonly used.

by on (#95165)
Doing it in hardware seems like a waste of transistors for bad programmers who don't know how to do it in software.

And after they wonder why bad games are released.... :?

Also, it's nice to have a hitbox slightly smaller than the graphical representations of the objects.

by on (#95169)
Shiru wrote:
So i guess it is just impossible to do a simple rect intersect in a PC game, because PC has so much power to waste. OK.

I see your sarcasm, but bounding box collision often does not work in games designed to meet prevailing production values for commercial PC games. Players won't stand for what they consider crappy hitboxes, and they'll one-star the game on all the review sites if the instant replay of the moments before a character's death (sometimes called a "killcam") shows a bogus kill.

That said, here's the general technique that applies to all platforms:
  1. Optional: Reject objects that cannot possibly overlap. In some cases, this can be done by sorting the object list or dividing the playfield into sectors.
  2. Reject collisions based on bounding boxes, which are very fast to test.
  3. Optional: Reject collisions based on bounding spheres, which are also fairly fast to test.
  4. Optional: Reject collisions based on more precise geometry.
The difference I speak of between software collision on the PC and software collision on the NES lies in players' expectations of the "more precise geometry" used in step 4.

Bregalad wrote:
Also, it's nice to have a hitbox slightly smaller than the graphical representations of the objects.

Which might elicit complaints from players who think they hit an enemy critter but the game thinks they missed because the hitboxes were shrunk. One might prefer large hitboxes when the player is attacking and small hitboxes when the player is being attacked, such as the 1x1 or 2x2 pixel hitboxes of several bullet hell shooters, but that can make player vs. player encounters difficult to tune.

by on (#95172)
Hit boxes and kill boxes can be separated. And the PC games need to get over them selves it seems.

by on (#95183)
vicious: I'm a terrible teacher, but I still spent a lot of time on this topic, so I'll link it. It shows a lot of ways it can go wrong, and why the logic is the way it is with some simple diagrams. If you can deal with words-words-words, my harsh tone, and a few pages of problems that deal with a specific program rather than a general guide, it may be useful.

As well, you can find a few super fast ways to do it here.

There is stuff that's not collision detection there too,(which is totally worth reading too even if you don't understand it all) since it's not the focus of that topic. But you can see a simple 6502 bounding box routine get simplified and optimized in a way you might be able to understand.

That said, I like specific questions. If you end up getting stuck with collision, I will absolutely try to help in my own bumbling way if you post some code or some specific points of a guide you find that you do not understand.

tepples wrote:
I see your sarcasm, but bounding box collision often does not work in games designed to meet prevailing production values for commercial PC games.

But this doesn't matter at all because this topic is about NES, and because there are still easy to find guides all around the internet about collision logic that would work on NES. It's not as if all the guides written years ago have suddenly disappeared because 3D/crazy processing power is prevalent now. I guess it's true it's not always the same, but a list of exceptions that don't have much to do with the target platform doesn't need to be given to someone who doesn't need it. It's like finding fault in someone saying random number generator instead of psuedo random, because there's no such thing as a random number generator.

Bounding box collision is still useful to teach, and people still write guides about it because it is simple to understand. Also, as you've pointed it, it's useful to try before you even start with more advanced collision, since it will still reject VERY impossible collisions before wasting CPU time doing the more extreme checks for each set of objects. I'd would think a guide that doesn't teach this isn't really useful, because it's skipping a pretty much "free" optimization that can get extreme results depending on the number of objects. And PC games with processing power to spare LOVE lots of objects.

Quote:
Players won't stand for what they consider crappy hitboxes, and they'll one-star the game on all the review sites if the instant replay of the moments before a character's death (sometimes called a "killcam") shows a bogus kill.

True, but this topic is about NES. I have never seen such a feature in any classic game I've played. Except Cattrap (Game Boy), but that game has tile by tile movement anyway. Even if there are old games that do this, or if vicious wanted to do this, it's certainly much harder to program than collision. He'd have to already have a great deal of 6502 knowledge before such a feature would reveal "errors" in his collision detection. And by then I'd bet he'd be able to fix it.

by on (#95194)
Kasumi wrote:
I have never seen such a [killcam] feature in any classic game I've played.

Yeah, killcams didn't show up in any game I played until Goldeneye 007 for N64, which shows a replay after Bond is killed in action in the 1-player game. But instant replays have been around since Food Fight (1983).

Otherwise, I agree that rectangle testing should be enough for a beginner. Do that first.

by on (#95333)
When it finally comes down to the actual soft collision check do people use something like this:
Code:
declare function rectRect(x1 as integer, y1 as integer, x2 as integer, y2 as integer, x3 as integer, y3 as integer, x4 as integer, y4 as integer) as integer
   if x1 > x4 then return 0
   if x2 < x3 then return 0
   if y1 > y4 then return 0
   if y2 < y3 then return 0
   return 1
end function


It's in BASIC but really BASIC is almost pseudo code in readability. Also, not my code: just an example of soft collision someone helped me with.