Compare commits
No commits in common. "42ec7b74fc558d307b2d4d6e6b5efbe4043611b9" and "f570a4a9662437a731a7e5272fa3bd7020ef0e04" have entirely different histories.
42ec7b74fc
...
f570a4a966
|
@ -310,7 +310,6 @@ end
|
||||||
-- Use an empty table as a key for identifying Systems. Any table that contains
|
-- Use an empty table as a key for identifying Systems. Any table that contains
|
||||||
-- this key is considered a System rather than an Entity.
|
-- this key is considered a System rather than an Entity.
|
||||||
local systemTableKey = { "SYSTEM_TABLE_KEY" }
|
local systemTableKey = { "SYSTEM_TABLE_KEY" }
|
||||||
tiny.SKIP_PROCESS = { "SKIP_PROCESS_KEY" }
|
|
||||||
|
|
||||||
-- Checks if a table is a System.
|
-- Checks if a table is a System.
|
||||||
local function isSystem(table)
|
local function isSystem(table)
|
||||||
|
@ -323,12 +322,12 @@ local function processingSystemUpdate(system, dt)
|
||||||
local process = system.process
|
local process = system.process
|
||||||
local postProcess = system.postProcess
|
local postProcess = system.postProcess
|
||||||
|
|
||||||
local shouldSkipSystemProcess
|
local shouldSkipSystemProcess = false
|
||||||
if preProcess then
|
if preProcess then
|
||||||
shouldSkipSystemProcess = preProcess(system, dt)
|
shouldSkipSystemProcess = preProcess(system, dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
if process and shouldSkipSystemProcess ~= tiny.SKIP_PROCESS then
|
if process and not shouldSkipSystemProcess then
|
||||||
if system.nocache then
|
if system.nocache then
|
||||||
local entities = system.world.entities
|
local entities = system.world.entities
|
||||||
local filter = system.filter
|
local filter = system.filter
|
||||||
|
@ -348,7 +347,7 @@ local function processingSystemUpdate(system, dt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if postProcess and shouldSkipSystemProcess ~= tiny.SKIP_PROCESS then
|
if postProcess and not shouldSkipSystemProcess then
|
||||||
postProcess(system, dt)
|
postProcess(system, dt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -475,8 +474,6 @@ end
|
||||||
--- Adds an Entity to the world.
|
--- Adds an Entity to the world.
|
||||||
-- Also call this on Entities that have changed Components such that they
|
-- Also call this on Entities that have changed Components such that they
|
||||||
-- match different Filters. Returns the Entity.
|
-- match different Filters. Returns the Entity.
|
||||||
-- TODO: Track entity age when debugging?
|
|
||||||
-- TODO: Track debugName field when debugging?
|
|
||||||
function tiny.addEntity(world, entity)
|
function tiny.addEntity(world, entity)
|
||||||
local e2c = world.entitiesToChange
|
local e2c = world.entitiesToChange
|
||||||
e2c[#e2c + 1] = entity
|
e2c[#e2c + 1] = entity
|
||||||
|
|
|
@ -9,8 +9,8 @@ function Cart.reset(o)
|
||||||
y = 50,
|
y = 50,
|
||||||
}
|
}
|
||||||
o.velocity = {
|
o.velocity = {
|
||||||
x = 200 + (100 * math.random()),
|
x = 10 + (150 * math.random()),
|
||||||
y = 175 * (math.random() - 1),
|
y = 150 * (math.random() - 1),
|
||||||
}
|
}
|
||||||
o.size = size
|
o.size = size
|
||||||
o.canBeBounced = {
|
o.canBeBounced = {
|
||||||
|
@ -37,6 +37,7 @@ function Cart.reset(o)
|
||||||
position = { x = self.position.x, y = self.position.y },
|
position = { x = self.position.x, y = self.position.y },
|
||||||
focusPriority = 1,
|
focusPriority = 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return o
|
return o
|
||||||
|
|
|
@ -13,10 +13,16 @@ function Effects.makeFloatier(entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Cause the given ingredient to spawn more frequently
|
--- Cause the given ingredient to spawn more frequently
|
||||||
function Effects.moreOfIngredient(ingredient, spawner) end
|
function Effects.moreOfIngredient(ingredient, spawner)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Each of the given ingredient will have a *mult score from now on.
|
--- Each of the given ingredient will have a *mult score from now on.
|
||||||
function Effects.multiplyIngredientValue(ingredient, mult, spawner) end
|
function Effects.multiplyIngredientValue(ingredient, mult, spawner)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Each ingredient *multiplies* score in some way, in addition to adding.
|
--- Each ingredient *multiplies* score in some way, in addition to adding.
|
||||||
function Effects.multiplicativeIngredientValue(ingredient, addedMult, spawner) end
|
function Effects.multiplicativeIngredientValue(ingredient, addedMult, spawner)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
25
src/main.lua
25
src/main.lua
|
@ -8,10 +8,6 @@ import("CoreLibs/ui.lua")
|
||||||
import("CoreLibs/utilities/where.lua")
|
import("CoreLibs/utilities/where.lua")
|
||||||
|
|
||||||
import("../lib/tiny.lua")
|
import("../lib/tiny.lua")
|
||||||
|
|
||||||
local tiny <const> = tiny
|
|
||||||
world = tiny.world()
|
|
||||||
|
|
||||||
import("tiny-tools.lua")
|
import("tiny-tools.lua")
|
||||||
import("assets.lua")
|
import("assets.lua")
|
||||||
import("systems/filter-types.lua")
|
import("systems/filter-types.lua")
|
||||||
|
@ -20,14 +16,13 @@ import("systems/collision-detection.lua")
|
||||||
import("systems/collision-resolution.lua")
|
import("systems/collision-resolution.lua")
|
||||||
import("systems/draw.lua")
|
import("systems/draw.lua")
|
||||||
import("systems/gravity.lua")
|
import("systems/gravity.lua")
|
||||||
import("systems/move-toward.lua")
|
|
||||||
import("systems/rounds.lua")
|
import("systems/rounds.lua")
|
||||||
import("systems/spawner.lua")
|
import("systems/spawner.lua")
|
||||||
import("systems/velocity.lua")
|
import("systems/velocity.lua")
|
||||||
import("ingredients/ingredients.lua")
|
import("ingredients/ingredients.lua")
|
||||||
import("cart.lua")
|
import("cart.lua")
|
||||||
import("utils.lua")
|
|
||||||
|
|
||||||
|
local tiny <const> = tiny
|
||||||
local gfx <const> = playdate.graphics
|
local gfx <const> = playdate.graphics
|
||||||
playdate.display.setRefreshRate(50)
|
playdate.display.setRefreshRate(50)
|
||||||
gfx.setBackgroundColor(gfx.kColorWhite)
|
gfx.setBackgroundColor(gfx.kColorWhite)
|
||||||
|
@ -61,8 +56,21 @@ function Score:draw()
|
||||||
gfx.drawText("Z|" .. self.points, 360, 5)
|
gfx.drawText("Z|" .. self.points, 360, 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
world:addEntity(floor)
|
world = tiny.world(
|
||||||
world:addEntity(cart)
|
fallSystem,
|
||||||
|
velocitySystem,
|
||||||
|
roundSystem,
|
||||||
|
spawnerSystem,
|
||||||
|
collectedEntities,
|
||||||
|
collidingEntities,
|
||||||
|
collisionResolution,
|
||||||
|
collisionDetection,
|
||||||
|
cameraPanSystem,
|
||||||
|
drawRectanglesSystem,
|
||||||
|
drawSpriteSystem,
|
||||||
|
floor,
|
||||||
|
cart
|
||||||
|
)
|
||||||
addAllSpawners(world)
|
addAllSpawners(world)
|
||||||
|
|
||||||
world:addEntity(Ingredients.getFirst())
|
world:addEntity(Ingredients.getFirst())
|
||||||
|
@ -73,7 +81,6 @@ playdate.setAutoLockDisabled(true)
|
||||||
function playdate.update()
|
function playdate.update()
|
||||||
local deltaSeconds = playdate.getElapsedTime()
|
local deltaSeconds = playdate.getElapsedTime()
|
||||||
playdate.resetElapsedTime()
|
playdate.resetElapsedTime()
|
||||||
playdate.timer.updateTimers()
|
|
||||||
gfx.clear(gfx.kColorWhite)
|
gfx.clear(gfx.kColorWhite)
|
||||||
playdate.drawFPS(5, 5)
|
playdate.drawFPS(5, 5)
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ Camera = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
expireBelowScreenSystem = filteredSystem({ position = T.XyPair, expireBelowScreenBy = T.number })
|
|
||||||
|
|
||||||
cameraPanSystem = filteredSystem({ focusPriority = T.number, position = T.XyPair }, function(e, dt)
|
cameraPanSystem = filteredSystem({ focusPriority = T.number, position = T.XyPair }, function(e, dt)
|
||||||
if e.focusPriority >= focusPriority.priority then
|
if e.focusPriority >= focusPriority.priority then
|
||||||
focusPriority.position = e.position
|
focusPriority.position = e.position
|
||||||
|
@ -26,11 +24,4 @@ function cameraPanSystem:postProcess()
|
||||||
Camera.pan.x = math.max(0, focusPriority.position.x - 200)
|
Camera.pan.x = math.max(0, focusPriority.position.x - 200)
|
||||||
Camera.pan.y = math.min(0, focusPriority.position.y - 120)
|
Camera.pan.y = math.min(0, focusPriority.position.y - 120)
|
||||||
gfx.setDrawOffset(-Camera.pan.x, -Camera.pan.y)
|
gfx.setDrawOffset(-Camera.pan.x, -Camera.pan.y)
|
||||||
|
|
||||||
for _, entity in pairs(expireBelowScreenSystem.entities) do
|
|
||||||
if entity.position.y - (Camera.pan.y + 240) > entity.expireBelowScreenBy then
|
|
||||||
print("Entity expired - was too far below screen!")
|
|
||||||
self.world:removeEntity(entity)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,7 +26,7 @@ collisionResolution = filteredSystem({ collisionBetween = T.Collision }, functio
|
||||||
position = {
|
position = {
|
||||||
x = collider.position.x,
|
x = collider.position.x,
|
||||||
y = collider.position.y,
|
y = collider.position.y,
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,5 +55,25 @@ collisionResolution = filteredSystem({ collisionBetween = T.Collision }, functio
|
||||||
system.world:addEntity({ collected = collidedInto.collectable })
|
system.world:addEntity({ collected = collidedInto.collectable })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- if collidedInto.sparkOnCollision and collider.sparkOnCollision and (math.abs(collider.velocity.x) + math.abs(collider.velocity.y)) > 2 then
|
||||||
|
-- local size = { x = 1, y = 1 }
|
||||||
|
-- local spark = {
|
||||||
|
-- position = {
|
||||||
|
-- x = collider.position.x,
|
||||||
|
-- y = collider.position.y + collider.size.y - 2,
|
||||||
|
-- },
|
||||||
|
-- velocity = {
|
||||||
|
-- x = -collider.velocity.x,
|
||||||
|
-- y = 150,
|
||||||
|
-- },
|
||||||
|
-- size = size,
|
||||||
|
-- canCollideWith = 1,
|
||||||
|
-- mass = 1,
|
||||||
|
-- drawAsSprite = Spark,
|
||||||
|
-- expireAfterCollision = true,
|
||||||
|
-- }
|
||||||
|
-- system.world:addEntity(spark)
|
||||||
|
-- end
|
||||||
|
|
||||||
system.world:removeEntity(e)
|
system.world:removeEntity(e)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -4,10 +4,6 @@ drawRectanglesSystem = filteredSystem({ position = T.XyPair, drawAsRectangle = {
|
||||||
gfx.fillRect(e.position.x, e.position.y, e.drawAsRectangle.size.x, e.drawAsRectangle.size.y)
|
gfx.fillRect(e.position.x, e.position.y, e.drawAsRectangle.size.x, e.drawAsRectangle.size.y)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
drawTextSystem = filteredSystem({ position = T.XyPair, drawAsText = { text = T.str } }, function(e, dt)
|
|
||||||
gfx.drawTextAligned(e.drawAsText.text, e.position.x, e.position.y, gfx.kAlignCenter)
|
|
||||||
end)
|
|
||||||
|
|
||||||
drawSpriteSystem = filteredSystem({ position = T.XyPair, drawAsSprite = T.PdImage }, function(e, dt, system)
|
drawSpriteSystem = filteredSystem({ position = T.XyPair, drawAsSprite = T.PdImage }, function(e, dt, system)
|
||||||
e.drawAsSprite:draw(e.position.x, e.position.y)
|
e.drawAsSprite:draw(e.position.x, e.position.y)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -48,7 +48,7 @@ T = {
|
||||||
---@type RoundStateAction
|
---@type RoundStateAction
|
||||||
RoundStateAction = "start",
|
RoundStateAction = "start",
|
||||||
---@type CanSpawn
|
---@type CanSpawn
|
||||||
CanSpawn = {},
|
CanSpawn = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
local MoveToward = {
|
|
||||||
target = T.XyPair,
|
|
||||||
range = T.number,
|
|
||||||
speed = T.number,
|
|
||||||
}
|
|
||||||
|
|
||||||
local sqrt, abs = math.sqrt, math.abs
|
|
||||||
|
|
||||||
---@param xy1 XyPair
|
|
||||||
---@param xy2 XyPair
|
|
||||||
local function normalizeVector(xy1, xy2)
|
|
||||||
local x = xy1.x - xy2.x
|
|
||||||
local y = xy1.y - xy2.y
|
|
||||||
local distance = sqrt((x * x) + (y * y))
|
|
||||||
return x / distance, y / distance, distance
|
|
||||||
end
|
|
||||||
|
|
||||||
moveTowardSystem = filteredSystem(
|
|
||||||
{ moveToward = MoveToward, position = T.XyPair },
|
|
||||||
function(e, dt, system)
|
|
||||||
local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target)
|
|
||||||
if distance > e.moveToward.range then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO May be incorrect when signs are mismatched between vel and diff
|
|
||||||
local xVel = xNorm * e.moveToward.speed * dt
|
|
||||||
if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then
|
|
||||||
e.position.x = e.moveToward.target.x
|
|
||||||
else
|
|
||||||
e.position.x = e.position.x + xVel
|
|
||||||
end
|
|
||||||
|
|
||||||
local yVel = yNorm * e.moveToward.speed * dt
|
|
||||||
if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then
|
|
||||||
e.position.y = e.moveToward.target.y
|
|
||||||
else
|
|
||||||
e.position.y = e.position.y + yVel
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
|
@ -1,11 +1,8 @@
|
||||||
collectedEntities = filteredSystem({ collected = T.PdImage })
|
collectedEntities = filteredSystem({ collected = T.PdImage })
|
||||||
|
|
||||||
local onCollidingRemove = { "mass", "velocity", "canCollideWith" }
|
|
||||||
|
|
||||||
roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Maybe(T.XyPair) }, function(e, _, system)
|
roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Maybe(T.XyPair) }, function(e, _, system)
|
||||||
if e.roundAction == "end" then
|
if e.roundAction == "end" then
|
||||||
playdate.setAutoLockDisabled(false)
|
playdate.setAutoLockDisabled(false)
|
||||||
|
|
||||||
local y = e.position.y - 240
|
local y = e.position.y - 240
|
||||||
local rectWidth = 150
|
local rectWidth = 150
|
||||||
local plateSize = { x = rectWidth, y = 10 }
|
local plateSize = { x = rectWidth, y = 10 }
|
||||||
|
@ -22,57 +19,25 @@ roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Mayb
|
||||||
stopMovingOnCollision = true,
|
stopMovingOnCollision = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
local delayPerDrop = 150
|
|
||||||
local delay = 0
|
|
||||||
for i, collectable in ipairs(collectedEntities.entities) do
|
for i, collectable in ipairs(collectedEntities.entities) do
|
||||||
local collX, collY = collectable.collected:getSize()
|
local collX, collY = collectable.collected:getSize()
|
||||||
|
local onCollidingRemove = {"mass", "velocity", "canCollideWith"}
|
||||||
y = y - collY - 15
|
y = y - collY - 15
|
||||||
playdate.timer.new(delay, function(ee, ccollX, ccollY, yy, ii, ssystem, ccollectable)
|
system.world:addEntity({
|
||||||
ssystem.world:addEntity({
|
drawAsSprite = collectable.collected,
|
||||||
drawAsSprite = ccollectable.collected,
|
size = { x = collX, y = collY / 2 },
|
||||||
size = { x = ccollX, y = ccollY / 2 },
|
mass = 0.5,
|
||||||
mass = 0.5,
|
velocity = { x = 0, y = 0 },
|
||||||
velocity = { x = 0, y = 0 },
|
position = { x = e.position.x - (collX / 2), y = y },
|
||||||
position = { x = ee.position.x - (ccollX / 2), y = yy },
|
canCollideWith = 2,
|
||||||
canCollideWith = 2,
|
canBeCollidedBy = 2,
|
||||||
canBeCollidedBy = 2,
|
isSolid = true,
|
||||||
isSolid = true,
|
stopMovingOnCollision = true,
|
||||||
stopMovingOnCollision = true,
|
onCollidingRemove = onCollidingRemove,
|
||||||
onCollidingRemove = onCollidingRemove,
|
focusOnCollide = i,
|
||||||
focusOnCollide = ii,
|
})
|
||||||
expireBelowScreenBy = 5,
|
|
||||||
})
|
|
||||||
end, e, collX, collY, y, i, system, collectable)
|
|
||||||
delay = delay + delayPerDrop
|
|
||||||
system.world:removeEntity(collectable)
|
system.world:removeEntity(collectable)
|
||||||
end
|
end
|
||||||
|
|
||||||
local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3)
|
|
||||||
|
|
||||||
y = y - 50
|
|
||||||
for _, upgrade in ipairs(availableUpgrades) do
|
|
||||||
printTable(upgrade)
|
|
||||||
local collX, collY = 75, 30
|
|
||||||
y = y - collY - 15
|
|
||||||
playdate.timer.new(delay, function(ee, ccollX, ccollY, yy, ii, ssystem, ccollectable)
|
|
||||||
ssystem.world:addEntity({
|
|
||||||
drawAsText = {
|
|
||||||
text = upgrade.name,
|
|
||||||
},
|
|
||||||
size = { x = ccollX, y = ccollY / 2 },
|
|
||||||
mass = 0.5,
|
|
||||||
velocity = { x = 0, y = 0 },
|
|
||||||
position = { x = ee.position.x - (ccollX / 2), y = yy },
|
|
||||||
canCollideWith = 2,
|
|
||||||
canBeCollidedBy = 2,
|
|
||||||
isSolid = true,
|
|
||||||
stopMovingOnCollision = true,
|
|
||||||
onCollidingRemove = onCollidingRemove,
|
|
||||||
focusOnCollide = ii,
|
|
||||||
})
|
|
||||||
end, e, collX, collY, y, i, system, collectable)
|
|
||||||
delay = delay + delayPerDrop
|
|
||||||
end
|
|
||||||
system.world:removeEntity(e)
|
system.world:removeEntity(e)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
|
@ -3,7 +3,7 @@ local odds = 0
|
||||||
---@type { canSpawn: CanSpawn }
|
---@type { canSpawn: CanSpawn }
|
||||||
local selectedSpawner
|
local selectedSpawner
|
||||||
|
|
||||||
spawnerSystem = filteredSystem({ canSpawn = T.CanSpawn, odds = T.number }, function(spawner, _, _)
|
spawnerSystem = filteredSystem({ canSpawn = T.CanSpawn, odds = T.number }, function(spawner, _, system)
|
||||||
if odds <= 0 then
|
if odds <= 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -15,28 +15,22 @@ spawnerSystem = filteredSystem({ canSpawn = T.CanSpawn, odds = T.number }, funct
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- May cause process() and postProcess() to be skipped
|
--- process() and postProcess() are skipped when preProcess() returns true
|
||||||
function spawnerSystem:preProcess()
|
function spawnerSystem:preProcess()
|
||||||
local newestX = Ingredients.newestIngredient().position.x
|
local newestX = Ingredients.newestIngredient().position.x
|
||||||
local panX = Camera.pan.x
|
local panX = Camera.pan.x
|
||||||
local rightEdge = panX + 400
|
local rightEdge = panX + 400
|
||||||
local totalOdds = 0
|
|
||||||
for _, spawner in pairs(spawnerSystem.entities) do
|
|
||||||
totalOdds = totalOdds + spawner.odds
|
|
||||||
end
|
|
||||||
|
|
||||||
if newestX < rightEdge + 100 then
|
if newestX < rightEdge + 100 then
|
||||||
odds = math.random() * totalOdds
|
odds = math.random()
|
||||||
selectedSpawner = nil
|
selectedSpawner = nil
|
||||||
return -- A new ingredient needs spawning!
|
return false -- A new ingredient needs spawning!
|
||||||
end
|
end
|
||||||
|
|
||||||
-- We do not need a new ingredient at this time
|
-- We do not need a new ingredient at this time
|
||||||
return tiny.SKIP_PROCESS
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawnEveryX = 26
|
|
||||||
|
|
||||||
-- Currently spawns AT MOST one new ingredient per frame, which is probably not enough at high speeds!
|
-- Currently spawns AT MOST one new ingredient per frame, which is probably not enough at high speeds!
|
||||||
function spawnerSystem:postProcess()
|
function spawnerSystem:postProcess()
|
||||||
local newestX = Ingredients.newestIngredient().position.x
|
local newestX = Ingredients.newestIngredient().position.x
|
||||||
|
@ -50,7 +44,7 @@ function spawnerSystem:postProcess()
|
||||||
-- TODO: May not need to include lower spawners when we reach higher altitudes.
|
-- TODO: May not need to include lower spawners when we reach higher altitudes.
|
||||||
local panY = math.floor(Camera.pan.y or 0)
|
local panY = math.floor(Camera.pan.y or 0)
|
||||||
local yRange = selectedSpawner.canSpawn.yRange or { top = panY - 240, bottom = panY + 220 }
|
local yRange = selectedSpawner.canSpawn.yRange or { top = panY - 240, bottom = panY + 220 }
|
||||||
newlySpawned.position = { x = newestX + spawnEveryX, y = math.random(yRange.top, yRange.bottom) }
|
newlySpawned.position = { x = newestX + 60, y = math.random(yRange.top, yRange.bottom) }
|
||||||
|
|
||||||
self.world:addEntity(newlySpawned)
|
self.world:addEntity(newlySpawned)
|
||||||
end
|
end
|
||||||
|
@ -64,8 +58,6 @@ function addAllSpawners(world)
|
||||||
local size = { x = sizeX, y = sizeY / 2 }
|
local size = { x = sizeX, y = sizeY / 2 }
|
||||||
|
|
||||||
world:addEntity({
|
world:addEntity({
|
||||||
-- NOTE: This name should NOT be used to identify the spawner.
|
|
||||||
-- It should only be used to supply visual information when searching for available upgrades.
|
|
||||||
name = name,
|
name = name,
|
||||||
odds = spawnerOdds,
|
odds = spawnerOdds,
|
||||||
canSpawn = {
|
canSpawn = {
|
||||||
|
@ -91,7 +83,7 @@ function addAllSpawners(world)
|
||||||
|
|
||||||
addCollectableSpawner("Tomato", 0.1, 15, TomatoSprite)
|
addCollectableSpawner("Tomato", 0.1, 15, TomatoSprite)
|
||||||
|
|
||||||
addCollectableSpawner("Mushroom", 0.02, 5, MushroomSprite, {
|
addCollectableSpawner("Mushroom", 0.7, 5, MushroomSprite, {
|
||||||
flat = { x = 0, y = 290 },
|
flat = { x = 0, y = 290 },
|
||||||
mult = { x = 1, y = -1 },
|
mult = { x = 1, y = -1 },
|
||||||
}, { top = 219, bottom = 223 })
|
}, { top = 219, bottom = 223 })
|
||||||
|
@ -102,41 +94,15 @@ function addAllSpawners(world)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
---@alias Upgrade { name: string, apply = fun() }
|
|
||||||
|
|
||||||
---@return Upgrade[]
|
|
||||||
function getAvailableSpawnerUpgrades()
|
function getAvailableSpawnerUpgrades()
|
||||||
local upgrades = {}
|
local upgrades = {}
|
||||||
for _, spawner in pairs(spawnerSystem.entities) do
|
for _, spawner in pairs(spawnSystem.entities) do
|
||||||
if spawner.hasUpgradeSpeed then
|
if spawner.hasUpgradeSpeed then
|
||||||
upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed }
|
upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed }
|
||||||
end
|
end
|
||||||
|
if spawner.hasUpgradeValue then
|
||||||
if spawner.canSpawn.entity.score then
|
upgrades[#upgrades + 1] = { hasUpgradeValue = spawner.hasUpgradeValue }
|
||||||
upgrades[#upgrades + 1] = {
|
|
||||||
name = "Double " .. spawner.name .. " value",
|
|
||||||
apply = function()
|
|
||||||
spawner.canSpawn.entity.score = spawner.canSpawn.entity.score * 2
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(spawner.odds, "Expected all spawners to have an `odds` field!")
|
|
||||||
upgrades[#upgrades + 1] = {
|
|
||||||
name = "Double " .. spawner.name .. " frequency",
|
|
||||||
apply = function()
|
|
||||||
spawner.odds = spawner.odds * 2
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
-- if not spawner.canSpawn.entity.velocity then
|
|
||||||
-- upgrades[#upgrades + 1] = {
|
|
||||||
-- name = spawner.name .. " Movement",
|
|
||||||
-- upgrade = function()
|
|
||||||
-- spawner.canSpawn.entity.velocity = { x = -10, y = 0 }
|
|
||||||
-- end,
|
|
||||||
-- }
|
|
||||||
-- end
|
|
||||||
end
|
end
|
||||||
return upgrades
|
return upgrades
|
||||||
end
|
end
|
|
@ -24,7 +24,7 @@ function filteredSystem(shape, process)
|
||||||
end
|
end
|
||||||
system.filter = tiny.requireAll(table.unpack(keys))
|
system.filter = tiny.requireAll(table.unpack(keys))
|
||||||
if not process then
|
if not process then
|
||||||
return world:addSystem(system)
|
return system
|
||||||
end
|
end
|
||||||
if isSimulator then
|
if isSimulator then
|
||||||
-- local acceptableKeys = ""
|
-- local acceptableKeys = ""
|
||||||
|
@ -54,5 +54,5 @@ function filteredSystem(shape, process)
|
||||||
process(e, dt, self)
|
process(e, dt, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return world:addSystem(system)
|
return system
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
Utils = {}
|
|
||||||
|
|
||||||
--- Returns up to `n` random values from the given array. Will return fewer if `n > #fromArr`
|
|
||||||
---@generic T
|
|
||||||
---@param fromArr T[]
|
|
||||||
---@param n number
|
|
||||||
---@generic T[]
|
|
||||||
function Utils.getNDifferentValues(fromArr, n)
|
|
||||||
assert(n >= 0, "n must be a non-negative integer")
|
|
||||||
if n > #fromArr then
|
|
||||||
n = #fromArr
|
|
||||||
end
|
|
||||||
local found = 0
|
|
||||||
local indexes = {}
|
|
||||||
while found < n do
|
|
||||||
local randomIndex = math.random(#fromArr)
|
|
||||||
if not indexes[randomIndex] then
|
|
||||||
found = found + 1
|
|
||||||
indexes[randomIndex] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local randoms = {}
|
|
||||||
for i in pairs(indexes) do
|
|
||||||
randoms[#randoms + 1] = fromArr[i]
|
|
||||||
end
|
|
||||||
return randoms
|
|
||||||
end
|
|
Loading…
Reference in New Issue