Created
April 21, 2017 20:53
-
-
Save MattMcFarland/230280295e1b9ef8004380051ca7f85c to your computer and use it in GitHub Desktop.
pico8 - random dungeon
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Copyright(c) Matt McFarland - 2017 | |
-- MIT LICENSE | |
-- This will create rooms using the BSP method | |
rooms = {} | |
function _init() | |
local main_container = container(0, 6, 127, 121) | |
local max_depth = 6 | |
local container_tree = split_container(main_container, max_depth) | |
cls() | |
square = 1 | |
--add a function to room | |
--which updates the map | |
foreach(rooms, function (room) | |
room:paint() | |
end) | |
--use paths for map | |
paths(container_tree) | |
container_tree:paint() | |
end | |
function tree(leaf) | |
return { | |
leaf=leaf, | |
lchild=nil, | |
rchild=nil, | |
paint=function(self) | |
self.leaf:paint() | |
if (self.lchild ~= nil) then | |
self.lchild:paint() | |
end | |
if (self.rchild ~= nil) then | |
self.rchild:paint() | |
end | |
end | |
} | |
end | |
function paths(t) | |
if (nil == t.lchild or nil == t.rchild) return | |
t.lchild.leaf:path(t.rchild.leaf) | |
paths(t.lchild) | |
paths(t.rchild) | |
end | |
function container(x, y, w, h) | |
-- create a container cell | |
-- it may be discarded | |
local c = { | |
x=flr(x), y=flr(y), | |
w=flr(w), h=flr(h), | |
} | |
c.cx=c.x+flr(c.w/2) | |
c.cy=c.y+flr(c.h/2) | |
function c:paint() | |
rect( | |
self.x, self.y, | |
self.x + self.w, | |
self.y + self.h, | |
7 | |
) | |
end | |
function c:path(o) | |
line( | |
self.cx, | |
self.cy, | |
o.cx, | |
o.cy, | |
5 | |
) | |
end | |
return c | |
end | |
function make_room(c) | |
if (nil == c) return | |
-- create and add room from | |
-- the given container's info | |
local r = {} | |
local padding = 3 | |
r.x=c.x + padding | |
r.y=c.y + padding | |
r.w=c.w - padding * 2 | |
r.h=c.h - padding * 2 | |
function r:paint() | |
rectfill( | |
self.x, self.y, | |
self.x + self.w, | |
self.y + self.h, | |
3 | |
) | |
end | |
add(rooms, r) | |
end | |
-- "random split" a container | |
function r_split(cont) | |
local r1 = nil | |
local r2 = nil | |
if (rint(0,1) == 1) then | |
r1 = container( | |
cont.x, cont.y, | |
rint(1, cont.w), cont.h | |
) | |
r2 = container( | |
cont.x + r1.w, cont.y, | |
cont.w - r1.w, cont.h | |
) | |
if (r1.w / r1.h < 0.45 or r2.w / r2.h < 0.45) then | |
return r_split(cont) | |
end | |
else | |
r1 = container( | |
cont.x, cont.y, | |
cont.w, rint(1, cont.h) | |
) | |
r2 = container( | |
cont.x, cont.y + r1.h, | |
cont.w, cont.h - r1.h | |
) | |
if (r1.h / r1.w < 0.45 or r2.h / r2.w < 0.45) then | |
return r_split(cont) | |
end | |
end | |
return r1, r2 | |
end | |
function split_container(c, iter) | |
local root = tree(c) | |
if (iter ~= 0) then | |
local sr1, sr2 = r_split(c) | |
root.lchild = split_container(sr1, iter-1) | |
root.rchild = split_container(sr2, iter-1) | |
-- when we reach the end, | |
-- add rooms to the containers | |
if (iter == 1) then | |
make_room(sr1) | |
make_room(sr2) | |
end | |
end | |
return root | |
end | |
function rint(a, b) | |
return flr(rnd(b+1) + a) | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment