Files
basic1/games/lua_examples/lunar_lander.lua
2026-02-13 15:31:21 -05:00

174 lines
6.1 KiB
Lua

-- NAME: Lunar Lander
-- DESC: Land safely with limited fuel
-- Game states
local STATE_MENU = 0
local STATE_PLAYING = 1
local STATE_LANDED = 2
local STATE_CRASHED = 3
-- Game constants
local GRAVITY = 0.15
local THRUST_POWER = 0.3
local MAX_FUEL = 100
local SAFE_LANDING_SPEED = 1.5
function init()
game.vars.state = STATE_MENU
game.vars.score = 0
-- Lander
game.vars.lander_x = game.width() / 2
game.vars.lander_y = 10
game.vars.lander_vel_y = 0
game.vars.fuel = MAX_FUEL
game.vars.thrusting = false
-- Terrain
game.vars.landing_zone_x = game.width() / 2 - 20
game.vars.landing_zone_w = 40
game.vars.terrain_y = game.height() - 15
-- Enable continuous updates
game.set_frame_updates(true)
print("Lunar Lander initialized")
end
function update(event)
local state = game.vars.state
if state == STATE_MENU then
if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
reset_game()
game.vars.state = STATE_PLAYING
return true
end
elseif state == STATE_PLAYING then
-- Handle thrust input
if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.TOUCH_MOVE then
if game.vars.fuel > 0 then
game.vars.thrusting = true
game.vars.fuel = game.vars.fuel - 1
else
game.vars.thrusting = false
end
else
game.vars.thrusting = false
end
-- Update physics on frame tick
if event.type == INPUT.FRAME_TICK then
update_lander()
check_landing()
return true
end
elseif state == STATE_LANDED or state == STATE_CRASHED then
if event.type == INPUT.TOUCH_DOWN or event.type == INPUT.BUTTON_0 or event.type == INPUT.BUTTON_1 then
game.vars.state = STATE_MENU
return true
end
end
return false
end
function draw()
renderer.clear(false)
local state = game.vars.state
if state == STATE_MENU then
renderer.text_scaled(game.width() / 2 - 50, game.height() / 2 - 30, "LUNAR LANDER", true, 2)
renderer.text_scaled(game.width() / 2 - 70, game.height() / 2 - 5, "Land in the zone safely", true, 2)
renderer.text_scaled(game.width() / 2 - 50, game.height() / 2 + 20, "Tap to Start", true, 2)
elseif state == STATE_PLAYING or state == STATE_LANDED or state == STATE_CRASHED then
-- Draw terrain
renderer.rect(0, game.vars.terrain_y, game.width(), game.height() - game.vars.terrain_y, true, true)
-- Draw landing zone (outline)
renderer.rect(game.vars.landing_zone_x, game.vars.terrain_y - 2, game.vars.landing_zone_w, 2, true, true)
-- Draw lander (triangle)
local lander_w = 8
local lander_h = 6
renderer.line(game.vars.lander_x - lander_w / 2, game.vars.lander_y + lander_h,
game.vars.lander_x, game.vars.lander_y, true, 1)
renderer.line(game.vars.lander_x, game.vars.lander_y,
game.vars.lander_x + lander_w / 2, game.vars.lander_y + lander_h, true, 1)
renderer.line(game.vars.lander_x - lander_w / 2, game.vars.lander_y + lander_h,
game.vars.lander_x + lander_w / 2, game.vars.lander_y + lander_h, true, 1)
-- Draw thrust flame
if game.vars.thrusting then
renderer.line(game.vars.lander_x - 2, game.vars.lander_y + lander_h,
game.vars.lander_x - 1, game.vars.lander_y + lander_h + 3, true, 1)
renderer.line(game.vars.lander_x + 2, game.vars.lander_y + lander_h,
game.vars.lander_x + 1, game.vars.lander_y + lander_h + 3, true, 1)
end
-- Draw stats
renderer.text_scaled(5, 5, "Fuel: " .. tostring(math.floor(game.vars.fuel)), true, 2)
renderer.text_scaled(5, 15, "Speed: " .. tostring(math.floor(game.vars.lander_vel_y * 10)), true, 2)
if state == STATE_LANDED then
renderer.text_scaled(game.width() / 2 - 40, game.height() / 2 - 20, "LANDED!", true, 2)
renderer.text_scaled(game.width() / 2 - 30, game.height() / 2, "Score: " .. tostring(game.vars.score), true, 2)
renderer.text_scaled(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Menu", true, 2)
end
if state == STATE_CRASHED then
renderer.text_scaled(game.width() / 2 - 40, game.height() / 2 - 20, "CRASHED!", true, 2)
renderer.text_scaled(game.width() / 2 - 60, game.height() / 2 + 20, "Tap to Menu", true, 2)
end
end
end
function update_lander()
-- Apply gravity
game.vars.lander_vel_y = game.vars.lander_vel_y + GRAVITY
-- Apply thrust
if game.vars.thrusting then
game.vars.lander_vel_y = game.vars.lander_vel_y - THRUST_POWER
end
-- Update position
game.vars.lander_y = game.vars.lander_y + game.vars.lander_vel_y
end
function check_landing()
-- Check if lander reached terrain
if game.vars.lander_y + 6 >= game.vars.terrain_y then
local lander_left = game.vars.lander_x - 4
local lander_right = game.vars.lander_x + 4
local zone_left = game.vars.landing_zone_x
local zone_right = game.vars.landing_zone_x + game.vars.landing_zone_w
-- Check if in landing zone
if lander_left >= zone_left and lander_right <= zone_right then
-- Check landing speed
if game.vars.lander_vel_y <= SAFE_LANDING_SPEED then
game.vars.state = STATE_LANDED
game.vars.score = 100 + math.floor(game.vars.fuel)
else
game.vars.state = STATE_CRASHED
end
else
game.vars.state = STATE_CRASHED
end
end
end
function reset_game()
game.vars.lander_x = game.width() / 2
game.vars.lander_y = 10
game.vars.lander_vel_y = 0
game.vars.fuel = MAX_FUEL
game.vars.thrusting = false
game.vars.score = 0
end