174 lines
6.1 KiB
Lua
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
|