Add directional sticky and skewer box variants

This commit is contained in:
Your Name 2026-08-11 15:07:11 -04:00
parent c3f5aafd77
commit f549eaf523
13 changed files with 723 additions and 101 deletions

View file

@ -59,6 +59,53 @@ glow = love.graphics.newShader[[
}
]]
-- Sticky boxes reuse the authored box textures. This shader only wobbles their
-- sampling; the draw helper adds a tiny squash-and-stretch bounce around center.
goopShader = love.graphics.newShader[[
extern number goopTime;
extern vec2 sourceSize;
float goopHash(float value) {
return fract(sin(value * 91.3458) * 47453.5453);
}
vec4 effect(vec4 color, Image texture, vec2 textureCoords, vec2 screenCoords) {
float sourceY = textureCoords.y;
float pixelWidth = 1.0 / sourceSize.x;
float pixelHeight = 1.0 / sourceSize.y;
float column = floor(textureCoords.x * sourceSize.x / 2.0);
float seed = goopHash(column);
// Two gentle, out-of-phase waves make the surface feel soft and viscous.
// Both stay sub-pixel so the authored silhouette remains recognizable.
float horizontalWave = sin(goopTime * 1.7 + sourceY * 10.0 + seed * 6.2831);
float verticalWave = sin(goopTime * 1.3 + textureCoords.x * 12.0 + seed * 3.1415);
float sourceX = clamp(textureCoords.x + horizontalWave * pixelWidth * 0.45,
pixelWidth * 0.5, 1.0 - pixelWidth * 0.5);
float wobbledY = clamp(sourceY + verticalWave * pixelHeight * 0.28,
pixelHeight * 0.5, 1.0 - pixelHeight * 0.5);
return Texel(texture, vec2(sourceX, wobbledY)) * color;
}
]]
function drawGoopySprite(sprite, x, y, scale)
local w, h = sprite:getWidth(), sprite:getHeight()
local time = love.timer.getTime()
local bounce = math.sin(time * 2.4 + w * .17 + h * .11) * .035
local scaleX = scale * (1 + bounce)
local scaleY = scale * (1 - bounce)
local drawX = x - w * (scaleX - scale) / 2
local drawY = y - h * (scaleY - scale) / 2
goopShader:send("goopTime", time)
goopShader:send("sourceSize", {w, h})
local previousShader = love.graphics.getShader()
love.graphics.setShader(goopShader)
love.graphics.draw(sprite, drawX, drawY, 0, scaleX, scaleY)
love.graphics.setShader(previousShader)
end
-- Accessibility post-process. The puzzle's RGB channels are normally also
-- its visual language, so this runs only after the entire scene has been
-- composed. It leaves neutral UI/text alone and remaps saturated colours to