Got a worm prototype running

This commit is contained in:
2024-12-01 20:45:45 -06:00
parent edde009c75
commit ddea65d995

View File

@@ -0,0 +1,136 @@
local LoveNode = require 'src.utils.love_node'
local vector = require 'packages.vector-light'
local lume = require 'packages.lume'
local random = require 'src.utils.random'
local Timer = require 'packages.timer'
local debugDirs = {}
local Worm = {}
Worm.__index = Worm
local directions = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } }
function Worm.new(game)
setmetatable(Worm, { __index = LoveNode })
local self = setmetatable(LoveNode.new(), Worm)
self.game = game
self.stats = {
spawnDistanceFromPlayer = 5 * TILE_SIZE,
moveDelay = 1, -- Seconds between movement steps
tailLength = 5
}
self.size = {}
self.size.w, self.size.h = TILE_SIZE, TILE_SIZE -- self.texture:getDimensions()
self.isEnemy = true
self.tail = {}
local startingPos = self:_findSpawnPoint()
table.insert(self.tail, { startingPos.x, startingPos.y })
self.game.world:add(self.tail[1], startingPos.x, startingPos.y, self.size.w, self.size.h)
self.nextDirections = self:_findOpenDirections()
if #self.nextDirections > 0 then
self.forwardDirection = lume.randomchoice(self.nextDirections)
end
self.timer = Timer.new()
self.timer:every(self.stats.moveDelay, function() self:_move() end)
return self
end
function Worm:update(dt)
self.timer:update(dt)
end
function Worm:draw()
-- Draw worm body
love.graphics.setColor(0.88, 0.22, 0.88)
for _, node in ipairs(self.tail) do
local x, y = unpack(node)
local cx, cy = x + (self.size.w / 2), y + (self.size.h / 2)
love.graphics.circle('fill', cx, cy, TILE_SIZE / 2)
end
-- Debug draw potential collisions
-- love.graphics.setColor(0.88, 0.22, 0.22, 0.8)
-- for _, d in ipairs(debugDirs) do
-- if (d.pos) then
-- love.graphics.rectangle('fill', d.pos.x, d.pos.y, d.size.w, d.size.h)
-- else
-- love.graphics.circle('fill', d[1], d[2], 4)
-- end
-- end
-- local cx, cy = self:getCenter()
-- love.graphics.setColor(0.88, 0, 0)
-- for _, dir in ipairs(directions) do
-- local dx, dy = unpack(dir)
-- local x, y = cx + (dx * TILE_SIZE), cy + (dy * TILE_SIZE)
-- love.graphics.circle('line', x, y, 2)
-- end
-- Debug draw center
-- love.graphics.setColor(1, 1, 1)
-- love.graphics.circle('fill', cx, cy, 4)
end
function Worm:getCenter()
local headX, headY = unpack(self.tail[1])
return headX + (self.size.w / 2), headY + (self.size.h / 2)
end
function Worm:getSize() return self.size.w, self.size.h end
function Worm:_findSpawnPoint()
local pos = random.chooseUntil(self.game.env.nodes, function(element)
local distanceToPlayer = vector.dist(element.x, element.y, self.game.player:getPos())
return distanceToPlayer > self.stats.spawnDistanceFromPlayer
end)
-- pos.x = pos.x + ((TILE_SIZE - self.size.w) / 2)
-- pos.y = pos.y + ((TILE_SIZE - self.size.h) / 2)
return pos
end
function Worm:_findOpenDirections()
debugDirs = {}
local cx, cy = self:getCenter()
local d = {}
for _, dir in ipairs(directions) do
local dx, dy = unpack(dir)
local items, length = self.game.world:queryPoint(cx + (dx * TILE_SIZE), cy + (dy * TILE_SIZE))
debugDirs = lume.concat(debugDirs, items)
if (length == 0) then table.insert(d, dir) end
end
return d
end
function Worm:_move()
self.nextDirections = self:_findOpenDirections()
if #self.nextDirections > 0 then
self.forwardDirection = lume.randomchoice(self.nextDirections)
local dx, dy = unpack(self.forwardDirection)
local oldHeadX, oldHeadY = unpack(self.tail[1])
local newHeadX, newHeadY = oldHeadX + (dx * TILE_SIZE), oldHeadY + (dy * TILE_SIZE)
if #self.tail == self.stats.tailLength then
self.game.world:remove(self.tail[#self.tail])
table.remove(self.tail)
end
table.insert(self.tail, 1, { newHeadX, newHeadY })
self.game.world:add(self.tail[1], newHeadX, newHeadY, self.size.w, self.size.h)
end
end
return Worm