Compare commits
No commits in common. "590121f7a65f68c2d2de8cfede7e3487fa5a0ed6" and "42ec7b74fc558d307b2d4d6e6b5efbe4043611b9" have entirely different histories.
590121f7a6
...
42ec7b74fc
|
@ -782,11 +782,10 @@ function tiny.update(world, dt, filter)
|
||||||
for i = 1, #systems do
|
for i = 1, #systems do
|
||||||
local system = systems[i]
|
local system = systems[i]
|
||||||
if system.active and ((not filter) or filter(world, system)) then
|
if system.active and ((not filter) or filter(world, system)) then
|
||||||
-- TODO: Track how long each system runs for during any given frame.
|
|
||||||
-- Update Systems that have an update method (most Systems)
|
-- Update Systems that have an update method (most Systems)
|
||||||
local update = system.update
|
local update = system.update
|
||||||
if update then
|
if update then
|
||||||
--local currentMs = playdate.getCurrentTimeMilliseconds()
|
|
||||||
local interval = system.interval
|
local interval = system.interval
|
||||||
if interval then
|
if interval then
|
||||||
local bufferedTime = (system.bufferedTime or 0) + dt
|
local bufferedTime = (system.bufferedTime or 0) + dt
|
||||||
|
@ -798,14 +797,11 @@ function tiny.update(world, dt, filter)
|
||||||
else
|
else
|
||||||
update(system, dt)
|
update(system, dt)
|
||||||
end
|
end
|
||||||
--local endTimeMs = playdate.getCurrentTimeMilliseconds()
|
|
||||||
--print(tostring(endTimeMs - currentMs) .. "ms taken to update " .. system.name)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
system.modified = false
|
system.modified = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--print("")
|
|
||||||
|
|
||||||
-- Iterate through Systems IN ORDER AGAIN
|
-- Iterate through Systems IN ORDER AGAIN
|
||||||
for i = 1, #systems do
|
for i = 1, #systems do
|
||||||
|
|
|
@ -28,8 +28,6 @@ TomatoSprite = playdate.graphics.image.new("assets/images/TomatoSprite.png")
|
||||||
|
|
||||||
-- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
-- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
||||||
-- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
-- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
||||||
-- luacheck: ignore
|
-- !!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value)
|
||||||
---@type pd_font
|
-- return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft")
|
||||||
AshevilleSans14Bold = playdate.graphics.font.new("assets/fonts/Asheville-Sans-14-Bold.pft")
|
-- end))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,6 @@ end)!!(generatedFileWarning())
|
||||||
!!(dirLookup('assets/images', 'png', 'playdate.graphics.image.new', 'pd_image'))
|
!!(dirLookup('assets/images', 'png', 'playdate.graphics.image.new', 'pd_image'))
|
||||||
-- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
-- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
||||||
-- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
-- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer'))
|
||||||
!!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value)
|
-- !!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value)
|
||||||
return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft")
|
-- return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft")
|
||||||
end))
|
-- end))
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -1,295 +0,0 @@
|
||||||
tracking=1
|
|
||||||
space 3
|
|
||||||
! 2
|
|
||||||
" 5
|
|
||||||
# 9
|
|
||||||
$ 8
|
|
||||||
% 12
|
|
||||||
& 11
|
|
||||||
' 3
|
|
||||||
( 5
|
|
||||||
) 5
|
|
||||||
* 8
|
|
||||||
+ 8
|
|
||||||
, 3
|
|
||||||
- 6
|
|
||||||
. 2
|
|
||||||
/ 6
|
|
||||||
0 9
|
|
||||||
1 4
|
|
||||||
2 9
|
|
||||||
3 9
|
|
||||||
4 9
|
|
||||||
5 9
|
|
||||||
6 9
|
|
||||||
7 9
|
|
||||||
8 10
|
|
||||||
9 9
|
|
||||||
: 2
|
|
||||||
; 2
|
|
||||||
< 7
|
|
||||||
= 7
|
|
||||||
> 7
|
|
||||||
? 9
|
|
||||||
@ 11
|
|
||||||
A 10
|
|
||||||
B 9
|
|
||||||
C 9
|
|
||||||
D 9
|
|
||||||
E 8
|
|
||||||
F 8
|
|
||||||
G 9
|
|
||||||
H 9
|
|
||||||
I 2
|
|
||||||
J 8
|
|
||||||
K 10
|
|
||||||
L 9
|
|
||||||
M 12
|
|
||||||
N 9
|
|
||||||
O 9
|
|
||||||
P 9
|
|
||||||
Q 9
|
|
||||||
R 9
|
|
||||||
S 9
|
|
||||||
T 10
|
|
||||||
U 9
|
|
||||||
V 10
|
|
||||||
W 14
|
|
||||||
X 8
|
|
||||||
Y 8
|
|
||||||
Z 8
|
|
||||||
[ 3
|
|
||||||
\ 6
|
|
||||||
] 3
|
|
||||||
^ 6
|
|
||||||
_ 8
|
|
||||||
` 3
|
|
||||||
a 8
|
|
||||||
b 8
|
|
||||||
c 8
|
|
||||||
d 8
|
|
||||||
e 8
|
|
||||||
f 6
|
|
||||||
g 8
|
|
||||||
h 8
|
|
||||||
i 2
|
|
||||||
j 4
|
|
||||||
k 8
|
|
||||||
l 2
|
|
||||||
m 12
|
|
||||||
n 8
|
|
||||||
o 8
|
|
||||||
p 8
|
|
||||||
q 8
|
|
||||||
r 6
|
|
||||||
s 8
|
|
||||||
t 6
|
|
||||||
u 8
|
|
||||||
v 8
|
|
||||||
w 12
|
|
||||||
x 9
|
|
||||||
y 8
|
|
||||||
z 8
|
|
||||||
{ 6
|
|
||||||
| 2
|
|
||||||
} 6
|
|
||||||
~ 10
|
|
||||||
… 8
|
|
||||||
¥ 8
|
|
||||||
‼ 5
|
|
||||||
™ 8
|
|
||||||
© 11
|
|
||||||
® 11
|
|
||||||
。 16
|
|
||||||
、 16
|
|
||||||
ぁ 16
|
|
||||||
あ 16
|
|
||||||
ぃ 16
|
|
||||||
い 16
|
|
||||||
ぅ 16
|
|
||||||
う 16
|
|
||||||
ぇ 16
|
|
||||||
え 16
|
|
||||||
ぉ 16
|
|
||||||
お 16
|
|
||||||
か 16
|
|
||||||
が 16
|
|
||||||
き 16
|
|
||||||
ぎ 16
|
|
||||||
く 16
|
|
||||||
ぐ 16
|
|
||||||
け 16
|
|
||||||
げ 16
|
|
||||||
こ 16
|
|
||||||
ご 16
|
|
||||||
さ 16
|
|
||||||
ざ 16
|
|
||||||
し 16
|
|
||||||
じ 16
|
|
||||||
す 16
|
|
||||||
ず 16
|
|
||||||
せ 16
|
|
||||||
ぜ 16
|
|
||||||
そ 16
|
|
||||||
ぞ 16
|
|
||||||
た 16
|
|
||||||
だ 16
|
|
||||||
ち 16
|
|
||||||
ぢ 16
|
|
||||||
っ 16
|
|
||||||
つ 16
|
|
||||||
づ 16
|
|
||||||
て 16
|
|
||||||
で 16
|
|
||||||
と 16
|
|
||||||
ど 16
|
|
||||||
な 16
|
|
||||||
に 16
|
|
||||||
ぬ 16
|
|
||||||
ね 16
|
|
||||||
の 16
|
|
||||||
は 16
|
|
||||||
ば 16
|
|
||||||
ぱ 16
|
|
||||||
ひ 16
|
|
||||||
び 16
|
|
||||||
ぴ 16
|
|
||||||
ふ 16
|
|
||||||
ぶ 16
|
|
||||||
ぷ 16
|
|
||||||
へ 16
|
|
||||||
べ 16
|
|
||||||
ぺ 16
|
|
||||||
ほ 16
|
|
||||||
ぼ 16
|
|
||||||
ぽ 16
|
|
||||||
ま 16
|
|
||||||
み 16
|
|
||||||
む 16
|
|
||||||
め 16
|
|
||||||
も 16
|
|
||||||
ゃ 16
|
|
||||||
や 16
|
|
||||||
ゅ 16
|
|
||||||
ゆ 16
|
|
||||||
ょ 16
|
|
||||||
よ 16
|
|
||||||
ら 16
|
|
||||||
り 16
|
|
||||||
る 16
|
|
||||||
れ 16
|
|
||||||
ろ 16
|
|
||||||
ゎ 16
|
|
||||||
わ 16
|
|
||||||
ゐ 16
|
|
||||||
ゑ 16
|
|
||||||
を 16
|
|
||||||
ん 16
|
|
||||||
ゔ 16
|
|
||||||
ゕ 16
|
|
||||||
ゖ 16
|
|
||||||
゛ 1
|
|
||||||
゜ 0
|
|
||||||
ゝ 16
|
|
||||||
ゞ 16
|
|
||||||
ゟ 16
|
|
||||||
゠ 16
|
|
||||||
ァ 16
|
|
||||||
ア 16
|
|
||||||
ィ 16
|
|
||||||
イ 16
|
|
||||||
ゥ 16
|
|
||||||
ウ 16
|
|
||||||
ェ 16
|
|
||||||
エ 16
|
|
||||||
ォ 16
|
|
||||||
オ 16
|
|
||||||
カ 16
|
|
||||||
ガ 16
|
|
||||||
キ 16
|
|
||||||
ギ 16
|
|
||||||
ク 16
|
|
||||||
グ 16
|
|
||||||
ケ 16
|
|
||||||
ゲ 16
|
|
||||||
コ 16
|
|
||||||
ゴ 16
|
|
||||||
サ 16
|
|
||||||
ザ 16
|
|
||||||
シ 16
|
|
||||||
ジ 16
|
|
||||||
ス 16
|
|
||||||
ズ 16
|
|
||||||
セ 16
|
|
||||||
ゼ 16
|
|
||||||
ソ 16
|
|
||||||
ゾ 16
|
|
||||||
タ 16
|
|
||||||
ダ 16
|
|
||||||
チ 16
|
|
||||||
ヂ 16
|
|
||||||
ッ 16
|
|
||||||
ツ 16
|
|
||||||
ヅ 16
|
|
||||||
テ 16
|
|
||||||
デ 16
|
|
||||||
ト 16
|
|
||||||
ド 16
|
|
||||||
ナ 16
|
|
||||||
ニ 16
|
|
||||||
ヌ 16
|
|
||||||
ネ 16
|
|
||||||
ノ 16
|
|
||||||
ハ 16
|
|
||||||
バ 16
|
|
||||||
パ 16
|
|
||||||
ヒ 16
|
|
||||||
ビ 16
|
|
||||||
ピ 16
|
|
||||||
フ 16
|
|
||||||
ブ 16
|
|
||||||
プ 16
|
|
||||||
ヘ 16
|
|
||||||
ベ 16
|
|
||||||
ペ 16
|
|
||||||
ホ 16
|
|
||||||
ボ 16
|
|
||||||
ポ 16
|
|
||||||
マ 16
|
|
||||||
ミ 16
|
|
||||||
ム 16
|
|
||||||
メ 16
|
|
||||||
モ 16
|
|
||||||
ャ 16
|
|
||||||
ヤ 16
|
|
||||||
ュ 16
|
|
||||||
ユ 16
|
|
||||||
ョ 16
|
|
||||||
ヨ 16
|
|
||||||
ラ 16
|
|
||||||
リ 16
|
|
||||||
ル 16
|
|
||||||
レ 16
|
|
||||||
ロ 16
|
|
||||||
ヮ 16
|
|
||||||
ワ 16
|
|
||||||
ヰ 16
|
|
||||||
ヱ 16
|
|
||||||
ヲ 16
|
|
||||||
ン 16
|
|
||||||
ヴ 16
|
|
||||||
ヵ 16
|
|
||||||
ヶ 16
|
|
||||||
ヷ 16
|
|
||||||
ヸ 16
|
|
||||||
ヹ 16
|
|
||||||
ヺ 16
|
|
||||||
・ 16
|
|
||||||
ー 16
|
|
||||||
ヽ 16
|
|
||||||
ヾ 16
|
|
||||||
ヿ 16
|
|
||||||
「 16
|
|
||||||
」 16
|
|
||||||
円 16
|
|
||||||
<EFBFBD> 13
|
|
|
@ -3,16 +3,13 @@ Cart = {}
|
||||||
local sizeX, sizeY = CartSprite:getSize()
|
local sizeX, sizeY = CartSprite:getSize()
|
||||||
local size = { x = sizeX, y = sizeY * 0.75 }
|
local size = { x = sizeX, y = sizeY * 0.75 }
|
||||||
|
|
||||||
cartSystem = filteredSystem("cart", { isCart = T.marker })
|
|
||||||
|
|
||||||
function Cart.reset(o)
|
function Cart.reset(o)
|
||||||
o.isCart = T.marker
|
|
||||||
o.position = {
|
o.position = {
|
||||||
x = 20,
|
x = 20,
|
||||||
y = 50,
|
y = 50,
|
||||||
}
|
}
|
||||||
o.velocity = {
|
o.velocity = {
|
||||||
x = 300 + (100 * math.random()),
|
x = 200 + (100 * math.random()),
|
||||||
y = 175 * (math.random() - 1),
|
y = 175 * (math.random() - 1),
|
||||||
}
|
}
|
||||||
o.size = size
|
o.size = size
|
||||||
|
@ -36,11 +33,9 @@ function Cart.reset(o)
|
||||||
y = self.position.y,
|
y = self.position.y,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
-- Focus on the center, where the cart stopped
|
|
||||||
world:addEntity({
|
world:addEntity({
|
||||||
position = { x = self.position.x, y = self.position.y },
|
position = { x = self.position.x, y = self.position.y },
|
||||||
focusPriority = 1,
|
focusPriority = 1,
|
||||||
removeAtRoundStart = true,
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
effectSystem = filteredSystem("effects", { canReceive })
|
effectSystem = filteredSystem({ canReceive })
|
||||||
|
|
||||||
Effects = {}
|
Effects = {}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Ingredients = {}
|
||||||
local ingredientCache = {}
|
local ingredientCache = {}
|
||||||
|
|
||||||
local _ingredientCacheIndex = 1
|
local _ingredientCacheIndex = 1
|
||||||
local maxCache = 80
|
local maxCache = 100
|
||||||
for i = 1, maxCache do
|
for i = 1, maxCache do
|
||||||
ingredientCache[i] = {}
|
ingredientCache[i] = {}
|
||||||
end
|
end
|
||||||
|
@ -19,16 +19,6 @@ function Ingredients.cacheSize()
|
||||||
return maxCache
|
return maxCache
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ingredients.clearCache(world)
|
|
||||||
for _, o in ipairs(ingredientCache) do
|
|
||||||
for key in pairs(o) do
|
|
||||||
o[key] = nil
|
|
||||||
end
|
|
||||||
world:addEntity(o)
|
|
||||||
end
|
|
||||||
world:addEntity(Ingredients.getFirst())
|
|
||||||
end
|
|
||||||
|
|
||||||
function Ingredients.nextInCache()
|
function Ingredients.nextInCache()
|
||||||
local index = _ingredientCacheIndex
|
local index = _ingredientCacheIndex
|
||||||
_ingredientCacheIndex = _ingredientCacheIndex + 1
|
_ingredientCacheIndex = _ingredientCacheIndex + 1
|
||||||
|
|
31
src/main.lua
31
src/main.lua
|
@ -15,19 +15,15 @@ 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")
|
||||||
|
import("systems/camera-pan.lua")
|
||||||
|
import("systems/collision-detection.lua")
|
||||||
|
import("systems/collision-resolution.lua")
|
||||||
|
import("systems/draw.lua")
|
||||||
import("systems/gravity.lua")
|
import("systems/gravity.lua")
|
||||||
import("systems/move-toward.lua")
|
import("systems/move-toward.lua")
|
||||||
import("systems/velocity.lua")
|
|
||||||
import("systems/spawner.lua")
|
|
||||||
import("systems/rounds.lua")
|
import("systems/rounds.lua")
|
||||||
import("systems/camera-pan.lua")
|
import("systems/spawner.lua")
|
||||||
import("systems/collision-resolution.lua")
|
import("systems/velocity.lua")
|
||||||
import("systems/collision-detection.lua")
|
|
||||||
|
|
||||||
import("systems/draw.lua")
|
|
||||||
import("systems/input.lua")
|
|
||||||
import("systems/menu.lua")
|
|
||||||
|
|
||||||
import("ingredients/ingredients.lua")
|
import("ingredients/ingredients.lua")
|
||||||
import("cart.lua")
|
import("cart.lua")
|
||||||
import("utils.lua")
|
import("utils.lua")
|
||||||
|
@ -74,23 +70,22 @@ world:addEntity(Ingredients.getFirst())
|
||||||
-- TODO: Re-enable when cart stops
|
-- TODO: Re-enable when cart stops
|
||||||
playdate.setAutoLockDisabled(true)
|
playdate.setAutoLockDisabled(true)
|
||||||
|
|
||||||
local startMsOffset = -playdate.getCurrentTimeMilliseconds()
|
|
||||||
|
|
||||||
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)
|
||||||
local fps = playdate.getFPS()
|
|
||||||
if fps > 0 and fps < 20 then
|
|
||||||
local currentTime = playdate.getCurrentTimeMilliseconds() + startMsOffset
|
|
||||||
print("At " .. (currentTime / 1000) .. "s, FPS below 20: " .. fps)
|
|
||||||
end
|
|
||||||
|
|
||||||
floor.position.x = Camera.pan.x - 600
|
floor.position.x = Camera.pan.x - 600
|
||||||
|
|
||||||
world:update(math.min(1 / 40, deltaSeconds))
|
world:update(deltaSeconds)
|
||||||
|
|
||||||
gfx.setDrawOffset(0, 0)
|
gfx.setDrawOffset(0, 0)
|
||||||
Score:draw()
|
Score:draw()
|
||||||
|
|
||||||
|
if playdate.buttonJustPressed(playdate.kButtonA) then
|
||||||
|
Cart.reset(cart)
|
||||||
|
init()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,9 +9,9 @@ Camera = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
expireBelowScreenSystem = filteredSystem("expireBelowScreen", { position = T.XyPair, expireBelowScreenBy = T.number })
|
expireBelowScreenSystem = filteredSystem({ position = T.XyPair, expireBelowScreenBy = T.number })
|
||||||
|
|
||||||
cameraPanSystem = filteredSystem("cameraPan", { 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
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
collidingEntities = filteredSystem("collidingEntitites", {
|
collidingEntities = filteredSystem({
|
||||||
velocity = T.XyPair,
|
|
||||||
position = T.XyPair,
|
position = T.XyPair,
|
||||||
size = T.XyPair,
|
size = T.XyPair,
|
||||||
canCollideWith = T.bitMask,
|
canCollideWith = T.bitMask,
|
||||||
isSolid = Maybe(T.bool),
|
isSolid = Maybe(T.bool),
|
||||||
})
|
})
|
||||||
|
|
||||||
collisionDetection = filteredSystem("collisionDetection",
|
collisionDetection = filteredSystem(
|
||||||
{ position = T.XyPair, size = T.XyPair, canBeCollidedBy = T.bitMask, isSolid = Maybe(T.bool) },
|
{ position = T.XyPair, size = T.XyPair, canBeCollidedBy = T.bitMask, isSolid = Maybe(T.bool) },
|
||||||
-- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
|
-- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
|
||||||
function(e, _, system)
|
function(e, _, system)
|
||||||
for _, collider in pairs(collidingEntities.entities) do
|
for _, collider in pairs(collidingEntities.entities) do
|
||||||
if (e ~= collider) and collider.canCollideWith and e.canBeCollidedBy and ((collider.canCollideWith & e.canBeCollidedBy) ~= 0) then
|
if (e ~= collider) and collider.canCollideWith and ((collider.canCollideWith & e.canBeCollidedBy) ~= 0) then
|
||||||
local colliderTop = collider.position.y
|
local colliderTop = collider.position.y
|
||||||
local colliderBottom = collider.position.y + collider.size.y
|
local colliderBottom = collider.position.y + collider.size.y
|
||||||
local entityTop = e.position.y
|
local entityTop = e.position.y
|
||||||
|
@ -34,8 +33,3 @@ collisionDetection = filteredSystem("collisionDetection",
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
function collisionDetection:preProcess()
|
|
||||||
-- print("collidingEntities count: " .. #collidingEntities.entities)
|
|
||||||
-- print("collidedEntities count: " .. #self.entities)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
collisionResolution = filteredSystem("collisionResolution", { collisionBetween = T.Collision }, function(e, dt, system)
|
collisionResolution = filteredSystem({ collisionBetween = T.Collision }, function(e, dt, system)
|
||||||
local collidedInto, collider = e.collisionBetween[1], e.collisionBetween[2]
|
local collidedInto, collider = e.collisionBetween[1], e.collisionBetween[2]
|
||||||
local colliderTop = collidedInto.position.y
|
local colliderTop = collidedInto.position.y
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ collisionResolution = filteredSystem("collisionResolution", { collisionBetween =
|
||||||
|
|
||||||
if collider.focusOnCollide then
|
if collider.focusOnCollide then
|
||||||
system.world:addEntity({
|
system.world:addEntity({
|
||||||
removeAtRoundStart = true,
|
|
||||||
focusPriority = collider.focusOnCollide,
|
focusPriority = collider.focusOnCollide,
|
||||||
position = {
|
position = {
|
||||||
x = collider.position.x,
|
x = collider.position.x,
|
||||||
|
|
|
@ -1,49 +1,13 @@
|
||||||
local gfx <const> = playdate.graphics
|
local gfx <const> = playdate.graphics
|
||||||
|
|
||||||
drawRectanglesSystem = filteredSystem("drawRectangles", { position = T.XyPair, drawAsRectangle = { size = T.XyPair } }, function(e, dt)
|
drawRectanglesSystem = filteredSystem({ position = T.XyPair, drawAsRectangle = { size = T.XyPair } }, function(e, dt)
|
||||||
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)
|
||||||
|
|
||||||
drawSpriteSystem = filteredSystem("drawSprites", { position = T.XyPair, drawAsSprite = T.PdImage }, function(e, dt, system)
|
drawTextSystem = filteredSystem({ position = T.XyPair, drawAsText = { text = T.str } }, function(e, dt)
|
||||||
e.drawAsSprite:draw(e.position.x, e.position.y)
|
gfx.drawTextAligned(e.drawAsText.text, e.position.x, e.position.y, gfx.kAlignCenter)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local textHeight = AshevilleSans14Bold:getHeight()
|
drawSpriteSystem = filteredSystem({ position = T.XyPair, drawAsSprite = T.PdImage }, function(e, dt, system)
|
||||||
local xMargin = 4
|
e.drawAsSprite:draw(e.position.x, e.position.y)
|
||||||
|
end)
|
||||||
drawTextSystem = filteredSystem("drawText",
|
|
||||||
{ position = T.XyPair, drawAsText = { text = T.str, style = Maybe(T.str) } },
|
|
||||||
function(e, dt)
|
|
||||||
local textWidth = AshevilleSans14Bold:getTextWidth(e.drawAsText.text)
|
|
||||||
if e.drawAsText.style == TextStyle.Inverted then
|
|
||||||
gfx.fillRect(
|
|
||||||
e.position.x - xMargin - textWidth / 2,
|
|
||||||
e.position.y - 2,
|
|
||||||
textWidth + (xMargin * 2),
|
|
||||||
textHeight + 2
|
|
||||||
)
|
|
||||||
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
|
||||||
end
|
|
||||||
if e.drawAsText.style == TextStyle.Bordered then
|
|
||||||
gfx.setColor(gfx.kColorWhite)
|
|
||||||
gfx.fillRect(
|
|
||||||
e.position.x - xMargin - textWidth / 2,
|
|
||||||
e.position.y - 2,
|
|
||||||
textWidth + (xMargin * 2),
|
|
||||||
textHeight + 2
|
|
||||||
)
|
|
||||||
gfx.setColor(gfx.kColorBlack)
|
|
||||||
gfx.setImageDrawMode(gfx.kDrawModeCopy)
|
|
||||||
gfx.drawRect(
|
|
||||||
e.position.x - xMargin - textWidth / 2,
|
|
||||||
e.position.y - 2,
|
|
||||||
textWidth + (xMargin * 2),
|
|
||||||
textHeight + 2
|
|
||||||
)
|
|
||||||
end
|
|
||||||
AshevilleSans14Bold:drawTextAligned(e.drawAsText.text, e.position.x, e.position.y, kTextAlignment.center)
|
|
||||||
if e.drawAsText.style == TextStyle.Inverted then
|
|
||||||
gfx.setImageDrawMode(gfx.kDrawModeCopy)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
|
@ -18,8 +18,6 @@ local XyPair = { x = 1, y = 1 }
|
||||||
|
|
||||||
---@alias CanSpawn { entity: Entity }
|
---@alias CanSpawn { entity: Entity }
|
||||||
|
|
||||||
---@alias InRelations Entity[]
|
|
||||||
|
|
||||||
T = {
|
T = {
|
||||||
XyPair = XyPair,
|
XyPair = XyPair,
|
||||||
bool = true,
|
bool = true,
|
||||||
|
@ -51,12 +49,6 @@ T = {
|
||||||
RoundStateAction = "start",
|
RoundStateAction = "start",
|
||||||
---@type CanSpawn
|
---@type CanSpawn
|
||||||
CanSpawn = {},
|
CanSpawn = {},
|
||||||
---@type InRelations
|
|
||||||
InRelations = {},
|
|
||||||
---@type InputState
|
|
||||||
InputState = {},
|
|
||||||
---@type Entity
|
|
||||||
Entity = {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
@ -65,9 +57,3 @@ T = {
|
||||||
function Maybe(t)
|
function Maybe(t)
|
||||||
return { maybe = t }
|
return { maybe = t }
|
||||||
end
|
end
|
||||||
|
|
||||||
TextStyle = {
|
|
||||||
Inverted = "INVERTED",
|
|
||||||
Bordered = "BORDERED",
|
|
||||||
None = "None",
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
local G = -300
|
local G = -300
|
||||||
fallSystem = filteredSystem("fall", { velocity = T.XyPair, mass = T.number }, function(e, dt)
|
fallSystem = filteredSystem({ velocity = T.XyPair, mass = T.number }, function(e, dt)
|
||||||
e.velocity.y = e.velocity.y - (G * dt * e.mass) - (0.5 * dt * dt)
|
e.velocity.y = e.velocity.y - (G * dt * e.mass) - (0.5 * dt * dt)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
---@alias InputState { upJustPressed: boolean, downJustPressed: boolean, rightJustPressed: boolean, leftJustPressed: boolean, aJustPressed: boolean, bJustPressed: boolean }
|
|
||||||
|
|
||||||
local buttonJustPressed = playdate.buttonJustPressed
|
|
||||||
local inputState = {}
|
|
||||||
|
|
||||||
inputSystem = filteredSystem("input", { canReceiveInput = T.marker }, function(e, _, system)
|
|
||||||
e.inputState = inputState
|
|
||||||
system.world:addEntity(e)
|
|
||||||
end)
|
|
||||||
|
|
||||||
function inputSystem:preProcess()
|
|
||||||
inputState.upJustPressed = buttonJustPressed(playdate.kButtonUp)
|
|
||||||
inputState.downJustPressed = buttonJustPressed(playdate.kButtonDown)
|
|
||||||
inputState.rightJustPressed = buttonJustPressed(playdate.kButtonRight)
|
|
||||||
inputState.leftJustPressed = buttonJustPressed(playdate.kButtonLeft)
|
|
||||||
inputState.aJustPressed = buttonJustPressed(playdate.kButtonA)
|
|
||||||
inputState.bJustPressed = buttonJustPressed(playdate.kButtonB)
|
|
||||||
end
|
|
|
@ -1,31 +0,0 @@
|
||||||
---@alias MenuItem { onSelect: fun(), highlighted: boolean, navigateDown: MenuItem | nil, navigateUp: MenuItem | nil }
|
|
||||||
|
|
||||||
---@type MenuItem[]
|
|
||||||
local MenuItems = {}
|
|
||||||
|
|
||||||
menuController = filteredSystem("menuController", { menuItems = MenuItems, inputState = T.InputState }, function(e, _, system)
|
|
||||||
for _, menuItem in pairs(e.menuItems) do
|
|
||||||
if menuItem.highlighted then
|
|
||||||
if e.inputState.aJustPressed then
|
|
||||||
menuItem.onSelect(system.world)
|
|
||||||
end
|
|
||||||
if e.inputState.downJustPressed and menuItem.navigateDown then
|
|
||||||
menuItem.highlighted = false
|
|
||||||
menuItem.navigateDown.highlighted = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if e.inputState.upJustPressed and menuItem.navigateUp then
|
|
||||||
menuItem.highlighted = false
|
|
||||||
menuItem.navigateUp.highlighted = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, menuItem in pairs(e.menuItems) do
|
|
||||||
if menuItem.highlighted then
|
|
||||||
menuItem.drawAsText.style = TextStyle.Inverted
|
|
||||||
else
|
|
||||||
menuItem.drawAsText.style = TextStyle.Bordered
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
|
@ -15,24 +15,27 @@ local function normalizeVector(xy1, xy2)
|
||||||
return x / distance, y / distance, distance
|
return x / distance, y / distance, distance
|
||||||
end
|
end
|
||||||
|
|
||||||
moveTowardSystem = filteredSystem("moveToward", { moveToward = MoveToward, position = T.XyPair }, function(e, dt, system)
|
moveTowardSystem = filteredSystem(
|
||||||
local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target)
|
{ moveToward = MoveToward, position = T.XyPair },
|
||||||
if distance > e.moveToward.range then
|
function(e, dt, system)
|
||||||
return
|
local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target)
|
||||||
end
|
if distance > e.moveToward.range then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO May be incorrect when signs are mismatched between vel and diff
|
-- TODO May be incorrect when signs are mismatched between vel and diff
|
||||||
local xVel = xNorm * e.moveToward.speed * dt
|
local xVel = xNorm * e.moveToward.speed * dt
|
||||||
if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then
|
if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then
|
||||||
e.position.x = e.moveToward.target.x
|
e.position.x = e.moveToward.target.x
|
||||||
else
|
else
|
||||||
e.position.x = e.position.x + xVel
|
e.position.x = e.position.x + xVel
|
||||||
end
|
end
|
||||||
|
|
||||||
local yVel = yNorm * e.moveToward.speed * dt
|
local yVel = yNorm * e.moveToward.speed * dt
|
||||||
if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then
|
if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then
|
||||||
e.position.y = e.moveToward.target.y
|
e.position.y = e.moveToward.target.y
|
||||||
else
|
else
|
||||||
e.position.y = e.position.y + yVel
|
e.position.y = e.position.y + yVel
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
)
|
||||||
|
|
|
@ -1,66 +1,10 @@
|
||||||
collectedEntities = filteredSystem("collectedEntities", { collected = T.PdImage })
|
collectedEntities = filteredSystem({ collected = T.PdImage })
|
||||||
|
|
||||||
local onCollidingRemove = { "mass", "velocity", "canCollideWith" }
|
local onCollidingRemove = { "mass", "velocity", "canCollideWith" }
|
||||||
|
|
||||||
local Drop = { i = T.number, delay = T.number, startAt = T.XyPair }
|
roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Maybe(T.XyPair) }, function(e, _, system)
|
||||||
|
if e.roundAction == "end" then
|
||||||
disableCollisionWhenRoundEnds = filteredSystem("disableCollisionWhenRoundEnds", { disableCollisionWhenRoundEnds = T.marker })
|
playdate.setAutoLockDisabled(false)
|
||||||
|
|
||||||
collectableDropSystem = filteredSystem("collectableDrop", { drop = Drop }, function(e, dt, system)
|
|
||||||
e.drop.delay = e.drop.delay - dt
|
|
||||||
if e.drop.delay > 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local collX, collY = e.drop.sprite:getSize()
|
|
||||||
system.world:addEntity({
|
|
||||||
drawAsSprite = e.drop.sprite,
|
|
||||||
size = { x = collX, y = collY / 2 },
|
|
||||||
mass = 0.5,
|
|
||||||
velocity = { x = 0, y = 0 },
|
|
||||||
position = { x = e.drop.startAt.x - (collX / 2), y = e.drop.startAt.y },
|
|
||||||
canCollideWith = 2,
|
|
||||||
canBeCollidedBy = 2,
|
|
||||||
isSolid = true,
|
|
||||||
stopMovingOnCollision = true,
|
|
||||||
onCollidingRemove = onCollidingRemove,
|
|
||||||
focusOnCollide = e.drop.i,
|
|
||||||
expireBelowScreenBy = 5,
|
|
||||||
removeAtRoundStart = true,
|
|
||||||
})
|
|
||||||
system.world:removeEntity(e)
|
|
||||||
end)
|
|
||||||
|
|
||||||
removeAtRoundStart = filteredSystem("removeAtRoundStart", { removeAtRoundStart = T.bool })
|
|
||||||
|
|
||||||
filteredSystem("afterDelayAdd", { afterDelayAdd = { entity = T.Entity, delay = T.number } }, function(e, dt, system)
|
|
||||||
e.afterDelayAdd.delay = e.afterDelayAdd.delay - dt
|
|
||||||
if e.afterDelayAdd.delay > 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
system.world:addEntity(e.afterDelayAdd.entity)
|
|
||||||
system.world:removeEntity(e)
|
|
||||||
end)
|
|
||||||
|
|
||||||
roundSystem = filteredSystem("round", { roundAction = T.RoundStateAction, position = Maybe(T.XyPair) }, function(e, _, system)
|
|
||||||
if e.roundAction == "start" then
|
|
||||||
for _, cart in pairs(cartSystem.entities) do
|
|
||||||
Cart.reset(cart)
|
|
||||||
system.world:addEntity(cart)
|
|
||||||
end
|
|
||||||
for _, remove in pairs(removeAtRoundStart.entities) do
|
|
||||||
system.world:removeEntity(remove)
|
|
||||||
end
|
|
||||||
system.world:addSystem(spawnerSystem)
|
|
||||||
Ingredients.clearCache(system.world)
|
|
||||||
elseif e.roundAction == "end" then
|
|
||||||
system.world:removeSystem(spawnerSystem)
|
|
||||||
for _, toExpire in pairs(disableCollisionWhenRoundEnds.entities) do
|
|
||||||
toExpire.canCollideWith = nil
|
|
||||||
toExpire.canBeCollidedBy = nil
|
|
||||||
--system.world:addEntity(toExpire)
|
|
||||||
system.world:removeEntity(toExpire)
|
|
||||||
end
|
|
||||||
-- playdate.setAutoLockDisabled(false)
|
|
||||||
|
|
||||||
local y = e.position.y - 240
|
local y = e.position.y - 240
|
||||||
local rectWidth = 150
|
local rectWidth = 150
|
||||||
|
@ -76,84 +20,59 @@ roundSystem = filteredSystem("round", { roundAction = T.RoundStateAction, positi
|
||||||
canBeCollidedBy = 2,
|
canBeCollidedBy = 2,
|
||||||
isSolid = true,
|
isSolid = true,
|
||||||
stopMovingOnCollision = true,
|
stopMovingOnCollision = true,
|
||||||
removeAtRoundStart = true,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TODO: Big ol' numbers displaying how many ingredients were collected?
|
local delayPerDrop = 150
|
||||||
-- TODO: Could layer ingredients in rows of three? Maybe just when it's higher?
|
|
||||||
local delayPerDrop = 0.100
|
|
||||||
local delay = 0
|
local delay = 0
|
||||||
for i, collectable in ipairs(collectedEntities.entities) do
|
for i, collectable in ipairs(collectedEntities.entities) do
|
||||||
local _, collY = collectable.collected:getSize()
|
local collX, collY = collectable.collected:getSize()
|
||||||
y = y - collY - 15
|
y = y - collY - 15
|
||||||
system.world:addEntity({
|
playdate.timer.new(delay, function(ee, ccollX, ccollY, yy, ii, ssystem, ccollectable)
|
||||||
drop = {
|
ssystem.world:addEntity({
|
||||||
sprite = collectable.collected,
|
drawAsSprite = ccollectable.collected,
|
||||||
i = i,
|
size = { x = ccollX, y = ccollY / 2 },
|
||||||
delay = delay,
|
mass = 0.5,
|
||||||
startAt = {
|
velocity = { x = 0, y = 0 },
|
||||||
x = e.position.x,
|
position = { x = ee.position.x - (ccollX / 2), y = yy },
|
||||||
y = y
|
canCollideWith = 2,
|
||||||
}
|
canBeCollidedBy = 2,
|
||||||
},
|
isSolid = true,
|
||||||
})
|
stopMovingOnCollision = true,
|
||||||
|
onCollidingRemove = onCollidingRemove,
|
||||||
|
focusOnCollide = ii,
|
||||||
|
expireBelowScreenBy = 5,
|
||||||
|
})
|
||||||
|
end, e, collX, collY, y, i, system, collectable)
|
||||||
delay = delay + delayPerDrop
|
delay = delay + delayPerDrop
|
||||||
system.world:removeEntity(collectable)
|
system.world:removeEntity(collectable)
|
||||||
end
|
end
|
||||||
|
|
||||||
local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3)
|
local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3)
|
||||||
-- Sorting from shortest to longest sort of makes them look like a bun?
|
|
||||||
table.sort(availableUpgrades, function(a, b)
|
|
||||||
return #a.name > #b.name
|
|
||||||
end)
|
|
||||||
|
|
||||||
y = y - 50
|
y = y - 50
|
||||||
local menuEntity = {
|
|
||||||
menuItems = {},
|
|
||||||
canReceiveInput = T.marker,
|
|
||||||
}
|
|
||||||
local upgradeBelow
|
|
||||||
local i = #collectedEntities.entities
|
|
||||||
for _, upgrade in ipairs(availableUpgrades) do
|
for _, upgrade in ipairs(availableUpgrades) do
|
||||||
i = i + 1
|
printTable(upgrade)
|
||||||
local collX, collY = 75, 21
|
local collX, collY = 75, 30
|
||||||
y = y - collY - 15 - 15
|
y = y - collY - 15
|
||||||
local upgradeEntity = {
|
playdate.timer.new(delay, function(ee, ccollX, ccollY, yy, ii, ssystem, ccollectable)
|
||||||
onSelect = upgrade.apply,
|
ssystem.world:addEntity({
|
||||||
drawAsText = {
|
drawAsText = {
|
||||||
text = upgrade.name,
|
text = upgrade.name,
|
||||||
style = TextStyle.Inverted,
|
},
|
||||||
},
|
size = { x = ccollX, y = ccollY / 2 },
|
||||||
size = { x = collX, y = collY },
|
mass = 0.5,
|
||||||
mass = 0.5,
|
velocity = { x = 0, y = 0 },
|
||||||
velocity = { x = 0, y = 0 },
|
position = { x = ee.position.x - (ccollX / 2), y = yy },
|
||||||
position = { x = e.position.x, y = y },
|
canCollideWith = 2,
|
||||||
canCollideWith = 2,
|
canBeCollidedBy = 2,
|
||||||
canBeCollidedBy = 2,
|
isSolid = true,
|
||||||
isSolid = true,
|
stopMovingOnCollision = true,
|
||||||
stopMovingOnCollision = true,
|
onCollidingRemove = onCollidingRemove,
|
||||||
onCollidingRemove = onCollidingRemove,
|
focusOnCollide = ii,
|
||||||
focusOnCollide = i,
|
})
|
||||||
navigateDown = upgradeBelow,
|
end, e, collX, collY, y, i, system, collectable)
|
||||||
highlighted = true,
|
|
||||||
removeAtRoundStart = true,
|
|
||||||
}
|
|
||||||
if upgradeBelow then
|
|
||||||
upgradeBelow.navigateUp = upgradeEntity
|
|
||||||
upgradeBelow.highlighted = false
|
|
||||||
upgradeBelow.drawAsText.style = TextStyle.Bordered
|
|
||||||
end
|
|
||||||
upgradeBelow = upgradeEntity
|
|
||||||
menuEntity.menuItems[#menuEntity.menuItems + 1] = upgradeEntity
|
|
||||||
delay = delay + delayPerDrop
|
delay = delay + delayPerDrop
|
||||||
system.world:addEntity({
|
|
||||||
afterDelayAdd = {
|
|
||||||
delay = delay,
|
|
||||||
entity = upgradeEntity
|
|
||||||
},
|
|
||||||
})
|
|
||||||
system.world:addEntity(menuEntity)
|
|
||||||
end
|
end
|
||||||
|
system.world:removeEntity(e)
|
||||||
end
|
end
|
||||||
system.world:removeEntity(e)
|
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -3,7 +3,7 @@ local odds = 0
|
||||||
---@type { canSpawn: CanSpawn }
|
---@type { canSpawn: CanSpawn }
|
||||||
local selectedSpawner
|
local selectedSpawner
|
||||||
|
|
||||||
spawnerSystem = filteredSystem("spawner", { canSpawn = T.CanSpawn, odds = T.number }, function(spawner, _, _)
|
spawnerSystem = filteredSystem({ canSpawn = T.CanSpawn, odds = T.number }, function(spawner, _, _)
|
||||||
if odds <= 0 then
|
if odds <= 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -35,7 +35,7 @@ function spawnerSystem:preProcess()
|
||||||
return tiny.SKIP_PROCESS
|
return tiny.SKIP_PROCESS
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawnEveryX = 30
|
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()
|
||||||
|
@ -55,6 +55,8 @@ function spawnerSystem:postProcess()
|
||||||
self.world:addEntity(newlySpawned)
|
self.world:addEntity(newlySpawned)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local expireWhenOffScreenBy = { x = 2000, y = 480 }
|
||||||
|
|
||||||
---@param world World
|
---@param world World
|
||||||
function addAllSpawners(world)
|
function addAllSpawners(world)
|
||||||
function addCollectableSpawner(name, spawnerOdds, score, sprite, canBounce, yRange)
|
function addCollectableSpawner(name, spawnerOdds, score, sprite, canBounce, yRange)
|
||||||
|
@ -76,7 +78,6 @@ function addAllSpawners(world)
|
||||||
drawAsSprite = sprite,
|
drawAsSprite = sprite,
|
||||||
collectable = sprite,
|
collectable = sprite,
|
||||||
expireWhenOffScreenBy = expireWhenOffScreenBy,
|
expireWhenOffScreenBy = expireWhenOffScreenBy,
|
||||||
disableCollisionWhenRoundEnds = T.marker,
|
|
||||||
canBounce = canBounce,
|
canBounce = canBounce,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -84,7 +85,7 @@ function addAllSpawners(world)
|
||||||
end
|
end
|
||||||
|
|
||||||
addCollectableSpawner("Lettuce", 0.7, 1, LettuceSprite, {
|
addCollectableSpawner("Lettuce", 0.7, 1, LettuceSprite, {
|
||||||
flat = { x = 12, y = 220 },
|
flat = { x = 22, y = 190 },
|
||||||
mult = { x = 1, y = -0.5 },
|
mult = { x = 1, y = -0.5 },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -108,30 +109,24 @@ function getAvailableSpawnerUpgrades()
|
||||||
local upgrades = {}
|
local upgrades = {}
|
||||||
for _, spawner in pairs(spawnerSystem.entities) do
|
for _, spawner in pairs(spawnerSystem.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.canSpawn.entity.score then
|
if spawner.canSpawn.entity.score then
|
||||||
local name = "Double " .. spawner.name .. " value"
|
|
||||||
upgrades[#upgrades + 1] = {
|
upgrades[#upgrades + 1] = {
|
||||||
name = name,
|
name = "Double " .. spawner.name .. " value",
|
||||||
apply = function(world)
|
apply = function()
|
||||||
print("Applying " .. name)
|
|
||||||
spawner.canSpawn.entity.score = spawner.canSpawn.entity.score * 2
|
spawner.canSpawn.entity.score = spawner.canSpawn.entity.score * 2
|
||||||
world:addEntity({ roundAction = "start" })
|
end
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(spawner.odds, "Expected all spawners to have an `odds` field!")
|
assert(spawner.odds, "Expected all spawners to have an `odds` field!")
|
||||||
local name = "Double " .. spawner.name .. " frequency"
|
|
||||||
upgrades[#upgrades + 1] = {
|
upgrades[#upgrades + 1] = {
|
||||||
name = name,
|
name = "Double " .. spawner.name .. " frequency",
|
||||||
apply = function(world)
|
apply = function()
|
||||||
print("Applying " .. name)
|
|
||||||
spawner.odds = spawner.odds * 2
|
spawner.odds = spawner.odds * 2
|
||||||
world:addEntity({ roundAction = "start" })
|
end
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- if not spawner.canSpawn.entity.velocity then
|
-- if not spawner.canSpawn.entity.velocity then
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
local sqrt = math.sqrt
|
local sqrt = math.sqrt
|
||||||
|
|
||||||
velocitySystem = filteredSystem("velocity", { position = T.XyPair, velocity = T.XyPair }, function(e, dt, system)
|
velocitySystem = filteredSystem({ position = T.XyPair, velocity = T.XyPair }, function(e, dt, system)
|
||||||
if sqrt((e.velocity.x * e.velocity.x) + (e.velocity.y * e.velocity.y)) < 2 then
|
if not e.velocity then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if sqrt((e.velocity.x * e.velocity.x) + (e.velocity.y * e.velocity.y)) < 1.5 then
|
||||||
e.velocity = nil
|
e.velocity = nil
|
||||||
if e.spawnEntitiesWhenStopped then
|
if e.spawnEntitiesWhenStopped then
|
||||||
e:spawnEntitiesWhenStopped(system.world)
|
e:spawnEntitiesWhenStopped(system.world)
|
||||||
|
|
|
@ -13,9 +13,8 @@ local isSimulator = playdate.isSimulator
|
||||||
---@param shape T
|
---@param shape T
|
||||||
---@param process fun(entity: T, dt: number, system: System)
|
---@param process fun(entity: T, dt: number, system: System)
|
||||||
---@return System | { entities: T[] }
|
---@return System | { entities: T[] }
|
||||||
function filteredSystem(name, shape, process)
|
function filteredSystem(shape, process)
|
||||||
local system = tiny.processingSystem()
|
local system = tiny.processingSystem()
|
||||||
system.name = name
|
|
||||||
local keys = {}
|
local keys = {}
|
||||||
for key, value in pairs(shape) do
|
for key, value in pairs(shape) do
|
||||||
if type(value) ~= "table" or value.maybe == nil then
|
if type(value) ~= "table" or value.maybe == nil then
|
||||||
|
|
|
@ -4,7 +4,7 @@ Utils = {}
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param fromArr T[]
|
---@param fromArr T[]
|
||||||
---@param n number
|
---@param n number
|
||||||
---@return T[]
|
---@generic T[]
|
||||||
function Utils.getNDifferentValues(fromArr, n)
|
function Utils.getNDifferentValues(fromArr, n)
|
||||||
assert(n >= 0, "n must be a non-negative integer")
|
assert(n >= 0, "n must be a non-negative integer")
|
||||||
if n > #fromArr then
|
if n > #fromArr then
|
||||||
|
@ -26,49 +26,3 @@ function Utils.getNDifferentValues(fromArr, n)
|
||||||
end
|
end
|
||||||
return randoms
|
return randoms
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Track the number of instances of a given element, instead of needing multiple copies.
|
|
||||||
---@class CountSet
|
|
||||||
---@field private data table<table, number>
|
|
||||||
---@field private elementCount number
|
|
||||||
CountSet = {}
|
|
||||||
|
|
||||||
function CountSet.new()
|
|
||||||
return setmetatable({ data = {}, elementCount = 0 }, { __index = CountSet })
|
|
||||||
end
|
|
||||||
|
|
||||||
function CountSet:add(element)
|
|
||||||
local existing = self.data[element]
|
|
||||||
if existing then
|
|
||||||
self.data[element] = existing + 1
|
|
||||||
else
|
|
||||||
self.data[element] = 1
|
|
||||||
end
|
|
||||||
self.elementCount = self.elementCount + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
function CountSet:balancedRandomPop()
|
|
||||||
if self.elementCount == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local toPop = math.random(self.elementCount)
|
|
||||||
for element, count in pairs(self.data) do
|
|
||||||
toPop = toPop - count
|
|
||||||
if toPop <= 0 then
|
|
||||||
local newCount = count - 1
|
|
||||||
if newCount == 0 then
|
|
||||||
self.data[element] = nil
|
|
||||||
else
|
|
||||||
self.data[element] = newCount
|
|
||||||
end
|
|
||||||
self.elementCount = self.elementCount - 1
|
|
||||||
return element
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function CountSet:iterRandom()
|
|
||||||
return function()
|
|
||||||
return self:balancedRandomPop()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
Loading…
Reference in New Issue