It is currently Wed Oct 23, 2019 9:33 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: My Platformer Framework
PostPosted: Tue Sep 17, 2019 2:40 am 
Offline
User avatar

Joined: Sat Aug 31, 2019 2:12 pm
Posts: 17
Hi!

Based on my Physics Demo, I've been writing an object oriented platformer framework in C.
My goal is to achieve the highest possible performance while at the expense of having a high level of human-readable and maintainable code.
It's too early to open-source it, but I will do so as soon as it's stable enough.

Image Image Image

Please test it out and let me know how the controls feel... :)
The collision detection is not perfect yet, but I hope there won't be any problems.

PS: I did the sprites as well. :mrgreen:

Roadmap:
Code:
[X] Object-oriented code
[X] Text-based game menus
[X] Collision detection with simplified physics
[X] Smooth player movement
[>] Support metatiles and metasprites
[ ] Sprite collision detection
[ ] Background scrolling
[ ] Many other features...


Controls: L/R Move, A Jump, B Run

EDIT: I added a new version with idle animation.


Attachments:
File comment: Added idle animation
platformer2.nes [40.02 KiB]
Downloaded 187 times
File comment: First version
platformer.nes [40.02 KiB]
Downloaded 166 times

_________________
Image


Last edited by wonder on Wed Sep 18, 2019 8:47 am, edited 1 time in total.
Top
 Profile  
 
PostPosted: Tue Sep 17, 2019 8:27 am 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 628
Location: Central Illinois, USA
Good work so far!

Quote:
Please test it out and let me know how the controls feel...

The jump physics do feel a little odd to me. Maybe a little too fast vertically in comparison to the horizontal velocity? I'm not sure.

_________________
My games: http://www.bitethechili.com


Top
 Profile  
 
PostPosted: Thu Sep 19, 2019 10:16 am 
Offline

Joined: Tue Oct 16, 2018 5:46 am
Posts: 101
Location: Gothenburg, Sweden
This looks really cool! Have you found any issues in performance or rom space developing in C as opposed to assembly?

How do you do your collision detection? With so many objects and platforms on screen, the fact that it stays at 60 fps is what I find most impressive. :)

BTW, How do you even debug your C code? I've only ever coded for NES in assembly..


Top
 Profile  
 
PostPosted: Sat Sep 21, 2019 4:18 am 
Offline
User avatar

Joined: Sat Aug 31, 2019 2:12 pm
Posts: 17
gauauu wrote:
Good work so far!
The jump physics do feel a little odd to me. Maybe a little too fast vertically in comparison to the horizontal velocity? I'm not sure.

Thanks!! Indeed, I'm still not fully satisfied with the current velocity/acceleration values, there's still a lot of room for improvement. :)


pwnskar wrote:
This looks really cool! Have you found any issues in performance or rom space developing in C as opposed to assembly?

Thank you so much! I'm really glad you like it! Well, I've never coded in assembly so I'm not sure how much of a performance hit is the fact that I am writing it in C.
Nevertheless, I believe my C code is as tight as it can possible be, while keeping an high level of abstraction.

pwnskar wrote:
How do you do your collision detection? With so many objects and platforms on screen, the fact that it stays at 60 fps is what I find most impressive.

It took me around one month to come-up with this algorithm and make it work fast in the NES. Normally I would use sin(), cos() and atan2(), but since the <math.h> is not really available in this context, I had to wrap my head around it and come up with an entirely different solution. I'm attaching my collision detection module, but bear in mind that it's still a work in progress.

pwnskar wrote:
BTW, How do you even debug your C code? I've only ever coded for NES in assembly...

Well, first of all, I wrote my own printf(), so I can do stuff like print_at(3, 3, "Vx: %d", actor.vx);.
Second, I always check the generated assembly code in the compiler listings (both locally and on 8bitworkshop).
Finally, for benchmarking, I'm using the methods suggested in this thread: How can I benchmark my C code?


Attachments:
collision.c [7.01 KiB]
Downloaded 127 times

_________________
Image
Top
 Profile  
 
PostPosted: Sat Sep 21, 2019 12:39 pm 
Offline

Joined: Tue Oct 16, 2018 5:46 am
Posts: 101
Location: Gothenburg, Sweden
wonder wrote:
It took me around one month to come-up with this algorithm and make it work fast in the NES. Normally I would use sin(), cos() and atan2(), but since the <math.h> is not really available in this context, I had to wrap my head around it and come up with an entirely different solution. I'm attaching my collision detection module, but bear in mind that it's still a work in progress.

Thanks for sharing the attachment! I had a look at it but I'm ashamed to admit most of it went above my head! :D Will try to read through it some more though, as I'm sure there's lots I can learn from it.

Do each entity check it's collision against whatever tiles are loaded into the nametables behind them? Is that what you're doing when using your P2B() function? Or do you keep a buffer of collision boxes that gets updated with every nametable change?

I do a buffer kind of solution myself, but I only load in platforms that you can land on. For collision between entities I think maybe we're doing some things similarly. What I do is I take the coordinates for the collision box of entity_1, add all the sides to the collision box of entity_2, but mirrored and flipped upside down, then I compare the result of that to the pivot (or "hot spot" if you will) of entity_2. The result would be the same as comparing all corners of entity_1 to each side of entity_2 to see if they intersect, but this way I only check one point instead of four.

Code:
Screen space collision boxes:
(p = pivot)
                        +-------------+
       +----------+     |  entity_2   |
       | entity_1 |     |       :     |
       |     :    |     |       :     |
       |-----p----|     |-------p-----|
       |     :    |     +-------------+
       +----------+
-------------------------------------------

Screen space collision boxes added together:

+------------------------+ entity_2 pivot
|     +----------+       |      |
|     | entity_1 |       |      |
|     |     :    |       |      V
|-----|-----p----|-------|      p
|     |     :    |       |
|     +----------+       |
|                        |
|  enity_1 padded with   |
| dimensions of entity_2 |
+------------------------+

-------------------------------------------

Does entity_2's pivot overlap the combined collision box?

Anyways, since you shared so much of your code I thought I'd share the principle of mine. The actual assembly code is even more confusing even to myself, so I'll spare you that.. :)

I'm looking forward to see how your engine comes along!

Cheers! :beer:


Top
 Profile  
 
PostPosted: Sun Sep 22, 2019 2:16 am 
Offline
User avatar

Joined: Sat Aug 31, 2019 2:12 pm
Posts: 17
Hello again!

Quote:
Do each entity check it's collision against whatever tiles are loaded into the nametables behind them?

Yes, but I'm not using the nametable itself. I'm using a grid object char matrix[x][y] = {{...}, {...}, ...};.

Quote:
Is that what you're doing when using your P2B() function?

P2B means "pixel-to-block", it gives me the result of the given pixel-coordinate divided by 8 (block size).

Quote:
Or do you keep a buffer of collision boxes that gets updated with every nametable change?

I'm not sure what you mean, but I'm guessing that the answer is no.

I've drafted a PDF on which I try to explain my reasoning in more detail, see attached. :)


Attachments:
Collision detection algorithm on the NES.pdf [129.67 KiB]
Downloaded 112 times

_________________
Image
Top
 Profile  
 
PostPosted: Sun Sep 22, 2019 9:17 am 
Offline

Joined: Tue Oct 16, 2018 5:46 am
Posts: 101
Location: Gothenburg, Sweden
wonder wrote:
Quote:
Or do you keep a buffer of collision boxes that gets updated with every nametable change?

I'm not sure what you mean, but I'm guessing that the answer is no.

Perhaps buffer wasn't the right word. What I meant was if you were keeping a representation of all the collision boxes in RAM and then update them accordingly whenever there's a change to the nametables. If your char matrix[x,y] is kept in RAM, then this would be that. But I'm guessing you're keeping it in ROM, since it should need 960 bytes for each full screen and keeping it in RAM would take up almost half the available RAM on NROM.


Top
 Profile  
 
PostPosted: Sun Sep 22, 2019 1:28 pm 
Offline
User avatar

Joined: Sat Aug 31, 2019 2:12 pm
Posts: 17
pwnskar wrote:
If your char matrix[x,y] is kept in RAM, then this would be that. But I'm guessing you're keeping it in ROM, since it should need 960 bytes for each full screen and keeping it in RAM would take up almost half the available RAM on NROM.

Yep! That's right, I'm keeping it in ROM (in C all I had to do was declare it as const char). :)

_________________
Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group