chore(world): extract map module from the world module

Fix #35
This commit is contained in:
Kazhnuz 2019-07-22 22:38:19 +02:00
parent 303b6a7184
commit d8c0e62190
12 changed files with 303 additions and 249 deletions

View file

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Changed
- **world:** extract map module from the world module
## [0.6.0] - 2019-07-20 ## [0.6.0] - 2019-07-20
- Meta: Add proper crediting - Meta: Add proper crediting

View file

@ -26,7 +26,7 @@ local cwd = (...):gsub('%.baseworld$', '') .. "."
local BaseWorld = Object:extend() local BaseWorld = Object:extend()
local Sti = require(cwd .. "libs.sti") local mapObjects = require(cwd .. "maps")
local CameraSystem = require(cwd .. "camera") local CameraSystem = require(cwd .. "camera")
local PADDING_VALUE = 10/100 local PADDING_VALUE = 10/100
@ -34,17 +34,18 @@ local PADDING_VALUE = 10/100
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- All functions to init the world and the map -- All functions to init the world and the map
function BaseWorld:new(scene, actorlist, mapfile) function BaseWorld:new(scene, actorlist, mapfile, maptype)
self.scene = scene self.scene = scene
self.actorlist = actorlist self.actorlist = actorlist
self.mapfile = mapfile self.mapfile = mapfile
self.mapObjects = mapObjects
self.cameras = CameraSystem(self) self.cameras = CameraSystem(self)
self:initActors() self:initActors()
self:initPlayers() self:initPlayers()
self:setActorList(self.actorlist) self:setActorList(self.actorlist)
self:initMap(self.mapfile) self:initMap(self.mapfile, maptype)
self:setGravity() self:setGravity()
self:register() self:register()
@ -60,10 +61,13 @@ function BaseWorld:setActorList(actorlist)
end end
end end
function BaseWorld:initMap(mapfile) function BaseWorld:initMap(mapfile, maptype)
self.haveMap = false if (mapfile ~= nil) then
self.haveBackgroundColor = false self.maptype = maptype or "sti"
self.backcolor = {128, 128, 128} else
self.maptype = "empty"
end
self.mapfile = mapfile self.mapfile = mapfile
end end
@ -83,7 +87,7 @@ end
function BaseWorld:reset() function BaseWorld:reset()
self:initActors() self:initActors()
self:initPlayers() self:initPlayers()
self:initMap(self.mapfile) self:initMap(self.mapfile, self.maptype)
self.cameras:initViews() self.cameras:initViews()
collectgarbage() collectgarbage()
@ -98,11 +102,12 @@ function BaseWorld:initActors( )
self.currentCreationID = 0 self.currentCreationID = 0
end end
function BaseWorld:newActor(name, x, y) function BaseWorld:newActor(name, x, y, z)
self.obj.index[name](self, x, y) self.obj.index[name](self, x, y)
end end
function BaseWorld:newCollision(name, x, y, w, h) function BaseWorld:newCollision(name, x, y, z, w, h, d)
print("Creating collision " .. name .. " at position " .. x .. ";" .. y .. ". Size is " .. w .. ";" .. h)
self.obj.collisions[name](self, x, y, w, h) self.obj.collisions[name](self, x, y, w, h)
end end
@ -216,21 +221,6 @@ end
-- PLAYER MANAGEMENT FUNCTIONS -- PLAYER MANAGEMENT FUNCTIONS
-- Basic function to handle player actors -- Basic function to handle player actors
function BaseWorld:loadMap()
local mapfile = self.mapfile
if mapfile == nil then
self.haveMap = false
self.haveBackgroundColor = false
self.backcolor = {128, 128, 128}
else
self.haveMap = true
self.map = Sti(mapfile)
self.haveBackgroundColor = true
self.backcolor = self.map.backgroundcolor or {128, 128, 128}
self:loadMapObjects()
end
end
function BaseWorld:initPlayers() function BaseWorld:initPlayers()
self.players = {} self.players = {}
self.playerNumber = 1 self.playerNumber = 1
@ -240,15 +230,21 @@ function BaseWorld:setPlayerNumber(playerNumber)
self.playerNumber = playerNumber or 1 self.playerNumber = playerNumber or 1
end end
function BaseWorld:addPlayer(actor, sourceid) function BaseWorld:addPlayer(x, y, z, id)
local player = {} local player = {}
player.actor = actor if id <= self.playerNumber then
player.actor = self:newPlayer(x, y, z)
player.sourceid = sourceid or 1 player.sourceid = sourceid or 1
table.insert(self.players, player) table.insert(self.players, player)
self.cameras:addTarget(player.actor) self.cameras:addTarget(player.actor)
end end
end
function BaseWorld:newPlayer(x, y, z)
return self.obj.Player(self, x, y)
end
function BaseWorld:sendInputToPlayers(actor) function BaseWorld:sendInputToPlayers(actor)
for i,v in ipairs(self.players) do for i,v in ipairs(self.players) do
@ -269,112 +265,55 @@ end
-- MAP FUNCTIONS -- MAP FUNCTIONS
-- All map wrappers -- All map wrappers
function BaseWorld:loadMap()
self:createMapController()
self:loadMapObjects()
end
function BaseWorld:createMapController()
if (self.maptype == "empty") then
self.mapObjects.Base(self)
elseif (self.maptype == "sti") then
self.mapObjects.Sti(self, self.mapfile)
end
end
function BaseWorld:loadMapObjects() function BaseWorld:loadMapObjects()
self:loadMapCollisions() if (self.map ~= nil) then
self:loadMapPlayers() self.map:loadObjects()
self:loadMapActors()
end
function BaseWorld:loadMapCollisions()
for k, objectlayer in pairs(self.map.layers) do
if self:isCollisionIndexed(objectlayer.name) then
print("DEBUG: loading actors in " .. objectlayer.name .. " collision layer")
for k, object in pairs(objectlayer.objects) do
self:newCollisionFromMap(objectlayer, object)
end
self.map:removeLayer(objectlayer.name)
end
end
end
function BaseWorld:loadMapActors()
for k, objectlayer in pairs(self.map.layers) do
if self:isActorIndexed(objectlayer.name) then
print("DEBUG: loading actors in " .. objectlayer.name .. " actor layer")
for k, object in pairs(objectlayer.objects) do
if (object.properties.batchActor) then
self:batchActor(objectlayer, object)
else
self:newActorFromMap(objectlayer, object)
end
end
self.map:removeLayer(objectlayer.name)
end
end
end
function BaseWorld:batchActor(objectlayer, object)
local name = objectlayer.name
local gwidth = object.properties.gwidth or self.map.tilewidth
local gheight = object.properties.gheight or self.map.tileheight
local x = object.x
local y = object.y
local w = object.width
local h = object.height
local cellHor = math.ceil(w / gwidth)
local cellVert = math.ceil(h / gheight)
for i=1, cellHor do
for j=1, cellVert do
self:newActor(name, x + (i-1)*gwidth, y + (j-1)*gheight)
end
end
end
function BaseWorld:newActorFromMap(objectlayer, object)
self:newActor(objectlayer.name, object.x, object.y)
end
function BaseWorld:newCollisionFromMap(objectlayer, object)
self:newCollision(objectlayer.name, object.x, object.y, object.width, object.height)
end
function BaseWorld:addPlayerFromMap(object, i)
self:addPlayer(self.obj.Player(self, object.x, object.y), i)
end
function BaseWorld:loadMapPlayers()
for k, objectlayer in pairs(self.map.layers) do
if (objectlayer.name == "player") then
print("DEBUG: loading actors in player layer")
local i = 1
for k, object in pairs(objectlayer.objects) do
if (i <= self.playerNumber) then
-- TODO: don't hardcode camera handling
self:addPlayerFromMap(object, i)
end
i = i + 1
end
self.map:removeLayer(objectlayer.name)
end
end end
end end
function BaseWorld:getDimensions() function BaseWorld:getDimensions()
if self.haveMap then if (self.map ~= nil) then
return self.map.width * self.map.tilewidth, return self.map:getDimensions()
self.map.height * self.map.tileheight
else else
return core.screen:getDimensions() return core.screen:getDimensions()
end end
end end
function BaseWorld:setBackgroundColor(r, g, b) function BaseWorld:setBackgroundColor(r, g, b)
self.backcolor = {r, g, b} if (self.map ~= nil) then
self.haveBackgroundColor = true self.map:setBackgroundColor(r, g, b)
end
end end
function BaseWorld:removeBackgroundColor() function BaseWorld:removeBackgroundColor()
self.haveBackgroundColor = false if (self.map ~= nil) then
self.map:setBackgroundColor()
end
end end
function BaseWorld:getBackgroundColor() function BaseWorld:getBackgroundColor()
return self.backcolor[1]/256, self.backcolor[2]/256, self.backcolor[3]/256 if (self.map ~= nil) then
return self.map:getBackgroundColor()
else
return 0, 0, 0
end
end end
function BaseWorld:resizeMap(w, h) function BaseWorld:resizeMap(w, h)
if self.haveMap then if (self.map ~= nil) then
local w, h = utils.math.floorCoord(w, h) local w, h = utils.math.floorCoord(w, h)
self.map:resize(w, h) self.map:resize(w, h)
end end
@ -413,12 +352,11 @@ function BaseWorld:updateActors(dt)
end end
function BaseWorld:updateMap(dt) function BaseWorld:updateMap(dt)
if self.haveMap then if (self.map ~= nil) then
self.map:update(dt) self.map:update(dt)
end end
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS
-- All function to draw the map, world and actors -- All function to draw the map, world and actors
@ -448,21 +386,14 @@ function BaseWorld:drawActors(id)
end end
function BaseWorld:drawMap(id) function BaseWorld:drawMap(id)
if self.haveMap then if (self.map ~= nil) then
for _, layer in ipairs(self.map.layers) do self.map:draw()
if layer.visible and layer.opacity > 0 and (layer.type == "tilelayer") then
self.map:drawLayer(layer)
end
end
end end
end end
function BaseWorld:drawBackgroundColor() function BaseWorld:drawBackgroundColor()
if self.haveBackgroundColor then if (self.map ~= nil) then
local r, g, b = self.backcolor[1], self.backcolor[2], self.backcolor[3] self.map:drawBackgroundColor()
love.graphics.setColor(r/256, g/256, b/256)
love.graphics.rectangle("fill", 0, 0, 480, 272)
utils.graphics.resetColor()
end end
end end

View file

@ -0,0 +1,7 @@
local cwd = (...):gsub('%.init$', '') .. "."
local mapObjects = {}
mapObjects.Sti = require(cwd .. "sti")
mapObjects.Base = require(cwd .. "parent")
return mapObjects

View file

@ -0,0 +1,81 @@
local ParentMap = Object:extend()
-- INIT FUNCTION
-- Initialize the map
function ParentMap:new(world, r, g, b)
self.world = world
local r = r or 128
local g = g or 128
local b = b or 128
self.backgroundColor = {r, g, b}
self:register()
end
function ParentMap:register()
self.world.map = self
end
-- UPDATE FUNCTION
-- Update or modify the map
function ParentMap:resize(w, h)
-- Empty Placeholder function
end
function ParentMap:update(dt)
-- Empty Placeholder function
end
function ParentMap:loadObjects()
self:loadCollisions()
self:loadPlayers()
self:loadActors()
end
function ParentMap:loadCollisions()
-- Empty Placeholder function
end
function ParentMap:loadPlayers()
-- Empty Placeholder function
end
function ParentMap:loadActors()
-- Empty Placeholder function
end
function ParentMap:setBackgroundColor(r, g, b)
local r = r or 128
local g = g or 128
local b = b or 128
self.backgroundColor = {r, g, b}
end
function ParentMap:setBackgroundColorFromTable(backgroundColor)
self.backgroundColor = backgroundColor or {128, 128, 128}
end
function ParentMap:getBackgroundColor()
return self.backgroundColor[1]/256, self.backgroundColor[2]/256, self.backgroundColor[3]/256
end
function ParentMap:getDimensions()
return core.screen:getDimensions()
end
function ParentMap:getBox()
local w, h = self:getDimensions()
return 0, 0, w, h
end
function ParentMap:drawBackgroundColor()
local r, g, b = self.backgroundColor[1], self.backgroundColor[2], self.backgroundColor[3]
love.graphics.setColor(r/256, g/256, b/256)
love.graphics.rectangle("fill", 0, 0, 480, 272)
utils.graphics.resetColor()
end
return ParentMap

View file

@ -0,0 +1,149 @@
local cwd = (...):gsub('%.sti$', '') .. "."
local Parent = require(cwd .. "parent")
local STI = require(cwd .. "libs.sti")
local StiMap = Parent:extend()
function StiMap:new(world, mapfile)
self.sti = STI(mapfile)
StiMap.super.new(self, world)
self:setBackgroundColorFromTable(self.sti.backgroundcolor)
end
function StiMap:getDimensions()
return self.sti.width * self.sti.tilewidth,
self.sti.height * self.sti.tileheight
end
-- UPDATE FUNCTION
-- Update or modify the map
function StiMap:resize(w, h)
self.sti:resize(w, h)
end
function StiMap:update(dt)
self.sti:update(dt)
end
-- LOADING FUNCTION
-- Load actors directly into the world
function StiMap:loadCollisions()
for k, objectlayer in pairs(self.sti.layers) do
if self.world:isCollisionIndexed(objectlayer.name) then
print("DEBUG: loading actors in " .. objectlayer.name .. " collision layer")
for k, object in pairs(objectlayer.objects) do
self:newCollision(objectlayer, object)
end
self.sti:removeLayer(objectlayer.name)
end
end
end
function StiMap:loadActors()
for k, objectlayer in pairs(self.sti.layers) do
if self.world:isActorIndexed(objectlayer.name) then
print("DEBUG: loading actors in " .. objectlayer.name .. " actor layer")
for k, object in pairs(objectlayer.objects) do
if (object.properties.batchActor) then
self:batchActor(objectlayer, object)
else
self:newActor(objectlayer, object)
end
end
self.sti:removeLayer(objectlayer.name)
end
end
end
function StiMap:loadPlayers()
for k, objectlayer in pairs(self.sti.layers) do
if (objectlayer.name == "player") then
print("DEBUG: loading actors in player layer")
local i = 1
for k, object in pairs(objectlayer.objects) do
self:newPlayer(object, i)
i = i + 1
end
self.sti:removeLayer(objectlayer.name)
end
end
end
function StiMap:batchActor(objectlayer, object)
local name = objectlayer.name
local gwidth = object.properties.gwidth or self.sti.tilewidth
local gheight = object.properties.gheight or self.sti.tileheight
local x = object.x
local y = object.y
local z = object.properties.z or 0
local w = object.width
local h = object.height
local cellHor = math.ceil(w / gwidth)
local cellVert = math.ceil(h / gheight)
for i=1, cellHor do
for j=1, cellVert do
print("DEBUG:", "Setting the world to create actor " .. name)
self.world:newActor(name, x + (i-1)*gwidth, y + (j-1)*gheight, z)
end
end
end
function StiMap:newActor(objectlayer, object)
local z = object.properties.z or 0
local adaptPosition = object.properties.adaptPosition or false
local y = object.y
if (adaptPosition) then
y = y + z
end
print("DEBUG:", "Setting the world to create actor " .. objectlayer.name)
self.world:newActor(objectlayer.name, object.x, y, z)
end
function StiMap:newCollision(objectlayer, object)
local z = object.properties.z or 0
local d = object.properties.d or 16
local fromTop = object.properties.fromTop or false
local y = object.y
if (fromTop) then
print("create from top, set z and y:", z, y, "=>", z-d, y+z)
y = y + z
z = z - d
end
print("DEBUG:", "Setting the world to create collision " .. objectlayer.name)
self.world:newCollision(objectlayer.name, object.x, y, z, object.width, object.height, d)
end
function StiMap:newPlayer(object, i)
local z = object.properties.z or 0
local adaptPosition = object.properties.adaptPosition or false
local y = object.y
if (adaptPosition) then
y = y + z
end
print("DEBUG:", "Setting the world to create player " .. i)
self.world:addPlayer(object.x, y, z, i)
end
-- DRAW FUNCTIONS
-- Draw the map
function StiMap:draw()
for _, layer in ipairs(self.sti.layers) do
if layer.visible and layer.opacity > 0 and (layer.type == "tilelayer") then
self.sti:drawLayer(layer)
end
end
end
return StiMap

View file

@ -26,7 +26,6 @@ local cwd = (...):gsub('%.world2D$', '') .. "."
local BaseWorld = require(cwd .. "baseworld") local BaseWorld = require(cwd .. "baseworld")
local World2D = BaseWorld:extend() local World2D = BaseWorld:extend()
local Sti = require(cwd .. "libs.sti")
local Bump = require(cwd .. "libs.bump") local Bump = require(cwd .. "libs.bump")
local CameraSystem = require(cwd .. "camera") local CameraSystem = require(cwd .. "camera")
@ -43,14 +42,6 @@ function World2D:initActors()
self.bodies = Bump.newWorld(50) self.bodies = Bump.newWorld(50)
end end
function World2D:newActor(name, x, y)
self.obj.index[name](self, x, y)
end
function World2D:newCollision(name, x, y, w, h)
self.obj.collisions[name](self, x, y, w, h)
end
function World2D:registerActor(actor) function World2D:registerActor(actor)
World2D.super.registerActor(self, actor) World2D.super.registerActor(self, actor)
end end
@ -72,53 +63,6 @@ function World2D:getActorsInRect(x, y, w, h)
return returnquery return returnquery
end end
-- PLAYER FUNCTIONS
-- Load player stuff
function World2D:addPlayer(actor, sourceid, haveCam)
local player = {}
player.actor = actor
player.sourceid = sourceid or 1
table.insert(self.players, player)
self.cameras:addTarget(player.actor)
end
-- MAP LOADING FUNCTIONS
-- Handle loading of actors from map
function World2D:batchActor(objectlayer, object)
local name = objectlayer.name
local gwidth = object.properties.gwidth or self.map.tilewidth
local gheight = object.properties.gheight or self.map.tileheight
local x = object.x
local y = object.y
local w = object.width
local h = object.height
local cellHor = math.ceil(w / gwidth)
local cellVert = math.ceil(h / gheight)
for i=1, cellHor do
for j=1, cellVert do
self:newActor(name, x + (i-1)*gwidth, y + (j-1)*gheight)
end
end
end
function World2D:newActorFromMap(objectlayer, object)
self:newActor(objectlayer.name, object.x, object.y)
end
function World2D:newCollisionFromMap(objectlayer, object)
self:newCollision(objectlayer.name, object.x, object.y, object.width, object.height)
end
function World2D:addPlayerFromMap(object, i)
self:addPlayer(self.obj.Player(self, object.x, object.y), i)
end
-- BODIES MANAGEMENT FUNCTIONS -- BODIES MANAGEMENT FUNCTIONS
-- Basic function to handle bodies. Wrappers around Bump2D functions -- Basic function to handle bodies. Wrappers around Bump2D functions

View file

@ -26,7 +26,6 @@ local cwd = (...):gsub('%.world3D$', '') .. "."
local BaseWorld = require(cwd .. "baseworld") local BaseWorld = require(cwd .. "baseworld")
local World3D = BaseWorld:extend() local World3D = BaseWorld:extend()
local Sti = require(cwd .. "libs.sti")
local Bump = require(cwd .. "libs.bump") local Bump = require(cwd .. "libs.bump")
local Bump3D = require(cwd .. "libs.bump-3dpd") local Bump3D = require(cwd .. "libs.bump-3dpd")
local Tsort = require(cwd .. "libs.tsort") local Tsort = require(cwd .. "libs.tsort")
@ -90,69 +89,8 @@ end
-- PLAYER FUNCTIONS -- PLAYER FUNCTIONS
-- Load player stuff -- Load player stuff
function World3D:addPlayer(actor, sourceid, haveCam) function World3D:newPlayer(x, y, z)
local player = {} return self.obj.Player(self, x, y, z)
player.actor = actor
player.sourceid = sourceid or 1
table.insert(self.players, player)
self.cameras:addTarget(player.actor)
end
-- MAP LOADING FUNCTIONS
-- Handle loading of actors from map
function World3D:batchActor(objectlayer, object)
local name = objectlayer.name
local gwidth = object.properties.gwidth or self.map.tilewidth
local gheight = object.properties.gheight or self.map.tileheight
local x = object.x
local y = object.y
local z = object.properties.z or 0
local w = object.width
local h = object.height
local cellHor = math.ceil(w / gwidth)
local cellVert = math.ceil(h / gheight)
for i=1, cellHor do
for j=1, cellVert do
self:newActor(name, x + (i-1)*gwidth, y + (j-1)*gheight, z)
end
end
end
function World3D:newActorFromMap(objectlayer, object)
local z = object.properties.z or 0
local adaptPosition = object.properties.adaptPosition or false
local y = object.y
if (adaptPosition) then
y = y + z
end
self:newActor(objectlayer.name, object.x, y, z)
end
function World3D:newCollisionFromMap(objectlayer, object)
local z = object.properties.z or 0
local d = object.properties.d or 16
local fromTop = object.properties.fromTop or false
local y = object.y
if (fromTop) then
print("create from top, set z and y:", z, y, "=>", z-d, y+z)
y = y + z
z = z - d
end
self:newCollision(objectlayer.name, object.x, y, z, object.width, object.height, d)
end
function World3D:addPlayerFromMap(object, i)
local z = object.properties.z or 0
self:addPlayer(self.obj.Player(self, object.x, object.y, z), i)
end end
-- BODIES MANAGEMENT FUNCTIONS -- BODIES MANAGEMENT FUNCTIONS