Log In  

Cart #spritestack-0 | 2020-07-29 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

Hey all,
I got a lot of questions on how I did the sprite stacking for my train demo, so I put together a simple example.

In short, objects are sliced vertically and drawn accordingly.

Then it's a matter of drawing them on top of each other, offsetting them more and more for each one.

To get the nice voxel/3D effect you also need to rotate the stack. In the example above the rotation function is courtesy of Frederic Souchu

Have fun!

P#80083 2020-07-29 11:17

:: 2358

@johanp This is amazing!

I’ve always been fascinated with this technique.

I’ve seen this effect on a JavaScript game on codepen many years ago called taxi apocalypse:
https://codepen.io/Gthibaud/details/WXxMdb
By https://codepen.io/Gthibaud

I’ve also stumbled across a great online tool to generate these stacked sprites on https://spritestack.io/
example: https://spritestack.io/sprite/1078

Now that I know how it’s done Pico-8, I’m looking forward to experimenting with some game ideas!

P#80116 2020-07-30 04:09
:: 2358

Not sure if this is the right place to ask for help?

I am still learning about pico-8 and game coding in general.

I spent some time using this sprite stack trick to make a 3d pixel art DeLorean, but I cannot figure out how to make it drive around the screen in the direction it is pointing, I've had a look at code from other carts for examples but can't make any sense of it, any help in the right direction would be great!

example of issue:

code I am working with:

function _init()
    dln={}
    dln.angle=0
    dln.x=0
    dln.y=0
end
function _update()
    if (btn(0)) dln.angle-=0.01
    if (btn(1)) dln.angle+=0.01
    if (btn(2)) then
        dln.x -= cos(angle)
        dln.y -= sin(angle)
    end
end
function _draw()
    cls(2)
    newangx=dln.x + cos(dln.angle) * 3
    newangy=dln.y + sin(dln.angle) * 3

--  draw_dln(dln.x+56,dln.y+62,dln.angle)
    draw_dln(newangx+56,newangy+62,dln.angle)

--  debug
    print("a "..dln.angle,1,(8*0))
    print("y "..dln.y,1,(8*1))
    print("x "..dln.x,1,(8*2))
    print("nax "..newangx,1,(8*3))
    print("nay "..newangy,1,(8*4))
end
function draw_dln(x,y,a)
    -- draw stack
    for i=0,6 do
        local sx = 16 * (i%8)
        local sy = 16 * flr(i/8)
        rspr(sx,sy,
            x, y-i*1,
            a, 2)
    end
end
-- sprite rotation by @fsouchu
...
P#80129 2020-07-30 15:46
:: johanp

Hey there @2358,
glad you like it and is putting it to good use!

To be honest, I always stumble on this too, and usually spend 5-10 minutes trying to get it right. The exact thing happened to me when I did the example above! :D

Trig in pico8 doesn't behave exactly like in the real world. From the wiki:
Important: PICO-8 measures the angle in a clockwise direction on the Cartesian plane, with 0.0 to the right, 0.25 downward, and so on. This is inverted from the convention used in traditional geometry, though the inversion only affects sin(), not cos().

In the cart above I've drawn the bus sprite so that it is facing/heading right. To get that working in code, I do this:
draw_bus(
56+40cos(angle), -- direction
64+40
sin(angle), -- direction
-angle-0.25) -- rotation angle

Ie, negate the angle and remove 90 degrees. :D

Oh boy. #honestGameDev

P#80135 2020-07-30 19:38
:: 2358
1

Whoo! it drives! thank you so much! @johanp

I did not realise the orientation was measured like that, but it all makes sense now.

I also messed up on the button angle codes (now fixed), I shouldn't be trying to code so early in the morning while half asleep, so easy to overlook these things.

P#80140 2020-07-30 21:36

@johanp, might want to enclose that tidbit about trigonometry quirks into a code block, "matching" * are treated as italics.

P#80185 2020-07-31 21:52

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2020-08-13 05:55 | 0.071s | 4194k | Q:41