Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

Commit

Permalink
Implement base for skull rendering
Browse files Browse the repository at this point in the history
The skull opening it's mouth will have to be smoothly animated.

Additive effect, danger skulls on path and death animation TBI.

Contributes to #9
  • Loading branch information
ShamblesSM committed Feb 18, 2023
1 parent 1bf97bd commit bf19d02
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 12 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/ZumaBlitzRemake/images/game/skull_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/ZumaBlitzRemake/images/game/skull_hole.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/ZumaBlitzRemake/images/game/skull_mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/ZumaBlitzRemake/images/game/skull_top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions games/ZumaBlitzRemake/sprites/game/skull_bottom.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"path": "images/game/skull_bottom.png",
"frame_size": {
"x": 41,
"y": 20
},
"states": [
{
"pos": {
"x": 0,
"y": 0
},
"frames": {
"x": 1,
"y": 1
}
}
],
"internal": false,
"batched": false
}
21 changes: 21 additions & 0 deletions games/ZumaBlitzRemake/sprites/game/skull_frame.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"path": "images/game/skull_frame.png",
"frame_size": {
"x": 65,
"y": 65
},
"states": [
{
"pos": {
"x": 0,
"y": 0
},
"frames": {
"x": 1,
"y": 1
}
}
],
"internal": false,
"batched": false
}
21 changes: 21 additions & 0 deletions games/ZumaBlitzRemake/sprites/game/skull_hole.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"path": "images/game/skull_hole.png",
"frame_size": {
"x": 56,
"y": 56
},
"states": [
{
"pos": {
"x": 0,
"y": 0
},
"frames": {
"x": 1,
"y": 1
}
}
],
"internal": false,
"batched": false
}
21 changes: 21 additions & 0 deletions games/ZumaBlitzRemake/sprites/game/skull_mask.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"path": "images/game/skull_mask.png",
"frame_size": {
"x": 56,
"y": 55
},
"states": [
{
"pos": {
"x": 0,
"y": 0
},
"frames": {
"x": 1,
"y": 1
}
}
],
"internal": false,
"batched": false
}
21 changes: 21 additions & 0 deletions games/ZumaBlitzRemake/sprites/game/skull_top.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"path": "images/game/skull_top.png",
"frame_size": {
"x": 42,
"y": 35
},
"states": [
{
"pos": {
"x": 0,
"y": 0
},
"frames": {
"x": 1,
"y": 1
}
}
],
"internal": false,
"batched": false
}
60 changes: 53 additions & 7 deletions src/Map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,31 @@ function Map:new(level, path, pathsBehavior, isDummy)
table.insert(self.paths, Path(self, pathData, pathBehavior))
end
self.shooter = data.shooter
self.targetPoints = data.targetPoints
self.targetPoints = data.targetPoints

-- FORK-SPECIFIC CODE:
-- Skulls. SPRITES ARE HARDCODED, DE-HARDCODE FIRST AND ALLOW FOR
-- CUSTOMIZATION BY THE MODDER IF THIS IS TO BE IMPLEMENTED TO UPSTREAM.
self.skullHoleSprite = _Game.resourceManager:getSprite("sprites/game/skull_hole.json")
self.skullMaskSprite = _Game.resourceManager:getSprite("sprites/game/skull_mask.json")
self.skullFrameSprite = _Game.resourceManager:getSprite("sprites/game/skull_frame.json")
self.skullTopSprite = _Game.resourceManager:getSprite("sprites/game/skull_top.json")
self.skullBottomSprite = _Game.resourceManager:getSprite("sprites/game/skull_bottom.json")
self.skullMaskShader = love.graphics.newShader[[
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) {
if (Texel(texture, texture_coords).rgb == vec3(0.0)) {
// a discarded pixel wont be applied as the stencil.
discard;
}
return vec4(1.0);
}
]]

self.skullPoints = {}
for _, path in pairs(self.paths) do
local lastPoint = path.nodes[#path.nodes].pos
table.insert(self.skullPoints, Vec2.round(lastPoint))
end
end


Expand Down Expand Up @@ -98,13 +122,35 @@ function Map:draw()
end

-- Objects that will be drown when the BCM is off
if not _Debug.e then
for i, sprite in ipairs(self.sprites) do
if not sprite.background then
sprite.sprite:draw(sprite.pos)
end
end
if not _Debug.e then
for i, sprite in ipairs(self.sprites) do
if not sprite.background then
sprite.sprite:draw(sprite.pos)
end
end
end

-- FORK-SPECIFIC CODE: skull rendering goes here
-- i took this from the love2d page is this a dirty way to do it
for i, pos in pairs(self.skullPoints) do
self.skullHoleSprite:draw(pos, Vec2(0.5,0.5))
love.graphics.stencil(function()
love.graphics.setShader(self.skullMaskShader)
self.skullMaskSprite:draw(pos, Vec2(0.5,0.5))
love.graphics.setShader()
end, "replace", 1)
love.graphics.setStencilTest("greater", 0)

local skullTopPos = Vec2(pos.x, (pos.y-3) - (self.paths[i]:getDangerProgress()*20))
local skullBotPos = Vec2(pos.x, pos.y+10)

self.skullTopSprite:draw(skullTopPos, Vec2(0.5,0.5))
self.skullBottomSprite:draw(skullBotPos, Vec2(0.5, 0.5))

love.graphics.setStencilTest()
self.skullFrameSprite:draw(pos, Vec2(0.5,0.5))
end
-- END FORK-SPECIFIC CODE
end


Expand Down
15 changes: 10 additions & 5 deletions src/Path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,16 @@ end
---Returns 0 if this path is not in danger, and linearly interpolates from 0 (danger point) to 1 (end of the path).
---@return number
function Path:getDangerProgress()
local maxOffset = self:getMaxOffset()
if not self:getDanger(maxOffset) then
return 0
end
return ((maxOffset / self.length) - self.dangerDistance) / (1 - self.dangerDistance)
local maxOffset = self:getMaxOffset()
-- FORK-SPECIFIC CHANGE:
-- Return 1 if the level is lost so the skull is wide open on failure.
-- Also, math.min the return value since it messes with the skull rendering.
if self.map.level.lost then
return 1
elseif not self:getDanger(maxOffset) then
return 0
end
return math.min(1, ((maxOffset / self.length) - self.dangerDistance) / (1 - self.dangerDistance))
end


Expand Down

0 comments on commit bf19d02

Please sign in to comment.