NES ASM Tips – Box Collision

One of the most important parts in any game, code wise, is to have some form of collision detection between sprites. This is Assembly Code snippet ( using NESASM3) should help you out when it comes to box to box collision and uses little space, so should be quite fast. We’re only using the A register AND 9 bits of RAM for simplicity.

Here we go, first with the variables being declared in Zero Page:

spriteCollider1Top = $40 ; SPRITE COLLIDER 1 TOP
spriteCollider1Left = $41 ; SPRITE COLLIDER 1 LEFT
spriteCollider1Width = $42 ; SPRITE COLLIDER 1 WIDTH
spriteCollider1Height = $43 ; SPRITE COLLIDER 1 HEIGHT

spriteCollider2Top = $44 ; SPRITE COLLIDER 2 TOP
spriteCollider2Left = $45 ; SPRITE COLLIDER 2 LEFT
spriteCollider2Width = $46 ; SPRITE COLLIDER 2 WIDTH
spriteCollider2Height = $47 ; SPRITE COLLIDER 2 HEIGHT

spriteCollisionResult = $48 ; SPRITE COLLISION RESULT - 0 = NO COLLISION, 1 = COLLISION

Next Up, The Function Itself, with an explanation of what we’re doing:

;COLLISION DETECTION BETWEEN SPRITES - RETURNS THE RESULT AS 0 OR 1
DetectCollisions:
PHA ; STORE OUR CURRENT A REGISTER ON THE STACK
LDA #$00
STA spriteCollisionResult ;INITIALIZE spriteCollisionResult to 0 (no collision found)
; START FIRST CASE
CLC                     ; CLEAR OUR CARRY FLAG
LDA spriteCollider1Left ; LOAD A WITH X1
ADC spriteCollider1Width ; ADD THE W1 TO X1
CMP spriteCollider2Left ; COMPARE X2 WITH A
BMI FinishCollisionCheckBetter ; IF GREATER, THEN SKIP THE REST, RETURN 0

; START 2ND CASE
CLC ; CLEAR OUR CARRY FLAG
LDA spriteCollider2Left ;LOAD A WITH X2
ADC spriteCollider2Width ; ADD W2 TO X2
CMP spriteCollider1Left ; COMPARE WITH LEFT OF X1
BMI FinishCollisionCheckBetter ; IF LESS THEN, SKIP THE REST, RETURN 0

; START THIRD BRACKET
CLC ; CLEAR OUR CARRY FLAG
LDA spriteCollider1Top ; LOAD A WITH Y1
ADC spriteCollider1Height ; ADD H1 TO Y1
CMP spriteCollider2Top ; COMPARE Y2 WITH A
BMI FinishCollisionCheckBetter ; IF LESS THEN, SKIP THE REST, RETURN 0

; START FOURTH BRACKET
CLC ; CLEAR OUR CARRY FLAG
LDA spriteCollider2Top ; LOAD A WITH Y2
ADC spriteCollider2Height ; ADD H2 TO Y2
CMP spriteCollider1Top ; COMPARE Y1 WITH A
BMI FinishCollisionCheckBetter ; IF LESS THEN, SKIP THE REST, RETURN 0

;THERE WAS A COLLISION! - STORE OUR COLLISION RESULT
LDA #$01
STA spriteCollisionResult 

FinishCollisionCheckBetter:
PLA ; RESTORE OUR CURRENT A REGISTER FROM THE STACK

RTS ; RETURN TO MAIN GAME LOOP

So, to use this effectively, simply set your sprite bits up appropriately, then Jump to the function (well, subroutine) by calling:

JSR DetectCollisions

If there is a collision between the two points, spriteCollision Result should contain a value of 1, otherwise it’s just a 0

Hopefully, this has helped someone out there get past one of the stumbling blocks with NES ASM development.

Happy coding everyone!

Another week, a bit more NES Game Development Completed!

So, this week I managed to  add a bit more to Flap Happy. Some of it obvious, some…not so much.

Firstly, there’s now some semblance of a background, just some simple dungeon walls in a loop but it was more the journey to getting them working that proved the interesting / challenging part. Y’see, It’s all down to how I have the levels generated….

  1. Firstly we fill the room with spikes.
  2. Put some verticals up on either side
  3. Then generate paths from left to right with varying heights.
  4. Then, and only then, do I actually draw the blue dungeon blocks, where the plain black spaces were.

Which is kinda backwards really when I think about it but hey. It works, I’ll take that.

The next issue was that of filesize.. The ROM image is 8kb too large for an NROM256 cartridge which should comprise of the following:
a 16 byte header
2 x 16kb PRG-ROM banks (Where the games code appears)
1 x 8kb CHR-ROM bank (Our Background and sprite tiles)

That should total up to just over 40kb…But that ROM says it’s 49kb. That can’t be right!

After a bit of puzzling with the NESASM3 compiler and messing around with my code banks to no avail I decided to just load the ROM into a text editor to see what was going on and, sure enough, 8192 blank characters at the end of the ROM file, doing sod all.

A quick deletion of those and (fingers crossed)… The game still loads and runs just fine, 40kb (well plus 16 bytes of header)!

The next issue is that regarding the generation of platforms in-game. Sure, they’re all positioned nicely now but, they shouldn’t all be active at the start of the game.

Thankfully, I have a fair chunk of zeropage RAM available to me so I’m storing the screen positions in memory… in memory. Yeah, I know. So, this weekend I’ll hopefully have that side of things sorted and some more obstacles can be placed for next week!

In the mean while, here’s some initial box art I’m playing around with, it’ll change a lot through time I’m sure.


Right, back to the code!

2018 is here and so is the year of NES Development in Assembly!

So, happy new year, I haven’t updated the blog in ages, my bad. A few things have happened since the last post. Christmas, Halloween and my beginnings of learning NES Development and the lowest level of language I’ll ever attempt to learn, ASSEMBLY (ASM)!

I attempted some ASM on the Atari 2600 a year ago to little success but decided, after a chat to the guys at Mega Cat Studios, to give it the college try.

The first 2 projects started and finished without really finishing, but that’s to be expected really, it’s a new language to me and I’m still learning a lot about it. Needless to say, it’s a lot more involved than C, as you’re dealing with the raw bytes and nothing else, which feels stark compared to anything else but I’m ableto understand a lot more of it now and feel that game #3, a port of the amazing Flapadiddle by Jayenkai, will be a worthy first completed game.

The first 2 games, taught me a lot about ASM and gave me some guidance as to how to organise my code as well as how backgrounds and palettes work. So, I put together the beginnings of a port of Invasion VS from my days of OUYA coding which got a fair way, then btibitjam came around so I decided to take what I’d learnt and put it into a gamejam.

invasion vs - nes eidtion - homebrew attempt #1super floofy sheepie - homebrew test #2 To be blunt, it didn’t work out, I ran out of time and spent most of August feeling pretty downbeat over everything, eventually picking myself up again mid October to retry again, but with the task of creating a procedurally generated game.

This meant creating a seeded linear randomiser in asm, that produces reasonably random, set values. After a while of researching I came across a simple one for 8-bit values which simply multiplied by 13 and added 1.

After protottypinmg some levels in PHP and GDLib I felt ready to tackle this in ASM and so far we have the following.

It’s actually playing pretty well and works in both emulator and on my PAL NES, there’s lots of features I want to add to this game and so far, it only has 5kb of game code out of an available 32kb, so ,there’s lots of scope available.

Each level is procedurally generated with a seed based on the internal framecounter and, whilst the platform placement still leaves much to be desired (and coded in properly) It feels like the game I’ve loved playing for a lot of last year.

You should check it out by the way, it’s both FREE and awesome [Download Flapadiddle]

More updates on the way.