Pico-8 Bach Inventions Effects ~ Day 5: Rotating Crown (Patreon)
Content
Hi everyone!
Today we're looking at Bach's rotating crown and how I implemented it!
First off, you need two crown sprites, one for the outside of the crown and one for the inside. I set them side by side, but you can put one under the other. (or anywhere else, but these positions are good because it's easy to get from one to the other in terms of coordinates)
Let's draw that crown now! First off, we use camera(-x,-y) to choose where the center of the crown will be on screen.
In this portrait, the crown takes up 40 pixels in width on-screen. (for no reason other than it seemed like the right size) So we'll start with a 'for' loop with x going from 0 to 39.
For each value of x, we will draw a vertical slice of the inside of the crown, and then a vertical slice of the inside for the crown. The inside will be drawn higher and the inside lower, to give an impression of perspective.
But here comes the trouble. We're getting to the point where we need to figure out the height offset for every slice of crown to make it look circular. And then we need to find which slice of the sprite to draw for each x value.
I scratched my head on this for longer than I'd care to admit when making this portrait and eventually fell back to keeping it super simple even if it meant it would be less convincing.
What I did is I used 'x/40*0.5' as angle for a sin() call that would give me the height offset for each new slice. And for finding the sprite slice, I went with the simplest solution possible: sx=(x/40*64+dt)%64. No trigonometry, we just take the x value, divide it by 40 (the width on-screen) and multiply it by 64 (the sprite's width).
Before deciding to go with that, I fumbled with trigonometry for a long while to no avail. In the end, I figured that to do this properly, I would need an 'arc cos' function, which would give me the proper angle for both my height offset calculations and my sprite slice approximation. However this function is absent from the Pico-8 API.
Two hours ago, it occurred to me that the formula 'cos(a)²+sin(a)²=1' could be used to make a custom acos() function. It's too late now, but maybe I'll get another occasion to try that out!
Anyway, here's the final code!
<code>local dt=t*30
camera(-x,-y)
for x=0,39 do
local y=4.5*sin(x/40*0.5)
local sx=(x/40*64+dt)%64 --outside of the crown
local sxb=(x/40*64-dt)%64 --inside of the crown
sspr(sxb+64,24,1,32,x,y) --24 is the y coordinate of the
sspr(sx,24,1,32,x,-y) -- sprite in the sprite-sheet
end
</code>
Thank you for reading! I hope this was informative!
As usual, the downloads for this portrait are available to my 5$+ supporters over there!
Take care!
TRASEVOL_DOG