prep for stage 3
This commit is contained in:
+143
-51
@@ -1,6 +1,60 @@
|
||||
local screen_width, screen_height = love.graphics.getDimensions()
|
||||
math.randomseed(os.time())
|
||||
|
||||
-- returns selected_object, distance_squared_to_object (if object_list is empty, returns nil, math.huge)
|
||||
local function get_closest_object(object_list, current_object)
|
||||
local selected_object, distance_squared_to_object = nil, math.huge
|
||||
for i = 1, #object_list do
|
||||
local function compare_object()
|
||||
local comparison_object = object_list[i]
|
||||
if comparison_object == current_object then
|
||||
return
|
||||
end
|
||||
local comparison_distance_squared = (current_object.position_x - comparison_object.position_x)^2 + (current_object.position_y - comparison_object.position_y)^2
|
||||
if comparison_distance_squared < distance_squared_to_object then
|
||||
selected_object = comparison_object
|
||||
distance_squared_to_object = comparison_distance_squared
|
||||
end
|
||||
end
|
||||
compare_object()
|
||||
end
|
||||
|
||||
return selected_object, distance_squared_to_object
|
||||
end
|
||||
|
||||
-- returns cargo_amount (actual amount transferred)
|
||||
local function transfer_cargo(source_object, destination_object, cargo_type, cargo_amount)
|
||||
if not source_object.cargo_contents[cargo_type] then
|
||||
return 0
|
||||
end
|
||||
if not destination_object.cargo_contents[cargo_type] then
|
||||
destination_object.cargo_contents[cargo_type] = 0
|
||||
end
|
||||
|
||||
cargo_amount = math.min(cargo_amount, source_object.cargo_contents[cargo_type])
|
||||
destination_object.cargo_contents[cargo_type] = destination_object.cargo_contents[cargo_type] + cargo_amount
|
||||
destination_object.cargo_free_space = destination_object.cargo_free_space - cargo_amount
|
||||
source_object.cargo_contents[cargo_type] = source_object.cargo_contents[cargo_type] - cargo_amount
|
||||
source_object.cargo_free_space = source_object.cargo_free_space + cargo_amount
|
||||
|
||||
if source_object.cargo_contents[cargo_type] <= 0 then
|
||||
source_object.cargo_contents[cargo_type] = nil
|
||||
end
|
||||
|
||||
return cargo_amount
|
||||
end
|
||||
|
||||
-- The resources collected by the player can be spent on something,
|
||||
-- like improving the ship. Speed, capacity, collection speed, etc.
|
||||
-- TODO future upgrade: range upgrade ?
|
||||
-- right now: iron -> caoacity, copper -> acceleration
|
||||
|
||||
local cargo_types = { "iron ore", "copper ore", }
|
||||
|
||||
-- TODO review my previous orbits code to add extremely slow background orbits to this
|
||||
-- planets/stars/stations always have fixed orbits; ships have a fixed orbital acceleration but have their own additional
|
||||
-- the "zero relative velocity" key will be a burn whatever amount of fuel/acceleration necessary to match local acceleration
|
||||
-- which.. since the currently stored velocity is a COMPLETELY SEPARATE SYSTEM - is literally just zeroing velocity which makes it even simpler to execute
|
||||
local player_ship = {
|
||||
position_x = screen_width / 2,
|
||||
position_y = screen_height / 2,
|
||||
@@ -10,35 +64,53 @@ local player_ship = {
|
||||
|
||||
radar_size = 10,
|
||||
|
||||
cargo_max_space = 100,
|
||||
cargo_free_space = 100,
|
||||
cargo_contents = {},
|
||||
cargo_fill_speed = 10,
|
||||
|
||||
-- TODO fuel capacity and use (idle and while acceleration)
|
||||
-- TODO cargo / mass affects acceleration
|
||||
}
|
||||
|
||||
local resource_points = {} -- NOTE they're "planets" but I intend for them to be multiple things tbh
|
||||
for i = 1, 3 do
|
||||
local resource_point = {
|
||||
position_x = math.random() * screen_width,
|
||||
position_y = math.random() * screen_height,
|
||||
radar_size = 10,
|
||||
local function spawn_3_points()
|
||||
for i = 1, 3 do
|
||||
local function make_resource_point()
|
||||
local current_point = {
|
||||
position_x = math.random() * screen_width,
|
||||
position_y = math.random() * screen_height,
|
||||
radar_size = 10,
|
||||
|
||||
cargo_free_space = 100000,
|
||||
cargo_contents = {},
|
||||
}
|
||||
cargo_max_space = 100000,
|
||||
cargo_free_space = 100000,
|
||||
cargo_contents = {},
|
||||
}
|
||||
|
||||
local cargo_types = { "iron ore", "copper ore", } -- TODO use a proper enumeration
|
||||
local selected_type = cargo_types[math.random(2)]
|
||||
local cargo_amount = math.random() * 10000
|
||||
-- TODO utility function to handle transferring cargo
|
||||
resource_point.cargo_contents[selected_type] = cargo_amount
|
||||
resource_point.cargo_free_space = resource_point.cargo_free_space - cargo_amount
|
||||
-- NOTE can select literally anything
|
||||
local selected_type = cargo_types[math.random(#cargo_types)]
|
||||
local cargo_amount = math.random() * 10000
|
||||
transfer_cargo({ cargo_contents = { [selected_type] = cargo_amount, }, cargo_free_space = 0, }, current_point, selected_type, cargo_amount)
|
||||
|
||||
-- TODO make sure it is not placed on top of another one or too close
|
||||
table.insert(resource_points, resource_point)
|
||||
local closest_object, distance_squared_to_object = get_closest_object(resource_points, current_point)
|
||||
if closest_object and distance_squared_to_object <= (closest_object.radar_size^2 + current_point.radar_size^2) * 1.5 then
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(resource_points, current_point)
|
||||
return true
|
||||
end
|
||||
|
||||
if not make_resource_point() then
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
spawn_3_points()
|
||||
|
||||
local last_message = ""
|
||||
function love.update(dt)
|
||||
-- NOTE this control scheme makes diagonal travel faster than horizontal/vertical
|
||||
if love.keyboard.isDown("w") then
|
||||
player_ship.velocity_y = player_ship.velocity_y - player_ship.acceleration * dt
|
||||
end
|
||||
@@ -52,52 +124,59 @@ function love.update(dt)
|
||||
player_ship.velocity_x = player_ship.velocity_x + player_ship.acceleration * dt
|
||||
end
|
||||
|
||||
-- NOTE this zeros out diagonal velocities faster than horizontal/vertical
|
||||
if love.keyboard.isDown("x") then
|
||||
if player_ship.velocity_x > 0 then
|
||||
player_ship.velocity_x = math.max(0, player_ship.velocity_x - player_ship.acceleration * dt)
|
||||
elseif player_ship.velocity_x < 0 then
|
||||
player_ship.velocity_x = math.min(0, player_ship.velocity_x + player_ship.acceleration * dt)
|
||||
end
|
||||
|
||||
if player_ship.velocity_y > 0 then
|
||||
player_ship.velocity_y = math.max(0, player_ship.velocity_y - player_ship.acceleration * dt)
|
||||
elseif player_ship.velocity_y < 0 then
|
||||
player_ship.velocity_y = math.min(0, player_ship.velocity_y + player_ship.acceleration * dt)
|
||||
end
|
||||
end
|
||||
|
||||
player_ship.position_x = player_ship.position_x + player_ship.velocity_x * dt
|
||||
player_ship.position_y = player_ship.position_y + player_ship.velocity_y * dt
|
||||
|
||||
-- TODO there needs to be a way to zero out relative velocity? (I don't think so yet)
|
||||
|
||||
if love.keyboard.isDown("space") then
|
||||
-- TODO this whole thing should be a function, especially cause it uses return shortcutting
|
||||
local selected_point, distance_to_point_squared = nil, math.huge
|
||||
for i = 1, #resource_points do
|
||||
local resource_point = resource_points[i]
|
||||
local distance_squared = (player_ship.position_x - resource_point.position_x)^2 + (player_ship.position_y - resource_point.position_y)^2
|
||||
if distance_squared < distance_to_point_squared then
|
||||
selected_point = resource_point
|
||||
distance_to_point_squared = distance_squared
|
||||
local function collect_resource()
|
||||
local closest_object, distance_squared_to_object = get_closest_object(resource_points, player_ship)
|
||||
-- TODO ideally, there should be an indicator that you're close enough instead of relying on messages (to be fair, the radius is the indicator)
|
||||
if distance_squared_to_object > closest_object.radar_size^2 then
|
||||
last_message = "Too far to pick up cargo."
|
||||
return
|
||||
end
|
||||
if player_ship.cargo_free_space <= 0 then
|
||||
last_message = "No cargo space left."
|
||||
return
|
||||
end
|
||||
-- TODO allow selecting cargo type
|
||||
local cargo_type = next(closest_object.cargo_contents)
|
||||
if not cargo_type then
|
||||
last_message = "There is nothing here."
|
||||
return
|
||||
end
|
||||
local cargo_amount = math.min(player_ship.cargo_fill_speed * dt, closest_object.cargo_contents[cargo_type])
|
||||
if cargo_amount <= 0 then
|
||||
last_message = "There is no cargo to pick up."
|
||||
return
|
||||
end
|
||||
|
||||
cargo_amount = transfer_cargo(closest_object, player_ship, cargo_type, cargo_amount)
|
||||
last_message = "Transfered " .. math.floor(cargo_amount * 100) / 100 .. " " .. cargo_type .. "."
|
||||
end
|
||||
-- TODO ideally, there should be an indicator that you're close enough instead of relying on messages (to be fair, the radius is the indicator)
|
||||
if distance_to_point_squared > selected_point.radar_size^2 then
|
||||
last_message = "Too far to pick up cargo."
|
||||
return
|
||||
end
|
||||
-- TODO there should be a persistent indicator of cargo capacity and how full it is
|
||||
if player_ship.cargo_free_space <= 0 then
|
||||
last_message = "No cargo space left."
|
||||
return
|
||||
end
|
||||
local cargo_type = next(selected_point.cargo_contents) -- TODO handle the possibility of this being empty
|
||||
local cargo_amount = math.min(player_ship.cargo_fill_speed * dt, selected_point.cargo_contents[cargo_type])
|
||||
if cargo_amount <= 0 then
|
||||
last_message = "There is no cargo to pick up."
|
||||
return
|
||||
end
|
||||
if not player_ship.cargo_contents[cargo_type] then
|
||||
player_ship.cargo_contents[cargo_type] = 0
|
||||
end
|
||||
player_ship.cargo_contents[cargo_type] = player_ship.cargo_contents[cargo_type] + cargo_amount
|
||||
player_ship.cargo_free_space = player_ship.cargo_free_space - cargo_amount
|
||||
selected_point.cargo_contents[cargo_type] = selected_point.cargo_contents[cargo_type] - cargo_amount
|
||||
selected_point.cargo_free_space = selected_point.cargo_free_space + cargo_amount
|
||||
last_message = "Transfered " .. cargo_amount .. " " .. cargo_type .. "."
|
||||
collect_resource()
|
||||
end
|
||||
end
|
||||
|
||||
local font = love.graphics.getFont()
|
||||
local font_height = font:getHeight()
|
||||
function love.draw()
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print(last_message, 1, 1)
|
||||
|
||||
love.graphics.rectangle("line", player_ship.position_x - player_ship.radar_size / 2, player_ship.position_y - player_ship.radar_size / 2, player_ship.radar_size, player_ship.radar_size)
|
||||
|
||||
@@ -105,6 +184,19 @@ function love.draw()
|
||||
local resource_point = resource_points[i]
|
||||
love.graphics.circle("line", resource_point.position_x, resource_point.position_y, resource_point.radar_size)
|
||||
end
|
||||
|
||||
love.graphics.print(last_message, 1, 1)
|
||||
|
||||
local inventory_status = {}
|
||||
for cargo_type, cargo_amount in pairs(player_ship.cargo_contents) do
|
||||
table.insert(inventory_status, { cargo_type = cargo_type, cargo_amount = cargo_amount })
|
||||
end
|
||||
table.sort(inventory_status, function(A, B) return A.cargo_amount > B.cargo_amount end)
|
||||
for i = 1, #inventory_status do
|
||||
inventory_status[i] = inventory_status[i].cargo_type .. ": " .. math.floor(inventory_status[i].cargo_amount * 10) / 10
|
||||
end
|
||||
local cargo_message = "Cargo: " .. math.min(math.floor((player_ship.cargo_max_space - player_ship.cargo_free_space) * 10) / 10, player_ship.cargo_max_space) .. "/" .. player_ship.cargo_max_space .. ". " .. table.concat(inventory_status, ", ")
|
||||
love.graphics.print(cargo_message, 1, screen_height - font_height - 1)
|
||||
end
|
||||
|
||||
function love.keypressed(key)
|
||||
|
||||
Reference in New Issue
Block a user