-- 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