luncher/src/systems/spawner.lua

108 lines
3.4 KiB
Lua

local odds = 0
---@type { canSpawn: CanSpawn }
local selectedSpawner
spawnerSystem = filteredSystem({ canSpawn = T.CanSpawn, odds = T.number }, function(spawner, _, system)
if odds <= 0 then
return
end
odds = odds - spawner.odds
if odds <= 0 then
selectedSpawner = spawner
else
selectedSpawner = selectedSpawner or spawner
end
end)
--- process() and postProcess() are skipped when preProcess() returns true
function spawnerSystem:preProcess()
local newestX = Ingredients.newestIngredient().position.x
local panX = Camera.pan.x
local rightEdge = panX + 400
if newestX < rightEdge + 100 then
odds = math.random()
selectedSpawner = nil
return false -- A new ingredient needs spawning!
end
-- We do not need a new ingredient at this time
return true
end
-- Currently spawns AT MOST one new ingredient per frame, which is probably not enough at high speeds!
function spawnerSystem:postProcess()
local newestX = Ingredients.newestIngredient().position.x
local newlySpawned = Ingredients.nextInCache()
-- TODO: If performance becomes an issue, maybe just swap out __index
for k, v in pairs(selectedSpawner.canSpawn.entity) do
newlySpawned[k] = v
end
-- TODO: May not need to include lower spawners when we reach higher altitudes.
local panY = math.floor(Camera.pan.y or 0)
local yRange = selectedSpawner.canSpawn.yRange or { top = panY - 240, bottom = panY + 220 }
newlySpawned.position = { x = newestX + 60, y = math.random(yRange.top, yRange.bottom) }
self.world:addEntity(newlySpawned)
end
local expireWhenOffScreenBy = { x = 2000, y = 480 }
---@param world World
function addAllSpawners(world)
function addCollectableSpawner(name, spawnerOdds, score, sprite, canBounce, yRange)
local sizeX, sizeY = sprite:getSize()
local size = { x = sizeX, y = sizeY / 2 }
world:addEntity({
name = name,
odds = spawnerOdds,
canSpawn = {
yRange = yRange,
entity = {
score = score,
canBeCollidedBy = 1,
expireAfterCollision = true,
size = size,
drawAsSprite = sprite,
collectable = sprite,
expireWhenOffScreenBy = expireWhenOffScreenBy,
canBounce = canBounce,
},
},
})
end
addCollectableSpawner("Lettuce", 0.7, 1, LettuceSprite, {
flat = { x = 22, y = 190 },
mult = { x = 1, y = -0.5 },
})
addCollectableSpawner("Tomato", 0.1, 15, TomatoSprite)
addCollectableSpawner("Mushroom", 0.7, 5, MushroomSprite, {
flat = { x = 0, y = 290 },
mult = { x = 1, y = -1 },
}, { top = 219, bottom = 223 })
addCollectableSpawner("Cheese", 0.05, 1, CheeseSprite, {
flat = { x = 50, y = 390 },
mult = { x = 0.7, y = -0.5 },
})
end
function getAvailableSpawnerUpgrades()
local upgrades = {}
for _, spawner in pairs(spawnSystem.entities) do
if spawner.hasUpgradeSpeed then
upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed }
end
if spawner.hasUpgradeValue then
upgrades[#upgrades + 1] = { hasUpgradeValue = spawner.hasUpgradeValue }
end
end
return upgrades
end