oma-command/game/world.lua
nosignal 64ce7f0fcb Initial public release
OMA-COMMAND — Missile Command arcade clone in Love2D with Omarchy theme integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 18:32:07 +01:00

97 lines
2.6 KiB
Lua

local World = {
GAME_W = 256,
GAME_H = 231,
visibleH = 231, -- actual visible height in game units (adapts to screen)
scale = 1,
offsetX = 0,
offsetY = 0,
state = "title",
wave = 1,
score = 0,
highScore = 0,
gameOverTimer = 0,
waveEndTimer = 0,
GROUND_Y = 213,
screenW = 0,
screenH = 0,
bonusCities = 0,
nextBonusAt = 10000,
}
function World.resize(w, h)
if not w or not h then
w, h = love.graphics.getDimensions()
end
World.screenW = w
World.screenH = h
-- Scale to fill width, let height adapt
World.scale = w / World.GAME_W
World.visibleH = h / World.scale
World.offsetX = 0
-- Anchor the bottom of the game (ground) to the bottom of the screen
-- Ground is at GROUND_Y, bottom of game area is GAME_H
World.offsetY = h - (World.GAME_H * World.scale)
end
function World.ensureScale()
local w, h = love.graphics.getDimensions()
if w ~= World.screenW or h ~= World.screenH then
World.resize(w, h)
local Fonts = require("rendering.fonts")
Fonts.init(World.scale)
end
end
function World.toGame(sx, sy)
local gx = (sx - World.offsetX) / World.scale
local gy = (sy - World.offsetY) / World.scale
gx = math.max(0, math.min(World.GAME_W, gx))
gy = math.max(0, math.min(World.GAME_H, gy))
return gx, gy
end
function World.toScreen(gx, gy)
return gx * World.scale + World.offsetX, gy * World.scale + World.offsetY
end
-- Top of the visible area in game coordinates (can be negative on widescreen)
function World.visibleTop()
return World.GAME_H - World.visibleH
end
function World.addScore(points)
local Waves = require("data.waves")
local config = Waves.get(World.wave)
local earned = points * config.multiplier
local oldScore = World.score
World.score = World.score + earned
-- Check for bonus city threshold crossing
while World.score >= World.nextBonusAt do
World.bonusCities = World.bonusCities + 1
World.nextBonusAt = World.nextBonusAt + 10000
end
-- Track high score
if World.score > World.highScore then
World.highScore = World.score
end
end
function World.addScoreRaw(points)
-- Add points without multiplier (used by tally screen)
local oldScore = World.score
World.score = World.score + points
while World.score >= World.nextBonusAt do
World.bonusCities = World.bonusCities + 1
World.nextBonusAt = World.nextBonusAt + 10000
end
if World.score > World.highScore then
World.highScore = World.score
end
end
return World