Update:
added function fixstages to TMap class, for prevent unreachable platforms from pattern in stage. Implementation is very simple and you can extend method as you wich. Currently is checked only "platform" tile id.
Method:
From generated POI point is created connection to free edge in stage and remove platform tiles between connected stages if exist.
This example show procedural level building combined from two method:
1) maze generator - for wall
2) predefined pattern - for stages (platform, ladder, obstacles, ...)
Every room is created from 2x2 stage, and stage is defined in sprite as template, where color index = tile id descibed in data structure:
self.template[0] = {name="empty" ,color=1,tile=self.starttile+0,probability=1.0} self.template[1] = {name="wall" ,color=2,tile=self.starttile+1,probability=1.0} self.template[2] = {name="platform" ,color=3,tile=self.starttile+2,probability=1.0} self.template[3] = {name="breakable",color=4,tile=self.starttile+3,probability=0.5} self.template[4] = {name="obstacle" ,color=5,tile=self.starttile+4,probability=0.5} self.template[5] = {name="ladder" ,color=6,tile=self.starttile+5,probability=1.0} self.template[6] = {name="item" ,color=7,tile=self.starttile+6,probability=0.5} self.template[7] = {name="exit" ,color=8,tile=self.starttile+7,probability=1.0} self.template[8] = {name="hazard" ,color=9,tile=self.starttile+8,probability=1.0} |
Maze is generated in stages count and walls are implemebted as wall to stage.
Control
[z] = generate new maze with wall
[x] = generate new order of patterns in stages
arrow=scroll map
Hi
here is my next cartridge which is combination of my previous Cellular automata class and Marching squares technique for generate procedural platform or top-down levels.
Control:
[z] tileset type #1
[x] tileset type #2
[arrows] scroll map
Note: source code is't optimized for tokens for now
AndyGFX
Hellou,
I think this is a very useful for everyone, who want create procedural maps.
Press Z key few times for smooth 'caves'.
EDIT: example is now as class.
How to:
... cave = TCellular:New() cave:Generate(128,116,0.6,4,5,5) ... function DrawMap() for xm=1,cave._w do for ym=1,cave._h do if (cave:Map(xm,ym)==0) pset(xm,ym,0) if (cave:Map(xm,ym)==1) pset(xm,ym,7) end end end ... |
AndyGFX.
Hi,
here is example how to write lua code more as OOP using metatable and user defined callbacks for update and draw per actor.
Note: Plane sprite is created as sprite 2x1 on sprite id 1 and 2.
-- Actors+Actor CLASSes -- andygfx - cubesteam - 2016 -- Define TActors container class --------------------------------------------- TActors = {} -- TActors CONSTRUCTOR function TActors:New() o = { list={} } setmetatable(o, self) self.__index = self return o end -- TActors methods ------------------------------------------------------------ -- add actor to Actors list function TActors:Add(actor) add(self.list,actor) end -- delete actor from Actors list function TActors:Del(actor) del(self.list,actor) end -- return count of actors in list function TActors:Count() return #self.list end -- call user defined update method on all actors in list function TActors:Update() for a in all(self.list) do if a.enable then a:update() end end end -- call user defined draw method on all actors in list function TActors:Draw() for a in all(self.list) do if a.enable then a:draw() end end end -- Define TActor class -------------------------------------------------------- TActor = {} -- TActor CONSTRUCTOR --------------------------------------------------------- function TActor:New() o = { name="actor", enable=true, visible=true, x = 0, y = 0, _x = 0, _y = 0, sprite = 0, sx = 1, sy = 1, dx = 0, dy = 0, update = function() end, draw = function() end } setmetatable(o, self) self.__index = self return o end -- METHODS -- set actor fields function TActor:Set(name,sprID,x,y,w,h,dx,dy) self.name=name self.sprite=sprID self.x=x self.y=y self._x=x self._y=y self.sx=w self.sy=h self.dx=dx self.dy=dy end -- set actor update and draw callback function TActor:SetCallback(fncUpdate,fncDraw) self.update = fncUpdate self.draw = fncDraw end -- respawn acgtor to start position function TActor:Respawn() self.x=self._x self.y=self._y end -- pico8 callbacks ------------------------------------------------------------ function _init() end function _update() Actors:Update() end function _draw() cls() Actors:Draw() end -- TEST ACTORS ---------------------------------------------------------------- -- create Actors container Actors=TActors:New() -- user defined UPDATE callback for actor function UpdatePlane(self) self.x+=self.dx self.y+=self.dy if self.x>128 then self:Respawn() end end -- user defined DRAW callback fro actor function DrawPlane(self) spr(self.sprite,self.x,self.y,self.sx,self.sy) end -- create actor#1 plane1 = TActor:New() plane1:Set("plane1",1,10,20,2,1,1,0) plane1:SetCallback(UpdatePlane,DrawPlane) Actors:Add(plane1) -- create actor#2 plane2 = TActor:New() plane2:Set("plane2",1,10,35,2,1,2,0) plane2:SetCallback(UpdatePlane,DrawPlane) Actors:Add(plane2) -- create actor#3 plane3 = TActor:New() plane3:Set("plane3",1,10,50,2,1,3,0) plane3:SetCallback(UpdatePlane,DrawPlane) Actors:Add(plane3) |