Log In  

Turn your 2D game into a 3D game!

That's 50% extra D!
100% guaranteed to work, sometimes, if you're lucky.
Simply paste this into the top of your 2D game, and be the envy of all your 2D coding friends!!!1!1

(OK, I'll stop now.)

This works best for top down games like "Pic-oh mummy!" by @Hokutoy, "Pakutto boy" by @Konimiru (both pictured)
Admittedly it's more of a gimmick/experiment - the result isn't very playable due to not being able to see the whole play area.

I mainly just wanted to see if it would work :)

_={
 map=map,
 spr=spr,
 sspr=sspr,
 pset=pset,
 circ=circ,
 camera=camera,
 cx=0,
 cy=0,
 cyoff=32,
 ch=32,
 d=128,
 ymid=0,
 s2w=function(x,y)
  return (x-_.cx)-64,_.ch,128-(y-_.cy)
 end,
 proj=function(x,y,z)
  local scale=_.d/z
  return x*scale+64,y*scale+_.ymid,scale
 end
}

camera=function(x,y)
 _.cx=x or 0
 _.cy=(y or 0)+_.cyoff
end

camera(0,0)

pset=function(x,y,c)
 local wx,wy,wz=_.s2w(x,y)
 if(wz<1)return
 local px,py=_.proj(wx,wy,wz)
 _.pset(px,py,c)
end

circ=function(x,y,r,c)
 local wx,wy,wz=_.s2w(x,y)
 if(wz<1)return
 local px,py,scale=_.proj(wx,wy,wz)
 _.circ(px,py,r*scale,c)
end

sspr=function(sx,sy,sw,sh,x,y,w,h,fx,fy)
 w=w or sw
 h=h or sh
 local wx,wy,wz=_.s2w(x+w/2,y+h)
 if(wz<1)return
 local px,py,scale=_.proj(wx,wy,wz)
 local pw,ph=w*scale,h*scale

 -- sub pixel stuff
 local x0,x1=flr(px-pw/2),flr(px+pw/2)
 local y0,y1=flr(py-ph),flr(py)

 _.sspr(sx,sy,w,h,x0,y0,x1-x0,y1-y0,fx,fy)
end

spr=function(n,x,y,w,h,fx,fy)
 if(not n or not x or not y)return
 -- convert to equivalent sspr() call
 w=(w or 1)*8
 h=(h or 1)*8
 local sx,sy=flr(n%16)*8,flr(n/16)*8
 sspr(sx,sy,w,h,x,y,w,h,fx,fy)
end

map=function(cx,cy,x,y,w,h,lyr)
 cx=cx or 0
 cy=cy or 0
 x=x or 0
 y=y or 0
 w=w or 128
 h=h or 64

 -- near/far corners
    local fx,fy,fz=_.s2w(x,y)
    local nx,ny,nz=_.s2w(x,y+h*8)

 -- clip
 nz=max(nz,0.5)
 if(fz<=nz)return

 -- project
 local npx,npy,nscale=_.proj(nx,ny,nz)
 local fpx,fpy,fscale=_.proj(fx,fy,fz)

 -- clamp
 npy=min(npy,128)

 -- rasterise
 local py=flr(npy)
 while py>=fpy do

  -- floor plane intercept
        local g=(py-_.ymid)/_.d
        local z=_.ch/g      

        -- map coords
        local mx,my=cx,(fz-z)/8+cy

        -- project to get left/right
        local lpx,lpy,lscale=_.proj(nx,ny,z)
        local rpx,rpy,rscale=_.proj(nx+w*8,ny,z)

        -- delta x
        local dx=w/(rpx-lpx)

        -- sub-pixel correction
        local l,r=flr(lpx+0.5)+1,flr(rpx+0.5)
        mx+=(l-lpx)*dx

  -- render
        tline(l,py,r,py,mx,my,dx,0,lyr)

  py-=1
 end 
end

EDIT 1: adjusted near plane to avoid numeric overflow. Defaults for omitted map() parameters.
EDIT 2: also 3Dise sspr, pset and circ
EDIT 3: sub-pixel logic
EDIT 4: add map() layer parameter. fix gaps between adjacent sprites.

New version!

I've made a new version called Instant 3D plus! :-).
It should behave exactly like the original, but it's cleaned up quite a bit, and you can call the 3D functions directly to fix the bits that it doesn't get right automatically - or place things in exact 3D positions (like up in the air).

More details in the other post.

P#75793 2020-05-04 11:57 ( Edited 2020-05-17 01:05)

2

It's pretty fantastic to see a 2D project in 3D :) Thank you.

...And sometimes it's not so simple haha.

P#75797 2020-05-04 15:09 ( Edited 2020-05-04 15:15)

Brilliant yet fails miserably on any game I tried!

P#75798 2020-05-04 18:00
:: Mot
1

No refunds!

Here's a few more:

"Mazeborn" by @gymcrash

"Lazarus the lizard" by @Truttle1

"Pico sprint" by @Felice

"Escape from squirrel park" by @Nikkei

"Object system demo" by @Saffith

"D-Day" by @projectSAM

P#75815 2020-05-05 00:06 ( Edited 2020-05-05 08:04)
1

I tried it with my project Delve and it turned out really weird

Really cool stuff though, love how simple it is to install.

I also used it on CoinDash and this is amazing!

P#75824 2020-05-05 05:42 ( Edited 2020-05-05 05:52)
2

@Mot Seeing this has 100% made my day. It's the 3D version of D-Day that I always wanted to get round to making. Now I don't have to - thank you! I can't wait to see how the final Hitler boss works in this...

P#75833 2020-05-05 08:43

Love it!

Awesome way to add perspective in a game.

I'll try it!

P#75834 2020-05-05 09:19
:: Mot

@projectSAM - It's a cool looking game. Reminds me of "Commando" or "Ikari Warriors" on the old 8-bit computers.
If you specify the width in tiles when you call map() it should clip off the right hand side, so you get a proper column instead of seeing the whole tilemap.

P#75836 2020-05-05 10:59
:: Mot
1

Adding/modifying a few camera() commands makes 3D "Pakutto Boy" quite playable.

P#75838 2020-05-05 11:17

Hey, this is super cool. I noticed that you're using a table to store the original functions. Could you not save a little table-lookup overhead by using a do end block instead?

do
 local _print=print
 function print(s,x,y,c)
  --fancy 3D version
  _print(s,x,y,c)
 end
end

This way there is no extra cost from dereferencing the table. Regardless, I'm gonna give this a shot as a starter point for a project :)

P#75876 2020-05-05 19:50 ( Edited 2020-05-05 19:51)
:: RyanC

This is really awesome, will definitely have to give it a try.

P#75883 2020-05-05 20:56

Wow, that's really cool! Thanks for trying it out on that little lizard game I made! :)

I wonder what it would look like if the PICO-8 IDE was made 3D...

P#75919 2020-05-06 01:52 ( Edited 2020-05-06 01:53)

I was planning on playing around with this and seeing what can be done with it on a blank project, but it doesn't appear to be working correctly? The perspective is nothing like in the screenshots. All it is doing is panning the camera.

P#75930 2020-05-06 03:04 ( Edited 2020-05-06 03:04)
:: Mot

@Lafolie do you have the latest 0.2.0 version?
There were some tline() issues in earlier versions.
I'm using 0.2.0e (although I noticed 0.2.0f has been released)

P#75931 2020-05-06 03:34

@Mot yeah I'm on 0d... I thought I updated to e though?! Strange. I'll update and get back to you.

P#75932 2020-05-06 03:37

It's a shame that tline doesn't accept the same optional layers attribute map does. Looks rather weird when these lads are flat on the map where there spawn points are defined and also running about.

Not sure what's going on with this one! Funnily enough Sonic does have running animations normally but it's broken here somehow. This is a really old unfinished project though and I don't really remember what most of the drawing code is doing and I don't have the time to dig into it right now.

P#75938 2020-05-06 07:20 ( Edited 2020-05-06 07:24)
:: Mot

@oakreef yeah, I noticed the layers issue too with some of my projects. If a layer parameter was added to the tline() command then it could be done properly.

The sonic one looks like it's not clearing the screen before drawing a frame...? Are you doing something clever, like dirty rectangles?

P#75988 2020-05-06 21:22

It's been ages since I touched that code and I don't want to dig through it now but IIRC I never bothered clearing the screen because the first thing it draws anyway is pink rectangle across the entire screen, which would wipe out the previous frame anyway. The intent was to eventually draw a proper background with parallax but I never got around to it.

P#75989 2020-05-06 21:25 ( Edited 2020-05-07 06:56)
:: Mot
1

Minor tweak to clean up raggedy lines

Before:

After:

P#76017 2020-05-07 07:14
:: NeithR
1

Just tried your code in my Imi's Dungeon game.
It exposes my tile entities xD.

P#76033 2020-05-07 11:50 ( Edited 2020-05-07 11:50)

@Mot it looks like Zep added layers to tline for 0.2.0h!

P#76083 2020-05-07 18:35
:: Mot

@oakreef cool. I've updated the snippet.

@NeithR lol :). Pay no attention to the man behind the curtain...

P#76103 2020-05-07 23:39
2

Not bad! Works decently well on my Breakout game with only one addition for camera()

P#76274 2020-05-09 21:48
:: cubee
2

I remade WoolCat as WoolCat 3D

P#76307 2020-05-10 11:03

Oh my God bless you, this is probably the best thing that has happened to me this whole year you are amazing

P#76436 2020-05-12 11:32
1

Like Jelpi 3d?

P#76437 2020-05-12 11:38
2

I made a quick little game with your Instant3D. Very nice!

P#76453 2020-05-12 17:07
2

Cart #nemuwizey-2 | 2020-05-13 | Code ▽ | Embed ▽ | No License
2
Guys, very simple test. Game-code labirynth like, also for beginners to learn. Code is super easy, if you want to start your own. Can turn into pac-man etc. 3D effect works great!

P#76481 2020-05-13 01:26 ( Edited 2020-05-13 01:34)
1

The one game that I have actually completed gave very amusing results.
Something about the game just hated the 3d code

P#76490 2020-05-13 11:04
2

Very usefull I enjoy it for a future game...

P.s. How about ask ZEP to put that code snippet as internal function in next Pico-8 version? as a poke or an I3D()

this snipped will be very used in the future tough! :)

good for my first 3d racer soon! btw.

P#76502 2020-05-13 15:29 ( Edited 2020-05-14 17:01)
2

This makes my cave game so much more immersive!

I had to add sprites over the top of the map tiles that were walls to "lift" them up. I'm using sprite flags to mark them. I'm going to try and bake that into the function, but it would have to be a second drawing pass because a single map call could included both types.

P#76649 2020-05-15 17:51

@Mot wow, thanks for trying out your great coffee on mazeborn... It's given me some perspective (!) on how my 3d version is going...

P#76910 2020-05-19 16:29
:: garryg

Can you switch this on and off?

I'm making a game that's part overhead map and part side on platform. The map part may benefit from this angle.

P#79219 2020-07-12 20:20
:: Mot

@garryg I made an updated version here with the ability to turn it on/off - plus some other cleanups etc.

P#79222 2020-07-12 21:24

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2021-06-13 17:29:22 | 0.163s | Q:77