Log In  


Cart #12063 | 2015-07-30 | Code ▽ | Embed ▽ | No License
18

I got to wondering whether you could rotate a sprite in PICO-8. Of course this facility is not provided, but it should be achievable, I thought.

How this works: 3 rotating objects. Arrows move the green cursor among them, and Z or X to toggle each object on or off.

The rotations are slightly ugly, but I think accurate. Smoothing could probably make them look better, but maybe not at reasonable cost. I don't know! Rotating the large sprite is CPU-intensive (and ugly!). I think for small objects this could be used in a game.

Issues:

  • Sprites are rotated about their top left corner. I think this is needed to guarantee that atan2 is one-to-one. But it would be better to rotate around an arbitrary center!
  • I forgot what the other issues are.
18


1

Doing a quick check of neighboring pixel(s) for color on the resulting black pixel gaps internal could help de-ugly it a little for cheap, I bet.


1

This is neat!

(Also, I'm laughing, because I spent some of today working up a sprite-based asteroids clone that gets around the lack of rotation by making the ship out of two circular pieces.)


You can calculate in reverse. From target position back to pixel of original sprite. I did that in "Pico Wheels" with the cars. Since we're doing this pixel by pixel for all pixels, it is also a good location to add realtime (per pixel) shadow in this loop.

Your method produces black pixels because of rounding pixel coordinate values. A rotated sprite might need more pixels than the original sprite has so iterating available pixels is not enough.

(Note: car.z is for jumping... it is used for shadow and car sprite offset during a jump animation)

car.drw=function()
  local r=flr(car.rot*20)/20
  local s=sin(r)
  local c=cos(r)
  local b=s*s+c*c
  for y=-6,5 do for x=-6,5 do
    local ox=( s*y+c*x)/b
    local oy=(-s*x+c*y)/b
    local col=sget(ox+4,oy+4)
    if col>0 then 
      pset(car.x+x-car.z,car.y+y-car.z,col)
      shadow(car.x+x+1+flr(car.z),car.y+y+1+flr(car.z))
    end
  end end
end

Cart #11341 | 2015-06-20 | Code ▽ | Embed ▽ | No License
25


Very nice!


6

@movAX13h

Your code example was what I was looking for.

Here I abstracted and extended it:

Cart #22489 | 2016-06-08 | Code ▽ | Embed ▽ | No License
6


Well this is promising. A bunch of new doors open if sprite rotation is somewhat easy to implement. How's the overhead on it though? Does it cost a lot to rotate...and what if there are several on the screen, a la Asteroids?


@morningtoas - it's not light by any means, and it will drop you down to 15fps fast.


What about rotating in 45 or 90 degree increments? Would that be less intensive?


Unrotated sprites in cart. On load, move it all to user memory. Each level (or something) grab needed sprites and write rotated versions into the sprite sheets for easy drawing.

Or something like that.


Yeah, if you have a limited number of things that need rotation, it might be a lot better to cache pre-rotated sprites. Keep in mind you can draw through the map and use its flags to flip, so a symmetrical object need only have 90 degrees worth of rotated images.

Also, if you were doing a game like Sega's old Afterburner, you'd simply rotate each sprite once at the start of the frame and then use them all as needed, since they all have the same rot and thus there's no need to rotate a hundred tree sprites individually.


@TonyTheTGR it would be fine if you cache them somehow as @tyroney and @Felice suggest.


I use the following method : sample.
Rendering from the destination area (to avoid holes in the drawing).



[Please log in to post a comment]