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.
P#12064 2015-07-30 19:30 ( Edited 2016-06-12 14:33)

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.

P#12066 2015-07-30 21:11 ( Edited 2015-07-31 01:11)
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.)

P#12069 2015-07-30 21:27 ( Edited 2015-07-31 01:27)

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

P#12070 2015-07-30 21:39 ( Edited 2015-07-31 01:56)

Very nice!

P#12071 2015-07-30 21:57 ( Edited 2015-07-31 01:57)
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

P#22490 2016-06-08 02:16 ( Edited 2016-06-08 06:16)

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?

P#22512 2016-06-08 10:12 ( Edited 2016-06-08 14:12)

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

P#22514 2016-06-08 10:24 ( Edited 2016-06-08 14:24)

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

P#22532 2016-06-08 17:32 ( Edited 2016-06-08 21:32)

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.

P#22534 2016-06-08 17:56 ( Edited 2016-06-08 21:56)

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.

P#22544 2016-06-09 03:17 ( Edited 2016-06-09 07:18)

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

P#22550 2016-06-09 12:22 ( Edited 2016-06-09 16:22)

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

P#22758 2016-06-12 10:33 ( Edited 2016-06-12 14:34)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-19 02:29:58 | 0.057s | Q:42