OMA-LANDER: fix flash, terrain overshoot, thrust particles, cleanups
- main.lua: flash logic was always true; now flashes only on crash, always on when landed. Remove empty fuel-depleted branch. Rotate thrust-particle spawn point by lander angle. - particles.lua: jet velocity had wrong vy sign, shooting particles upward; now emits along local (0,1) rotated by the lander angle. - terrain.lua: jagged step could overshoot the pad approach zone and produce an out-of-order point (zig-zag line, bad getHeightAt). Clamp the step to the approach boundary. Move Camera/World requires to module top instead of re-requiring inside the draw loop. - camera.lua: drop unused midY local. - fonts.lua/world.lua/main.lua: drop unused scale parameter on Fonts.init. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
515f78a3e7
commit
74c15e555a
6 changed files with 23 additions and 22 deletions
|
|
@ -18,10 +18,7 @@ function Camera.update(lander, terrain, dt)
|
|||
local groundY = terrain.getHeightAt(lander.x)
|
||||
local altitude = groundY - lander.y
|
||||
|
||||
-- Camera Y: always frame BOTH the lander and the terrain
|
||||
-- Centre the view between the lander and the ground, biased toward showing terrain
|
||||
local midY = (lander.y + groundY) / 2
|
||||
-- Bias: keep terrain in the lower third even at high altitude
|
||||
-- Camera Y: keep terrain in the lower portion of the viewport even at high altitude
|
||||
local targetY = lander.y + altitude * 0.45
|
||||
|
||||
Camera.y = Camera.y + (targetY - Camera.y) * math.min(1, dt * 3)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,14 @@ local Particles = {}
|
|||
local particles = {}
|
||||
|
||||
function Particles.spawnThrust(x, y, angle)
|
||||
-- Jet direction is local (0, 1) rotated by jetAngle (same convention as lander transformPoint)
|
||||
local spread = 0.5
|
||||
local speed = 30 + math.random() * 40
|
||||
local dir = angle + math.pi + (math.random() - 0.5) * spread
|
||||
local jetAngle = angle + (math.random() - 0.5) * spread
|
||||
table.insert(particles, {
|
||||
x = x, y = y,
|
||||
vx = math.sin(dir) * speed,
|
||||
vy = math.cos(dir) * speed,
|
||||
vx = -math.sin(jetAngle) * speed,
|
||||
vy = math.cos(jetAngle) * speed,
|
||||
life = 0.2 + math.random() * 0.2,
|
||||
maxLife = 0.4,
|
||||
ptype = "dot",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
local World = require("game.world")
|
||||
local Palette = require("rendering.palette")
|
||||
local Camera = require("game.camera")
|
||||
|
||||
local Terrain = {}
|
||||
|
||||
|
|
@ -61,6 +62,13 @@ function Terrain.generate()
|
|||
else
|
||||
-- Normal jagged terrain
|
||||
local step = 25 + math.random() * 35
|
||||
-- Don't overshoot the next pad's approach zone — would cause out-of-order points
|
||||
if padIdx <= #pads then
|
||||
local approach = pads[padIdx].x1 - 40
|
||||
if x < approach and x + step > approach then
|
||||
step = approach - x
|
||||
end
|
||||
end
|
||||
x = x + step
|
||||
y = y + (math.random() - 0.5) * 100
|
||||
y = math.max(baseline - 250, math.min(baseline + 250, y))
|
||||
|
|
@ -133,8 +141,6 @@ function Terrain.draw(visMinX, visMaxX)
|
|||
-- Multiplier label — constant screen size regardless of zoom
|
||||
love.graphics.setColor(p.pad[1], p.pad[2], p.pad[3], 0.8)
|
||||
local cx = (pad.x1 + pad.x2) / 2
|
||||
local Camera = require("game.camera")
|
||||
local World = require("game.world")
|
||||
local invZoom = 1 / (World.baseScale * Camera.getZoom())
|
||||
love.graphics.push()
|
||||
love.graphics.translate(cx, pad.y + 15 * invZoom)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ function World.ensureScale()
|
|||
if w ~= World.screenW or h ~= World.screenH then
|
||||
World.resize(w, h)
|
||||
local Fonts = require("rendering.fonts")
|
||||
Fonts.init(1)
|
||||
Fonts.init()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
19
main.lua
19
main.lua
|
|
@ -126,7 +126,7 @@ function love.load()
|
|||
love.graphics.setLineStyle("smooth")
|
||||
Palette.loadFromSystem()
|
||||
World.resize(love.graphics.getDimensions())
|
||||
Fonts.init(1)
|
||||
Fonts.init()
|
||||
HighScores.init()
|
||||
Sounds.init()
|
||||
Stars.init()
|
||||
|
|
@ -136,7 +136,7 @@ end
|
|||
|
||||
function love.resize(w, h)
|
||||
World.resize(w, h)
|
||||
Fonts.init(1)
|
||||
Fonts.init()
|
||||
end
|
||||
|
||||
function love.update(dt)
|
||||
|
|
@ -160,8 +160,10 @@ function love.update(dt)
|
|||
thrustSoundTimer = 0
|
||||
Sounds.play("thrust")
|
||||
end
|
||||
-- Thrust particles
|
||||
local fx, fy = l.x, l.y + 8
|
||||
-- Thrust particles — spawn at nozzle transformed by lander angle
|
||||
local sa, ca = math.sin(l.angle), math.cos(l.angle)
|
||||
local fx = l.x - sa * 8
|
||||
local fy = l.y + ca * 8
|
||||
Particles.spawnThrust(fx, fy, l.angle)
|
||||
else
|
||||
thrustSoundTimer = 0.15
|
||||
|
|
@ -179,11 +181,6 @@ function love.update(dt)
|
|||
-- Check terrain collision
|
||||
checkLanding()
|
||||
|
||||
-- Game over if fuel depleted and landed/still
|
||||
if World.fuel <= 0 and not l.thrusting then
|
||||
-- Let them coast until they crash or land
|
||||
end
|
||||
|
||||
elseif World.state == "landed" or World.state == "crashed" then
|
||||
World.stateTimer = World.stateTimer + dt
|
||||
Particles.update(dt)
|
||||
|
|
@ -249,8 +246,8 @@ function love.draw()
|
|||
-- Landing/crash result text
|
||||
if World.state == "landed" or World.state == "crashed" then
|
||||
love.graphics.setFont(Fonts.medium)
|
||||
local flash = World.state == "crashed" and
|
||||
(math.floor(World.stateTimer * 4) % 2 == 0) or true
|
||||
local flash = World.state == "landed" or
|
||||
(math.floor(World.stateTimer * 4) % 2 == 0)
|
||||
|
||||
if flash then
|
||||
if World.state == "crashed" then
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function Fonts.detectSystemFont()
|
|||
return nil
|
||||
end
|
||||
|
||||
function Fonts.init(scale)
|
||||
function Fonts.init()
|
||||
local h = love.graphics.getHeight()
|
||||
if h == Fonts.currentH then return end
|
||||
Fonts.currentH = h
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue