Skip to main content
Skip to main content

DynamicDataGrid

DynamicDataGrid

Functions

delete

Description

Calls the delete function on every cell, then cleans up.

Definition

delete()

Code

function DynamicDataGrid:delete()

-- Go over each cell in the data.
for columnIndex = self.localStartIndex, self.localEndIndex do
for rowIndex = self.localStartIndex, self.localEndIndex do

-- Get the cell.
local cell = self:getCellFromLocalIndices(columnIndex, rowIndex)

-- If the cell has a delete function, call it.
if cell and cell.delete then
cell:delete()
end
end
end

-- Unset the grid.
self.grid = nil
end

getCellFromWorldPosition

Description

Gets and returns the cell that exists at the given world position.

Definition

getCellFromWorldPosition(float worldX, float worldZ, boolean clamp)

Arguments

floatworldXThe x position in the world.
floatworldZThe z position in the world.
booleanclampTrue if the position should be clamped within the grid; defaults to false.

Return Values

booleancellThe cell at the given position, or nil if none was found.

Code

function DynamicDataGrid:getCellFromWorldPosition(worldX, worldZ, clamp)

-- Calculate the indices.
local xIndex, zIndex = self:getLocalIndicesByWorldPosition(worldX, worldZ)

-- If the indices should be clamped, do so.
if clamp then
xIndex = math.clamp(xIndex, self.localStartIndex, self.localEndIndex)
zIndex = math.clamp(zIndex, self.localStartIndex, self.localEndIndex)
end

-- Get the row.
local xrows = self.grid[ self.centreIndex + xIndex]

-- If the row exists, return the cell at the column on the row.
if xrows ~ = nil then
return xrows[ self.centreIndex + zIndex]
end

-- Return nil if nothing was found.
return nil
end

getGridIndicesByWorldPosition

Description

Gets the grid indices of the given position. The grid index is from 1 - rowColumnCount, essentially allowing the underlying 2D array to be indexed.

Definition

getGridIndicesByWorldPosition(float worldX, float worldZ)

Arguments

floatworldXThe x position in the world.
floatworldZThe z position in the world.

Return Values

floatindexXThe x index of the position.
floatindexZThe z index of the position.

Code

function DynamicDataGrid:getGridIndicesByWorldPosition(worldX, worldZ)

local worldIndexX, worldIndexZ = self:getWorldIndicesByWorldPosition(worldX, worldZ)
local currentIndexX, currentIndexZ = self:getWorldIndicesByWorldPosition( self.lastPosition.x, self.lastPosition.z)

-- Convert the position to an index, then offset it by the centre index to map it to 1 - rowColumnCount.
worldIndexX = (worldIndexX - currentIndexX) + self.centreIndex
worldIndexZ = (worldIndexZ - currentIndexZ) + self.centreIndex

return worldIndexX, worldIndexZ
end

getGridSnappedPosition

Description

Calculates and returns the given position snapped to the grid.

Definition

getGridSnappedPosition(float x, float z)

Arguments

floatxThe x position.
floatzThe z position.

Return Values

floatsnappedXThe snapped x position.
floatsnappedZThe snapped z position.

Code

function DynamicDataGrid:getGridSnappedPosition(x, z)

local snappedX = math.floor(x / self.tileSize) * self.tileSize
local snappedZ = math.floor(z / self.tileSize) * self.tileSize

-- Apply the half cell offset to the position.
snappedX = snappedX + ( self.tileSize / 2.0 )
snappedZ = snappedZ + ( self.tileSize / 2.0 )

return snappedX, snappedZ
end

getLocalIndicesByWorldPosition

Description

Calculates and returns the index relative to the position of the grid, so that the index 0, 0 is the centre of the grid.

Definition

getLocalIndicesByWorldPosition(float worldX, float worldZ)

Arguments

floatworldXThe x position in the world.
floatworldZThe z position in the world.

Return Values

floatindexXThe local x index of the position.
floatindexZThe local z index of the position.

Code

function DynamicDataGrid:getLocalIndicesByWorldPosition(worldX, worldZ)

local currentIndexX, currentIndexZ = self:getWorldIndicesByWorldPosition( self.lastPosition.x, self.lastPosition.z)
local worldIndexX, worldIndexZ = self:getWorldIndicesByWorldPosition(worldX, worldZ)

-- Convert the position to an index.
local localIndexX = (worldIndexX - currentIndexX)
local localIndexZ = (worldIndexZ - currentIndexZ)

return localIndexX, localIndexZ
end

getWorldPositionByLocalIndices

Description

Calculates the world position of the centre of the cell at the position defined by the current position and given cell offset.

Definition

getWorldPositionByLocalIndices(float localIndexX, float localIndexZ)

Arguments

floatlocalIndexXThe x index of the cell relative to the centre cell.
floatlocalIndexZThe z index of the cell relative to the centre cell.

Return Values

floatworldXThe world x position of the centre of the cell.
floatworldZThe world z position of the centre of the cell.

Code

function DynamicDataGrid:getWorldPositionByLocalIndices(localIndexX, localIndexZ)

local currentIndexX, currentIndexZ = self:getWorldIndicesByWorldPosition( self.lastPosition.x, self.lastPosition.z)

-- Return the world position.
return self:getGridSnappedPositionByLocalIndices(currentIndexX + localIndexX, currentIndexZ + localIndexZ)
end

new

Description

Creating dynamic data grid

Definition

new()

Arguments

anysize
anytileSize
anystartX
anystartZ
anycellConstructor
anycustomMt

Code

function DynamicDataGrid.new(size, tileSize, startX, startZ, cellConstructor, customMt)

-- Ensure the arguments are valid.
--#debug assert(size ~ = nil, "Grid size was missing")
--#debug assert(type(size) = = "number", "Grid size was not number")
--#debug assert(size > 0, "Grid size was 0 or lower")

--#debug assert(tileSize ~ = nil, "Tile size was missing")
--#debug assert(type(tileSize) = = "number", "Tile size was not number")
--#debug assert(tileSize > 0, "Tile size was 0 or lower")

--#debug if startX ~ = nil then
--#debug assert(type(startX) = = "number", "Starting x position was not a number")
--#debug assert(startZ ~ = nil, "Starting x position was given, but not z position")
--#debug assert(type(startZ) = = "number", "Starting z position was not a number")
--#debug end
--#debug if startZ ~ = nil then
--#debug assert(startX ~ = nil, "Starting z position was given, but not x position")
--#debug assert(type(startZ) = = "number", "Starting z position was not a number")
--#debug end

--#debug if cellConstructor ~ = nil then
--#debug assert(type(cellConstructor) = = "function", "Given cell constructor was not a function")
--#debug end

-- Create the instance.
local self = setmetatable( { } , customMt or DynamicDataGrid _mt)

-- The size variables.
self.tileSize = tileSize or 1
self.size = size or 20
self.rowColumnCount = math.ceil( self.size / self.tileSize)

-- Calculate the centre index.
self.centreIndex = math.floor( self.rowColumnCount * 0.5 ) + 1
self.localStartIndex = 1 - self.centreIndex
self.localEndIndex = ( self.localStartIndex + self.rowColumnCount) - 1

-- The last set position and its related indices.
self.lastPosition = { x = 0 , z = 0 }

-- Set the positional data if a position was given.
if startX and startZ then
self.lastPosition.x = startX
self.lastPosition.z = startZ
end

-- Keep track of any cells that get moved.
self.movedCells = { }

-- Create the grid.
self.grid = { }
for columnIndex = self.localStartIndex, self.localEndIndex do

-- Create the column.
local column = { }

-- Add each cell to the column.If a constructor was given, use that; otherwise just create an empty table.
for rowIndex = self.localStartIndex, self.localEndIndex do
local cell
if cellConstructor then
local cellWorldX, cellWorldZ = self:getWorldPositionByLocalIndices(columnIndex, rowIndex)
cell = cellConstructor(cellWorldX, cellWorldZ)
else
cell = { }
end
table.insert(column, cell)
end

-- Insert the column into the grid.
table.insert( self.grid, column)
end

-- The y offset.
self.yOffset = 0.05

-- Return the created instance.
return self
end