aboutsummaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/characters/characters-data.lua12
-rw-r--r--assets/gui/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--assets/images/.DS_Storebin0 -> 6148 bytes
-rw-r--r--assets/images/tile.pngbin0 -> 923 bytes
-rw-r--r--assets/images/tile_colored.pngbin0 -> 1182 bytes
-rw-r--r--assets/scripts/character-select.lua2
-rw-r--r--assets/scripts/local2P.lua258
-rw-r--r--assets/scripts/mainMenu.lua2
8 files changed, 207 insertions, 67 deletions
diff --git a/assets/characters/characters-data.lua b/assets/characters/characters-data.lua
index f0e0b42..c787b56 100644
--- a/assets/characters/characters-data.lua
+++ b/assets/characters/characters-data.lua
@@ -1,38 +1,34 @@
return {
{
name = "Cobalt Phantom",
- lives = 3,
speed = 240,
moves = {"teleportation", "quick_dashes", "smoke_screens", "strikes_from_the_shadows"},
hit_strength = 15,
asset_dir = "assets/characters/Cobalt Phantom",
- jump_strength = 925, -- was 1419 → dropped ~35%
+ jump_strength = 925,
},
{
name = "Emerald Venom",
- lives = 4,
speed = 192,
moves = {"snake_whip", "venom_bite", "poison_of_the_past"},
hit_strength = 12,
asset_dir = "assets/characters/Emerald Venom",
- jump_strength = 990, -- was 1524
+ jump_strength = 990,
},
{
name = "Golden Radiance",
- lives = 5,
speed = 384,
moves = {"solar_boom", "flashbang", "flare_frenzy"},
hit_strength = 13,
asset_dir = "assets/characters/Golden Radiance",
- jump_strength = 890, -- was 1386
+ jump_strength = 890,
},
{
name = "Crimson Reaper",
- lives = 2,
speed = 96,
moves = {"soul_slash", "deaths_reach", "phantom_step", "grim_harvest"},
hit_strength = 17,
asset_dir = "assets/characters/Crimson Reaper",
- jump_strength = 1050, -- was 1662
+ jump_strength = 1050,
}
}
diff --git a/assets/gui/.DS_Store b/assets/gui/.DS_Store
index cc495a7..df5b5e4 100644
--- a/assets/gui/.DS_Store
+++ b/assets/gui/.DS_Store
Binary files differ
diff --git a/assets/images/.DS_Store b/assets/images/.DS_Store
new file mode 100644
index 0000000..aa7349d
--- /dev/null
+++ b/assets/images/.DS_Store
Binary files differ
diff --git a/assets/images/tile.png b/assets/images/tile.png
new file mode 100644
index 0000000..5d397a7
--- /dev/null
+++ b/assets/images/tile.png
Binary files differ
diff --git a/assets/images/tile_colored.png b/assets/images/tile_colored.png
new file mode 100644
index 0000000..63ac985
--- /dev/null
+++ b/assets/images/tile_colored.png
Binary files differ
diff --git a/assets/scripts/character-select.lua b/assets/scripts/character-select.lua
index 06ee574..394ed0f 100644
--- a/assets/scripts/character-select.lua
+++ b/assets/scripts/character-select.lua
@@ -1,4 +1,4 @@
----@diagnostic disable: undefined-global
+---@diagnostic disable: undefined-global, lowercase-global
characters = require("assets.characters.characters-data")
diff --git a/assets/scripts/local2P.lua b/assets/scripts/local2P.lua
index 84ea73d..b425085 100644
--- a/assets/scripts/local2P.lua
+++ b/assets/scripts/local2P.lua
@@ -1,20 +1,29 @@
----@diagnostic disable: undefined-global
+---@diagnostic disable: undefined-global, lowercase-global
backgrounds = require("assets.backgrounds.backgrounds-data")
sprite_height = 128
sprite_width = 64
-gamePaused = false
+remaining_rounds = 9
+current_round = 1
+
+gamePaused = true
isKO = false
+isOverlay = true
+isNewRound = false
+isFight = false
+
+math.randomseed(os.time())
-groundTiles = {
- { x = 250, y = HEIGHT - 300, width = 200, height = 30 },
- { x = WIDTH - 250 - 200, y = HEIGHT - 300, width = 200, height = 30 },
- { x = 0, y = HEIGHT - 100, width = WIDTH, height = 100 }
+groundTiles = {}
+
+specialGroundTiles = {
+ { x = -50, y = 0, width = 55, height = HEIGHT, special = true },
+ { x = WIDTH - 5, y = 0, width = 50, height = HEIGHT, special = true }
}
-knockbackMultiplierX = 35.4
-knockbackMultiplierY = 8.73
+knockbackMultiplierX = 22.4
+knockbackMultiplierY = 7.73
minimalKnockbackMultiplierY = 40.3
@@ -31,6 +40,7 @@ function SafeInitCharacter(character, default_x, default_y)
character.can_apply_knockback = false
character.facing = "right"
character.isDead = false
+ character.wins = 0
end
function Setup()
@@ -38,13 +48,57 @@ function Setup()
setBgImage(backgrounds[bgIndex])
SafeInitCharacter(player1Character, 250, 150)
SafeInitCharacter(player2Character, WIDTH - 250 - (250 / 2), 150)
+
+ groundTiles = {}
+
+ local tileSize = 50
+ local gridWidth = math.floor(WIDTH / tileSize)
+ local gridHeight = math.floor(HEIGHT / tileSize)
+ local clusterSizeMin, clusterSizeMax = 3, 5
+ local clusterCount = 8
+
+ for _ = 1, clusterCount do
+ local clusterX = math.random(1, gridWidth - clusterSizeMax - 2)
+ local clusterY = math.random(5, gridHeight - 3)
+ local clusterSize = math.random(clusterSizeMin, clusterSizeMax)
+
+ for i = 0, clusterSize - 1 do
+ table.insert(groundTiles, {
+ x = (clusterX + i) * tileSize,
+ y = clusterY * tileSize,
+ width = tileSize,
+ height = tileSize,
+ special = false
+ })
+ end
+ end
+
+ for _, tile in ipairs(specialGroundTiles) do
+ table.insert(groundTiles, tile)
+ end
+
+ Timer.after(0.5, function ()
+ isOverlay = false
+ isNewRound = true
+ Timer.after(2, function ()
+ isNewRound = false
+ isFight = true
+ Timer.after(2, function ()
+ isFight = false
+ gamePaused = false
+ end)
+ end)
+ end)
end
gravity = 1570
function DrawGroundTiles()
for _, tile in ipairs(groundTiles) do
- queueRectForRender(tile.x, tile.y, tile.width, tile.height, 100, 100, 100, 255) -- gray boxes
+ if tile.special then
+ return
+ end
+ queueTextureForRender("assets/images/tile.png", tile.x, tile.y)
end
end
@@ -79,73 +133,85 @@ function IsHittingCeiling(character)
return false
end
-function IsTouchingWall(character, direction)
- for _, tile in ipairs(groundTiles) do
- local charBottom = character.y + sprite_height
- local charTop = character.y
- local tileBottom = tile.y + tile.height
- local tileTop = tile.y
-
- local verticalOverlapAmount = math.min(charBottom, tileBottom) - math.max(charTop, tileTop)
- local verticalOverlap = verticalOverlapAmount > 12
-
- -- New: Check if tile is within a certain horizontal range before collision test
- local horizontalDistance
- if direction == "left" then
- horizontalDistance = character.x - (tile.x + tile.width)
- if horizontalDistance > 15 then -- Only check if tile is within 15 pixels to the left
- goto continue
- end
- elseif direction == "right" then
- horizontalDistance = tile.x - (character.x + sprite_width)
- if horizontalDistance > 15 then -- Only check if tile is within 15 pixels to the right
- goto continue
- end
- end
+function AABBOverlap(a, b)
+ return a.x < b.x + b.width and
+ a.x + a.width > b.x and
+ a.y < b.y + b.height and
+ a.y + a.height > b.y
+end
- if direction == "left" then
- local nextX = character.x - character.speed
- local willCollide = nextX < tile.x + tile.width and character.x >= tile.x + tile.width
+function IsTouchingWall(character, direction, exclude_special)
+ local velocity = character.x_velocity
- if willCollide and verticalOverlap then
- character.x = tile.x + tile.width
- return true
- end
- elseif direction == "right" then
- local nextX = character.x + sprite_width + character.speed
- local willCollide = nextX > tile.x and character.x + sprite_width <= tile.x
+ -- Clamp how far ahead we look
+ local max_check_distance = 1.0 -- only check 1 pixel ahead
+ if velocity > max_check_distance then velocity = max_check_distance end
+ if velocity < -max_check_distance then velocity = -max_check_distance end
+
+ -- Prevent missing collisions on tiny glide
+ if math.abs(velocity) < 0.01 then
+ velocity = (direction == "right") and 0.01 or -0.01
+ end
+
+ local futureX = character.x + velocity
+
+ local charBox = {
+ x = futureX,
+ y = character.y,
+ width = sprite_width,
+ height = sprite_height
+ }
- if willCollide and verticalOverlap then
+ for _, tile in ipairs(groundTiles) do
+ if tile.special and exclude_special then goto continue end
+
+ local tileBox = {
+ x = tile.x,
+ y = tile.y,
+ width = tile.width,
+ height = tile.height
+ }
+
+ if AABBOverlap(charBox, tileBox) then
+ -- Resolve overlap
+ if direction == "left" then
+ character.x = tile.x + tile.width
+ elseif direction == "right" then
character.x = tile.x - sprite_width
- return true
end
+ character.x_velocity = 0
+ return true
end
+
::continue::
end
+
return false
end
function HandleP1Input()
if player1Character.isDead then return end
- if Input.isKeyPressedOnce("W") and player1Character.can_jump then
+ if Input.isKeyDown("W") and player1Character.can_jump then
player1Character.y_velocity = player1Character.jump_strength * -1.0
player1Character.can_jump = false
end
if Input.isKeyDown("D") then
- if not IsTouchingWall(player1Character, "right") then
+ if not IsTouchingWall(player1Character, "right", false) then
player1Character.x_velocity = player1Character.speed
player1Character.facing = "right"
else
player1Character.x_velocity = 0
+ player1Character.x = math.floor(player1Character.x)
end
end
if Input.isKeyDown("A") then
- if not IsTouchingWall(player1Character, "left") then
+ if not IsTouchingWall(player1Character, "left", false) then
player1Character.x_velocity = -player1Character.speed
player1Character.facing = "left"
else
player1Character.x_velocity = 0
+ player1Character.x = math.floor(player1Character.x)
end
end
@@ -156,25 +222,27 @@ end
function HandleP2Input()
if player2Character.isDead then return end
- if Input.isKeyPressedOnce("UP") and player2Character.can_jump then
+ if Input.isKeyDown("UP") and player2Character.can_jump then
player2Character.y_velocity = player2Character.jump_strength * -1.0
player2Character.can_jump = false
end
if Input.isKeyDown("RIGHT") then
- if not IsTouchingWall(player2Character, "right") then
+ if not IsTouchingWall(player2Character, "right", false) then
player2Character.x_velocity = player2Character.speed
player2Character.facing = "right"
else
player2Character.x_velocity = 0
+ player2Character.x = math.floor(player2Character.x)
end
end
if Input.isKeyDown("LEFT") then
- if not IsTouchingWall(player2Character, "left") then
+ if not IsTouchingWall(player2Character, "left", false) then
player2Character.x_velocity = -player2Character.speed
player2Character.facing = "left"
else
player2Character.x_velocity = 0
+ player2Character.x = math.floor(player2Character.x)
end
end
@@ -255,22 +323,44 @@ function KillPlayer(character)
isKO = true
Timer.after(2, function()
- character.lives = character.lives - 1
+ remaining_rounds = remaining_rounds - 1
+ current_round = current_round + 1
character.knockback_counter = 0
character.combo_chain = 0
- if character.lives > 0 then
- Respawn(character)
- character.isDead = false
+
+ if character == player1Character then
+ player2Character.wins = player2Character.wins + 1
+ else
+ player1Character.wins = player1Character.wins + 1
+ end
+
+ if remaining_rounds > 0 then
+ Setup()
else
-- Handle game over here
end
- gamePaused = false
isKO = false
+ if remaining_rounds > 0 then
+ isOverlay = true
+ Timer.after(2, function ()
+ isOverlay = false
+ isNewRound = true
+ Timer.after(2, function ()
+ isNewRound = false
+ isFight = true
+ Timer.after(2, function ()
+ gamePaused = false
+ isFight = false
+ end)
+ end)
+ end)
+ end
end)
end
function RegisterHit(attacker, target, damage)
target.knockback_counter = target.knockback_counter + damage
+ target.combo_chain = 0
attacker.combo_chain = attacker.combo_chain + 1
if attacker.combo_chain >= 4 then
@@ -332,6 +422,10 @@ end
function ApplyPhysics(character)
if character.isDead then return end
+
+ local last_x = character.x
+ local last_y = character.y
+
character.y_velocity = character.y_velocity + gravity * deltaTime
character.y = character.y + character.y_velocity * deltaTime
character.x = character.x + character.x_velocity * deltaTime
@@ -348,6 +442,15 @@ function ApplyPhysics(character)
IsHittingCeiling(character)
end
+ if IsTouchingWall(character, "left", true) then
+ character.x = last_x
+ character.x_velocity = 0
+ end
+ if IsTouchingWall(character, "right", true) then
+ character.x = last_x
+ character.x_velocity = 0
+ end
+
if not IsOnGround(character) then
character.can_jump = false
end
@@ -365,8 +468,12 @@ function ApplyPhysics(character)
end
end
-function DrawKOGraphic()
+function DrawOverlay()
queueRectForRender(0, 0, 1280, 720, 0, 0, 0, 150)
+end
+
+function DrawKOGraphic()
+ DrawOverlay()
local fontFile = "assets/fonts/OpenSans-Bold.ttf"
local fontSize = 96
@@ -375,10 +482,38 @@ function DrawKOGraphic()
local x = (1280 - textWidth) / 2
local y = 720 / 2 - fontSize / 2
- queueTextForRender(text, fontFile, x, y, fontSize, 255, 0, 0, 255)
queueTextForRender(text, fontFile, x + 5, y + 5, fontSize, 255, 255, 0, 255)
+ queueTextForRender(text, fontFile, x, y, fontSize, 255, 0, 0, 255)
+end
+
+function DrawNewRoundGraphic()
+ DrawOverlay()
+
+ local fontFile = "assets/fonts/OpenSans-Bold.ttf"
+ local fontSize = 96
+ local text = "Round " .. current_round
+ if remaining_rounds == 1 then
+ text = "Final Round"
+ end
+ local textWidth = getTextWidth(fontFile, fontSize, text)
+ local x = (1280 - textWidth) // 2
+ local y = 720 // 2 - fontSize // 2
+
+ queueTextForRender(text, fontFile, x, y, fontSize, 255, 255, 255, 255)
end
+function DrawFightGraphic()
+ DrawOverlay()
+
+ local fontFile = "assets/fonts/OpenSans-Bold.ttf"
+ local fontSize = 96
+ local text = "FIGHT!"
+ local textWidth = getTextWidth(fontFile, fontSize, text)
+ local x = (1280 - textWidth) // 2
+ local y = 720 // 2 - fontSize // 2
+
+ queueTextForRender(text, fontFile, x, y, fontSize, 255, 255, 0, 255)
+end
function Update()
local maxDelta = 0.05 -- max 50 ms per frame
@@ -404,4 +539,13 @@ function Update()
if isKO then
DrawKOGraphic()
end
+ if isOverlay then
+ DrawOverlay()
+ end
+ if isNewRound then
+ DrawNewRoundGraphic()
+ end
+ if isFight then
+ DrawFightGraphic()
+ end
end
diff --git a/assets/scripts/mainMenu.lua b/assets/scripts/mainMenu.lua
index ca290c6..f345f76 100644
--- a/assets/scripts/mainMenu.lua
+++ b/assets/scripts/mainMenu.lua
@@ -1,4 +1,4 @@
----@diagnostic disable: undefined-global
+---@diagnostic disable: undefined-global, lowercase-global
movementSpeed = 3;
bannerTextureWidth = 509;
buttonHeight = 50;