jarcane / minicosm

A FP-oriented game engine inspired by universe.rkt, written in Clojurescript
24 stars 2 forks source link

Apply Transforms to all DDN Primitives #11

Closed CaptainLexington closed 4 years ago

CaptainLexington commented 4 years ago

I just want to say I'm really excited about this project. I love the architectural simplicity! I thought I would make a suggestion for #3 and #4, although it doesn't follow your line of thought. I created a new function, render-with-transforms!, that every DDN primitive (i.e. everything but :group) calls when it does its final draw step. It passes this draw step as a lambda to the render-with-transforms!, which then inspects the DDN's attributes for :pos for translation, :rotate and :pivot for rotating around some point, and :scale. It provides defaults for each of these such that the API doesn't break - demo.cljs hasn't been changed and the output seems identical. However, any of these primitives can now be scaled, rotated around a pivot, or translated, without duplicated code.

There are some small surprises:

I tested this with every element type in demo.cljs but with no others.

Please feel free to nitpick any style or architecture issues you may have.

jarcane commented 4 years ago

Hi! My apologies for being slow on the uptake with your PR!

I really like this. The solution is elegant, looks like it doesn't have any serious performance implications, and actually does more than my original spec. :D Very cool.

Do you think you could add some info about the new properties to the DDN documentation in the README? Otherwise I'm quite happy to accept this. ^-^

CaptainLexington commented 4 years ago

No worries! I'm glad you liked it. I updated the PR with the README changes and I added transform support for :group because it seems like a natural way to express multiple viewports, or composite sprites (like QWOP or something). This did mean I could no longer reset the transform to a constant after every render - I have to step back each transformation individually, which does involve computing the inverse of the scale value by dividing one by it, which seems like the most expensive operation I've introduced. I'm far from an optimization expert, however. The demo still runs fine!

jarcane commented 4 years ago

Looks good to me! Thanks so much for the contribution!