Files
kimi-game/main.lua
T
2026-07-21 16:28:15 +02:00

168 lines
5.1 KiB
Lua

-- Point d'entrée LÖVE : menu principal, boucle, pas de simulation fixe.
-- `love . --tests` exécute la suite de tests automatisés puis quitte.
for _, a in ipairs(arg or {}) do
if a == "--tests" then
require("tests.runner_love")
return
end
end
local Game = require("src.game")
local UI = require("src.ui")
local Save = require("src.save")
local state = "menu" -- menu | game
local game, ui
local menuSel = 1
local seedInput = ""
local enteringSeed = false
local menuMsg = nil
local TICK = 1 / 30 -- pas de simulation fixe
local acc = 0
local function newGame(seed)
game = Game.new(seed)
ui = UI.new(game)
state = "game"
end
function love.load()
love.graphics.setFont(love.graphics.newFont(13))
math.randomseed(os.time())
end
function love.update(dt)
if state ~= "game" then return end
-- simulation à pas fixe, indépendante du framerate
acc = acc + dt
local steps = 0
while acc >= TICK and steps < 8 do
game:update(TICK)
acc = acc - TICK
steps = steps + 1
end
if steps == 8 then acc = 0 end -- évite la spirale de la mort
ui:update(dt)
end
function love.draw()
if state == "menu" then
drawMenu()
else
ui:draw()
end
end
local menuButtons = {}
local function menuButton(id, x, y, w, h, label, sub)
love.graphics.setColor(0.14, 0.16, 0.22)
love.graphics.rectangle("fill", x, y, w, h, 5, 5)
love.graphics.setColor(1, 1, 1)
love.graphics.print(label, x + 14, y + 8)
if sub then
love.graphics.setColor(0.65, 0.65, 0.7)
love.graphics.print(sub, x + 14, y + 24, 0, 0.85)
end
menuButtons[#menuButtons + 1] = { id = id, x = x, y = y, w = w, h = h }
end
function drawMenu()
menuButtons = {}
local w, h = love.graphics.getDimensions()
love.graphics.setBackgroundColor(0.03, 0.04, 0.06)
love.graphics.setColor(0.2, 0.95, 0.95)
love.graphics.print("OUTPOST REMOTE", w/2 - 150, h/2 - 170, 0, 2.2)
love.graphics.setColor(0.7, 0.7, 0.75)
love.graphics.print("Planète distante. Communications impossibles. Un robot, un programme par jour.",
w/2 - 300, h/2 - 110)
local bx, bw = w/2 - 180, 360
menuButton("new", bx, h/2 - 60, bw, 42, "Nouvelle partie", "graine aléatoire")
menuButton("seed", bx, h/2 - 10, bw, 42,
enteringSeed and ("Graine : " .. seedInput .. "_") or "Nouvelle partie avec graine",
enteringSeed and "tapez des chiffres, Entrée pour valider" or "cliquer pour saisir une graine")
if Save.exists() then
menuButton("load", bx, h/2 + 40, bw, 42, "Charger la partie", Save.FILE)
end
if menuMsg then
love.graphics.setColor(1, 0.5, 0.4)
love.graphics.print(menuMsg, bx, h/2 + 95)
end
love.graphics.setColor(0.5, 0.5, 0.55)
love.graphics.print("En jeu : F1 pour l'aide, F5 sauvegarde rapide, Échap+F10 retour menu",
bx, h - 60)
end
function love.mousepressed(mx, my, button)
if state == "menu" then
for _, b in ipairs(menuButtons) do
if mx >= b.x and mx <= b.x + b.w and my >= b.y and my <= b.y + b.h then
if b.id == "new" then
newGame(math.random(1, 999999))
elseif b.id == "seed" then
enteringSeed = true
seedInput = ""
elseif b.id == "load" then
local g, err = Save.read(Game)
if g then game, ui = g, UI.new(g); state = "game"
else menuMsg = "Erreur de chargement : " .. tostring(err) end
end
return
end
end
enteringSeed = false
return
end
-- en jeu : priorité au panneau
local w = love.graphics.getWidth()
if mx >= w - ui.panelW then
if ui:clickPanel(mx, my) then return end
end
ui:mousepressed(mx, my, button)
end
function love.mousereleased(mx, my, button)
if state == "game" then ui:mousereleased(mx, my, button) end
end
function love.mousemoved(mx, my, dx, dy)
if state == "game" then ui:mousemoved(mx, my, dx, dy) end
end
function love.wheelmoved(dx, dy)
if state == "game" then ui:wheelmoved(dx, dy) end
end
function love.textinput(t)
if state == "menu" and enteringSeed and t:match("^%d$") and #seedInput < 9 then
seedInput = seedInput .. t
end
end
function love.keypressed(key)
if state == "menu" then
if enteringSeed then
if key == "return" or key == "kpenter" then
local s = tonumber(seedInput)
if s then newGame(s) else menuMsg = "Graine invalide." end
enteringSeed = false
elseif key == "backspace" then
seedInput = seedInput:sub(1, -2)
elseif key == "escape" then
enteringSeed = false
end
end
return
end
if key == "f5" then
local ok, err = Save.write(game)
ui:flash(ok and "Partie sauvegardée." or ("Échec sauvegarde : " .. tostring(err)))
return
elseif key == "f10" then
state = "menu"
return
end
ui:keypressed(key)
end