Collision detection problem

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
claude_liet
Posts: 1
Joined: Thu Jun 20, 2019 7:37 pm

Collision detection problem

Post by claude_liet » Thu Jun 20, 2019 7:55 pm

I use nes.lib and wrote a simple function to detect collision. But there's something wrong that my player could stutter through the wall, here's my main code:

unsigned char CheckCollision(unsigned char x, unsigned char y)
{
vram_adr(get_ppu_addr(NAMETABLE_A, x, y));
vram_read(&tile, 1);
vram_adr(NAMETABLE_A);
if(tile == 0xE0 || tile == 0xE1 || tile == 0xF0 || tile == 0xF1)
{
//if wall
return 1;
}
else
{
return 0;
}
}
Attachments
TIM截图20190621105443.png
TIM截图20190621105443.png (16.46 KiB) Viewed 5317 times
TIM截图20190621105340.png
TIM截图20190621105340.png (2.53 KiB) Viewed 5317 times

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Collision detection problem

Post by dougeff » Fri Jun 21, 2019 5:05 am

You don't want to read from the PPU to determine collision. Especially you don't want to read from the PPU outside of v-blank.

Also. A read from the PPU ( vram_read function ) works differently than you would expect, and the first read from the PPU will return a "garbage" value. Every subsequent read will be a real value. So you need to read twice (to get 1 byte... read 3 times to get 2 bytes... etc)

And again, this is not what you should do for collisions. I recommend that you have a map of the room, in some compressed format, in the ROM (or RAM) that you read from... because, as I stated above, you shouldn't read from the PPU outside of v-blank. Also, setting a PPU address ( vram_adr function ) can mess up the scroll registers, if you don't undo it before the frame starts rendering.

...and if you do it while the frame is rendering (outside of v-blank), this might not work at all in a real hardware. It would fail 100% of the time.

Edit...
So, what you want is a constant array of values that represents the layout of the room. I prefer a 1 byte per 16x16 square of the room, so that you fit 16 wide nicely and you can do some bit shifting of X and y to get a collision byte like (binary) yyyyxxxx.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Collision detection problem

Post by dougeff » Fri Jun 21, 2019 5:45 pm

Apparently, vram_read does a dummy read for you, I forgot. You do not need an extra.
nesdoug.com -- blog/tutorial on programming for the NES

Post Reply