08. BG collisions

well, bg is a little different than sprites. We can’t read the bytes in the PPU, not easily. So let’s have a map of all the solid blocks in the room. Having each block 16×16 simplifies everything, and you can stuff the entire room into a 240 byte array. X from 0 to 15, Y from 0 to 14. I copied the array to the RAM, in case we want to make the BG destructable. (Which I will demonstrate a little later). Here’s what the array might look like…

const unsigned char c2[]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

And the 1’s here match the blocks in the game.

09_collide

To check collision, you just need to mask the low nibbles of X and Y (& 0xf0) and combine them YX… (X >> 4) + (Y & 0xf0). and check that byte in the array.

For sprites, I have been checking 4 points, each corner, and setting L R U D variables if collision, and eject as needed. First I do an X move, check collision points, and eject X if hit. Then I do a Y move, check collision, and eject Y if hit. See bg_collision() below.

This code is simplified, because X and Y moves are fixed at 1 pixel per frame. A little later, I will modify this so we can test variable speeds. 1 pixel per frame is a bit slow, and might be dull gameplay.

I have been using Tiled to make level data, to use for the collision map. It’s simple to use, and it can export a csv file, which is easy to make into a C array. But, it can’t import NES style .chr file, so I had to make a picture of all the types of blocks. This is very easy, since we have only 2 types, blank and block.

First I make tiles in NES Screen Tool. Then I draw the 2×2 blocks. It looks kind of dumb here, because I only have 2 types, but when have a more detailed game with dozens of blocks, it will start to make more sense. There isn’t a way to export a picture of the nametable, so I just do a screen capture, and crop it in GIMP, save as metatile.png.

Now, import it as a tileset to Tiled. The dimensions are 32×32 per tile, because NES screen tool doubles the pixels. Now design the levels, and export CSV.

09_Tiled

It’s a piece of cake to turn a CSV file into a C array, but I made a python 3 script anyway to automate it. CSV2C.py. Then I import the C arrays into my code, and have an array of pointers to each array.

Now, I wrote some code to print the array as a block of 2×2 tiles to the screen with a big loop and some vram_put statements. vram_put() needs the screen to be off. Left to right ppu writes wrap around to the next line. So, you don’t have to change the address to do even the entire screen.

And I have it so that, if you press “Start” it loads a new collision map, and draws it to the screen.

So, test it out. Bump into the walls. Collisions work. Press start. Collisions still work, because it loaded a new collision map loaded to the RAM.

Note, I shifted the whole screen down 1 by scroll y ff (-1). Sprites always show up 1 pixel low, so shifting the bg down 1 lines them up.

https://github.com/nesdoug/09_BG_Collide/blob/master/collide.c

https://github.com/nesdoug/09_BG_Collide

The loading code isn’t very good, because it can only draw 1 kind of tile block, and it never changes the attribute table. I’m going to cover a much better loading system (see page on metatiles), a bit later, but first I wanted to talk about scrolling.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s