Created
April 16, 2023 01:10
-
-
Save pwillia7/1daddfd523c281c3405a919b4a6446bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- love 2d game code | |
-- require the isometric library | |
local iso = require("isometric") | |
-- define some constants | |
local TILE_SIZE = 64 -- the size of each tile in pixels | |
local MAP_WIDTH = 20 -- the width of the map in tiles | |
local MAP_HEIGHT = 20 -- the height of the map in tiles | |
local CITY_COUNT = 4 -- the number of cities on the map | |
local NODE_COUNT = 10 -- the number of resource nodes on the map | |
local GOODS = {"wood", "coal", "iron", "steel", "oil", "plastic", "food", "clothes", "electronics"} -- the list of goods in the game | |
local PRICES = {wood = 10, coal = 20, iron = 30, steel = 50, oil = 40, plastic = 60, food = 80, clothes = 100, electronics = 200} -- the prices of goods in dollars per unit | |
local DEMANDS = {wood = 1, coal = 1, iron = 1, steel = 2, oil = 2, plastic = 3, food = 4, clothes = 5, electronics = 6} -- the demands of goods in units per city per month | |
local START_MONEY = 100000 -- the starting money of the player in dollars | |
local GOAL_MONEY = 100000000 -- the goal money of the player in dollars | |
local MONTH_DURATION = 10 -- the duration of a month in seconds | |
-- define some colors | |
local COLORS = { | |
grass = {0.2, 0.8, 0.2}, | |
road = {0.5, 0.5, 0.5}, | |
rail = {0.8, 0.8, 0.8}, | |
city = {1, 1, 1}, | |
node = {0.8, 0.8, 0.2}, | |
vehicle = {1, 0.5, 0}, | |
train = {0.5, 0.5, 1}, | |
toolbar = {0.2, 0.2, 0.2}, | |
text = {1, 1, 1} | |
} | |
-- define some images | |
local IMAGES = { | |
wood = love.graphics.newImage("wood.png"), | |
coal = love.graphics.newImage("coal.png"), | |
iron = love.graphics.newImage("iron.png"), | |
steel = love.graphics.newImage("steel.png"), | |
oil = love.graphics.newImage("oil.png"), | |
plastic = love.graphics.newImage("plastic.png"), | |
food = love.graphics.newImage("food.png"), | |
clothes = love.graphics.newImage("clothes.png"), | |
electronics = love.graphics.newImage("electronics.png") | |
} | |
-- define some sounds | |
local SOUNDS = { | |
build_road = love.audio.newSource("build_road.wav", "static"), | |
build_rail = love.audio.newSource("build_rail.wav", "static"), | |
buy_vehicle = love.audio.newSource("buy_vehicle.wav", "static"), | |
buy_train = love.audio.newSource("buy_train.wav", "static"), | |
set_route = love.audio.newSource("set_route.wav", "static"), | |
deliver_goods = love.audio.newSource("deliver_goods.wav", "static") | |
} | |
-- create a random map with grass tiles | |
local map = iso.Map(MAP_WIDTH, MAP_HEIGHT) | |
for x=1,map.width do | |
for y=1,map.height do | |
local tile = iso.Tile(TILE_SIZE) | |
tile:setColor(COLORS.grass) | |
map:setTile(x,y,tile) | |
end | |
end | |
-- create a list of cities with random names and locations | |
local cities = {} | |
local city_names = {"New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "San Antonio", "San Diego", "Dallas", "San Jose"} | |
for i=1,CITY_COUNT do | |
local city_name_index= math.random(#city_names) | |
local city_name= table.remove(city_names, city_name_index) | |
local city_x= math.random(2,map.width-1) | |
local city_y= math.random(2,map.height-1) | |
local city_tile= map:getTile(city_x,city_y) | |
city_tile:setColor(COLORS.city) | |
-- create a list of goods that the city demands with random quantities and values | |
local city_goods= {} | |
for j=1,#GOODS do | |
local good= GOODS[j] | |
local quantity= math.random(1,5) -- the quantity of the good that the city demands per month | |
local value= PRICES[good] * quantity -- the value of the good that the city demands per month | |
city_goods[good]= {quantity= quantity, value= value} | |
end | |
-- sort the goods by their value in descending order | |
table.sort(city_goods, function(a,b) return a.value > b.value end) | |
-- keep only the first 3 goods as the initial demands of the city | |
while #city_goods > 3 do | |
table.remove(city_goods) | |
end | |
-- create a city object with its name, location, tile, goods and money earned | |
local city= {name= city_name, x= city_x, y= city_y, tile= city_tile, goods= city_goods, money= 0} | |
-- add the city to the list of cities | |
table.insert(cities, city) | |
end | |
-- create a list of resource nodes with random types and locations | |
local nodes = {} | |
for i=1,NODE_COUNT do | |
local node_good_index = math.random(#GOODS) | |
local node_good = GOODS[node_good_index] | |
local node_x = math.random(2,map.width-1) | |
local node_y = math.random(2,map.height-1) | |
local node_tile = map:getTile(node_x,node_y) | |
node_tile:setColor(COLORS.node) | |
-- create a node object with its type, location and tile | |
local node = {good = node_good, x = node_x, y = node_y, tile = node_tile} | |
-- add the node to the list of nodes | |
table.insert(nodes, node) | |
end | |
-- create a list of vehicles with their types, costs and capacities | |
local vehicles = { | |
{type = "truck", cost = 10000, capacity = 10}, | |
{type = "van", cost = 20000, capacity = 20}, | |
{type = "bus", cost = 30000, capacity = 30} | |
} | |
-- create a list of trains with their types, costs and capacities | |
local trains = { | |
{type = "steam", cost = 50000, capacity = 50}, | |
{type = "diesel", cost = 100000, capacity = 100}, | |
{type = "electric", cost = 200000, capacity = 200} | |
} | |
-- create a list of routes with their start and end points and vehicles or trains assigned to them | |
local routes = {} | |
-- create a player object with its money and selected tool | |
local player = {money = START_MONEY, tool = "road"} | |
-- create a toolbar object with its buttons and position | |
local toolbar = {} | |
toolbar.x = 0 | |
toolbar.y = love.graphics.getHeight() - TILE_SIZE | |
toolbar.buttons = { | |
{name = "road", image = love.graphics.newImage("road.png")}, | |
{name = "rail", image = love.graphics.newImage("rail.png")}, | |
{name = "vehicle", image = love.graphics.newImage("vehicle.png")}, | |
{name = "train", image = love.graphics.newImage("train.png")}, | |
{name = "route", image = love.graphics.newImage("route.png")} | |
} | |
-- create a timer object to keep track of the game time | |
local timer = {} | |
timer.month = 1 -- the current month | |
timer.year = 2023 -- the current year | |
timer.time = 0 -- the elapsed time in seconds | |
timer.speed = 1 -- the speed of the game (1x, 2x or 4x) | |
-- create a function to draw the map and its elements | |
local function drawMap() | |
-- draw the map tiles | |
map:draw() | |
-- draw the city names and goods | |
for i,city in ipairs(cities) do | |
-- get the screen coordinates of the city tile | |
local x,y = map:toScreen(city.x,city.y) | |
-- draw the city name above the tile | |
love.graphics.setColor(COLORS.text) | |
love.graphics.print(city.name, x - TILE_SIZE/2, y - TILE_SIZE) | |
-- draw the city goods below the tile | |
for j,good in ipairs(city.goods) do | |
-- get the image of the good | |
local image = IMAGES[good] | |
-- draw the image with a small offset for each good | |
love.graphics.draw(image, x - TILE_SIZE/2 + (j-1) * TILE_SIZE/4, y + TILE_SIZE/4) | |
end | |
end | |
-- draw the node types | |
for i,node in ipairs(nodes) do | |
-- get the screen coordinates of the node tile | |
local x,y = map:toScreen(node.x,node.y) | |
-- get the image of the node good | |
local image = IMAGES[node.good] | |
-- draw the image on top of the tile | |
love.graphics.draw(image, x - TILE_SIZE/4, y - TILE_SIZE/4) | |
end | |
-- draw the routes and their vehicles or trains | |
for i,route in ipairs(routes) do | |
-- get the screen coordinates of the start and end points of the route | |
local x1,y1 = map:toScreen(route.start.x,route.start.y) | |
local x2,y2 = map:toScreen(route.routeend.x,route.routeend.y) | |
-- draw a line between the points with a color depending on the route type (road or rail) | |
if route.type == "road" then | |
love.graphics.setColor(COLORS.road) | |
elseif route.type == "rail" then | |
love.graphics.setColor(COLORS.rail) | |
end | |
love.graphics.line(x1,y1,x2,y2) | |
-- draw the vehicle or train on the route with a color depending on its type (truck, van, bus, steam, diesel or electric) | |
if route.vehicle then | |
if route.vehicle.type == "truck" then | |
love.graphics.setColor(COLORS.vehicle) | |
elseif route.vehicle.type == "van" then | |
love.graphics.setColor(COLORS.vehicle) | |
elseif route.vehicle.type == "bus" then | |
love.graphics.setColor(COLORS.vehicle) | |
end | |
-- get the position of the vehicle on the route based on its progress (0 to 1) | |
local x = x1 + (x2 - x1) * route.vehicle.progress | |
local y = y1 + (y2 - y1) * route.vehicle.progress | |
-- draw a circle to represent the vehicle | |
love.graphics.circle("fill", x, y, TILE_SIZE/8) | |
-- draw the good that the vehicle is carrying if any | |
if route.vehicle.good then | |
-- get the image of the good | |
local image = IMAGES[route.vehicle.good] | |
-- draw the image above the vehicle | |
love.graphics.draw(image, x - TILE_SIZE/4, y - TILE_SIZE/2) | |
end | |
elseif route.train then | |
if route.train.type == "steam" then | |
love.graphics.setColor(COLORS.train) | |
elseif route.train.type == "diesel" then | |
love.graphics.setColor(COLORS.train) | |
elseif route.train.type == "electric" then | |
love.graphics.setColor(COLORS.train) | |
end | |
-- get the position of the train on the route based on its progress (0 to 1) | |
local x = x1 + (x2 - x1) * route.train.progress | |
local y = y1 + (y2 - y1) * route.train.progress | |
-- draw a rectangle to represent the train | |
love.graphics.rectangle("fill", x - TILE_SIZE/4, y - TILE_SIZE/8, TILE_SIZE/2, TILE_SIZE/4) | |
-- draw the goods that the train is carrying if any | |
if route.train.goods then | |
for j,good in ipairs(route.train.goods) do | |
-- get the image of the good | |
local image = IMAGES[good] | |
-- draw the image above the train with a small offset for each good | |
love.graphics.draw(image, x - TILE_SIZE/4 + (j-1) * TILE_SIZE/8, y - TILE_SIZE/2) | |
end | |
end | |
end | |
end | |
end | |
-- create a function to draw the toolbar and its buttons | |
local function drawToolbar() | |
-- draw a rectangle to represent the toolbar background | |
love.graphics.setColor(COLORS.toolbar) | |
love.graphics.rectangle("fill", toolbar.x, toolbar.y, love.graphics.getWidth(), TILE_SIZE) | |
-- draw the toolbar buttons with their images and names | |
for i,button in ipairs(toolbar.buttons) do | |
-- get the position of the button based on its index | |
local x = toolbar.x + (i-1) * TILE_SIZE | |
local y = toolbar.y | |
-- draw the button image on top of the button background | |
love.graphics.draw(button.image, x, y) | |
-- draw the button name below the button image | |
love.graphics.setColor(COLORS.text) | |
love.graphics.print(button.name, x + TILE_SIZE/4, y + TILE_SIZE/2) | |
end | |
-- draw a rectangle around the selected button to indicate it is active | |
love.graphics.setColor(COLORS.text) | |
love.graphics.rectangle("line", toolbar.x + (player.tool-1) * TILE_SIZE, toolbar.y, TILE_SIZE, TILE_SIZE) | |
end | |
-- create a function to draw the player information and game status | |
local function drawInfo() | |
-- draw the player money on the top left corner of the screen | |
love.graphics.setColor(COLORS.text) | |
love.graphics.print("Money: $" .. player.money, 0, 0) | |
-- draw the game time on the top right corner of the screen | |
love.graphics.print("Time: " .. timer.month .. "/" .. timer.year .. " (" .. timer.speed .. "x)", love.graphics.getWidth() - 200, 0) | |
-- draw a message if the player has won or lost the game on the center of the screen | |
if player.money >= GOAL_MONEY then | |
love.graphics.print("You win! You have reached $" .. GOAL_MONEY .. "!", love.graphics.getWidth()/2 - 100, love.graphics.getHeight()/2 - 50) | |
elseif player.money <= 0 then | |
love.graphics.print("You lose! You have run out of money!", love.graphics.getWidth()/2 - 100, love.graphics.getHeight()/2 - 50) | |
end | |
end | |
-- create a function to update the game logic based on delta time (dt) | |
local function update(dt) | |
-- update the timer by adding the delta time multiplied by the speed | |
timer.time = timer.time + dt * timer.speed | |
-- check if a month has passed | |
if timer.time >= MONTH_DURATION then | |
-- reset the timer | |
timer.time = 0 | |
-- increment the month and the year if necessary | |
timer.month = timer.month + 1 | |
if timer.month > 12 then | |
timer.month = 1 | |
timer.year = timer.year + 1 | |
end | |
-- update the city demands by adding a new good every year with a random quantity and value | |
for i,city in ipairs(cities) do | |
if #city.goods < 5 and timer.month == 1 then | |
local good_index = math.random(#GOODS) | |
local good = GOODS[good_index] | |
local quantity = math.random(1,5) | |
local value = PRICES[good] * quantity | |
table.insert(city.goods, {good = good, quantity = quantity, value = value}) | |
end | |
end | |
-- update the routes by moving their vehicles or trains and delivering goods to the cities or nodes | |
for i,route in ipairs(routes) do | |
if route.vehicle then | |
-- increment the vehicle progress by a small amount depending on its type (truck, van or bus) | |
if route.vehicle.type == "truck" then | |
route.vehicle.progress = route.vehicle.progress + 0.01 | |
elseif route.vehicle.type == "van" then | |
route.vehicle.progress = route.vehicle.progress + 0.02 | |
elseif route.vehicle.type == "bus" then | |
route.vehicle.progress = route.vehicle.progress + 0.03 | |
end | |
-- check if the vehicle has reached the end of the route | |
if route.vehicle.progress >= 1 then | |
-- reset the vehicle progress | |
route.vehicle.progress = 0 | |
-- check if the vehicle is carrying a good or not | |
if route.vehicle.good then | |
-- check if the end point of the route is a city or a node | |
if route.routeend.city then | |
-- check if the city demands the good that the vehicle is carrying | |
for j,good in ipairs(route.routeend.city.goods) do | |
if good.good == route.vehicle.good then | |
-- deliver the good to the city and earn money based on its value | |
player.money = player.money + good.value | |
-- play a sound to indicate a successful delivery | |
SOUNDS.deliver_goods:play() | |
-- remove the good from the vehicle | |
route.vehicle.good = nil | |
end | |
end | |
elseif route.routeend.node then | |
-- deliver the good to the node and remove it from the vehicle | |
route.vehicle.good = nil | |
end | |
else | |
-- check if the start point of the route is a city or a node | |
if route.start.city then | |
-- pick up a random good from the city that matches one of its demands | |
local good_index= math.random(#route.start.city.goods) | |
local good= route.start.city.goods[good_index].good | |
route.vehicle.good= good | |
elseif route.start.node then | |
-- pick up the good from the node that matches its type | |
local good= route.start.node.good | |
route.vehicle.good= good | |
end | |
end | |
end | |
elseif route.train then | |
-- increment the train progress by a small amount depending on its type (steam, diesel or electric) | |
if route.train.type == "steam" then | |
route.train.progress= route.train.progress + 0.01 | |
elseif route.train.type == "diesel" then | |
route.train.progress= route.train.progress + 0.02 | |
elseif route.train.type == "electric" then | |
route.train.progress= route.train.progress + 0.03 | |
end | |
-- check if the train has reached the end of the route | |
if route.train.progress >= 1 then | |
-- reset the train progress | |
route.train.progress= 0 | |
-- check if the train is carrying any goods or not | |
if #route.train.goods > 0 then | |
-- check if the end point of the route is a city or a node | |
if route.routeend.city then | |
-- deliver all the goods to the city that match its demands and earn money based on their values | |
for j=#route.train.goods,1,-1 do | |
local good = route.train.goods[j] | |
for k,city_good in ipairs(route.routeend.city.goods) do | |
if city_good.good == good then | |
-- deliver the good to the city and earn money based on its value | |
player.money = player.money + city_good.value | |
-- play a sound to indicate a successful delivery | |
SOUNDS.deliver_goods:play() | |
-- remove the good from the train | |
table.remove(route.train.goods, j) | |
end | |
end | |
end | |
elseif route.routeend.node then | |
-- deliver all the goods to the node and remove them from the train | |
route.train.goods = {} | |
end | |
else | |
-- check if the start point of the route is a city or a node | |
if route.start.city then | |
-- pick up as many goods as possible from the city that match its demands and fit in the train capacity | |
for j,city_good in ipairs(route.start.city.goods) do | |
local good = city_good.good | |
local quantity = city_good.quantity | |
-- check if the train has enough space for the good | |
if #route.train.goods + quantity <= route.train.capacity then | |
-- pick up the good and add it to the train goods | |
for k=1,quantity do | |
table.insert(route.train.goods, good) | |
end | |
end | |
end | |
elseif route.start.node then | |
-- pick up as many goods as possible from the node that match its type and fit in the train capacity | |
local good = route.start.node.good | |
local quantity = math.min(route.train.capacity - #route.train.goods, 10) -- assume each node can produce up to 10 units of its good per month | |
-- check if the train has enough space for the good | |
if quantity > 0 then | |
-- pick up the good and add it to the train goods | |
for k=1,quantity do | |
table.insert(route.train.goods, good) | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
-- check if the player has clicked on the map or the toolbar | |
if love.mouse.isDown(1) then | |
-- get the mouse position | |
local mx,my = love.mouse.getPosition() | |
-- check if the mouse is over the toolbar or not | |
if my >= toolbar.y then | |
-- get the index of the button that the mouse is over | |
local button_index = math.floor(mx / TILE_SIZE) + 1 | |
-- check if the button index is valid | |
if button_index >= 1 and button_index <= #toolbar.buttons then | |
-- get the name of the button | |
local button_name = toolbar.buttons[button_index].name | |
-- set the player tool to the button name | |
player.tool = button_name | |
end | |
else | |
-- get the map coordinates of the tile that the mouse is over | |
local tx,ty = map:toMap(mx,my) | |
-- check if the tile coordinates are valid | |
if tx >= 1 and tx <= map.width and ty >= 1 and ty <= map.height then | |
-- get the tile object | |
local tile = map:getTile(tx,ty) | |
-- check what tool the player is using | |
if player.tool == "road" then | |
-- check if the tile is grass or not | |
if tile:getColor() == COLORS.grass then | |
-- build a road on the tile and deduct its cost from the player money | |
tile:setColor(COLORS.road) | |
player.money = player.money - 1000 | |
-- play a sound to indicate a successful build | |
SOUNDS.build_road:play() | |
end | |
elseif player.tool == "rail" then | |
-- check if the tile is grass or not | |
if tile:getColor() == COLORS.grass then | |
-- build a rail on the tile and deduct its cost from the player money | |
tile:setColor(COLORS.rail) | |
player.money = player.money - 2000 | |
-- play a sound to indicate a successful build | |
SOUNDS.build_rail:play() | |
end | |
elseif player.tool == "vehicle" then | |
-- check if there is a route selected or not | |
if not player.route then | |
-- check if there is a city or a node on the tile | |
for i,city in ipairs(cities) do | |
if city.x == tx and city.y == ty then | |
-- select the city as the start point of the route | |
player.route = {start = {city = city, x = tx, y = ty}, type = "road"} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
for i,node in ipairs(nodes) do | |
if node.x == tx and node.y == ty then | |
-- select the node as the start point of the route | |
player.route = {start = {node = node, x = tx, y = ty}, type = "road"} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
else | |
-- check if there is a city or a node on the tile | |
for i,city in ipairs(cities) do | |
if city.x == tx and city.y == ty then | |
-- select the city as the end point of the route | |
player.route.routeend = {city = city, x = tx, y = ty} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
for i,node in ipairs(nodes) do | |
if node.x == tx and node.y == ty then | |
-- select the node as the end point of the route | |
player.route.routeend = {node = node, x = tx, y = ty} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
-- check if both start and end points of the route are selected | |
if player.route.start and player.route.routeend then | |
-- check if there is a road connecting the start and end points of the route | |
local valid= true | |
local dx= math.abs(player.route.start.x - player.route.routeend.x) | |
local dy= math.abs(player.route.start.y - player.route.routeend.y) | |
if dx == dy then | |
-- check if the road is diagonal | |
for i=0,dx-1 do | |
local x= math.min(player.route.start.x, player.route.routeend.x) + i | |
local y= math.min(player.route.start.y, player.route.routeend.y) + i | |
local tile= map:getTile(x,y) | |
if tile:getColor() ~= COLORS.road then | |
-- the road is not valid | |
valid= false | |
break | |
end | |
end | |
elseif dx == 0 or dy == 0 then | |
-- check if the road is horizontal or vertical | |
for i=0,dx-1 do | |
local x= math.min(player.route.start.x, player.route.routeend.x) + i | |
local y= player.route.start.y | |
local tile= map:getTile(x,y) | |
if tile:getColor() ~= COLORS.road then | |
-- the road is not valid | |
valid= false | |
break | |
end | |
end | |
for i=0,dy-1 do | |
local x= player.route.start.x | |
local y= math.min(player.route.start.y, player.route.routeend.y) + i | |
local tile= map:getTile(x,y) | |
if tile:getColor() ~= COLORS.road then | |
-- the road is not valid | |
valid= false | |
break | |
end | |
end | |
else | |
-- the road is not valid | |
valid= false | |
end | |
-- check if the road is valid | |
if valid then | |
-- add the route to the list of routes | |
table.insert(routes, player.route) | |
-- ask the player to choose a vehicle type from the list of vehicles | |
local vehicle_type = love.window.showMessageBox("Choose a vehicle", "Please choose a vehicle type for your route:", {"truck", "van", "bus", "cancel"}) | |
-- check if the player has chosen a vehicle type or not | |
if vehicle_type ~= 4 then | |
-- get the vehicle object from the list of vehicles based on its type | |
local vehicle = vehicles[vehicle_type] | |
-- check if the player has enough money to buy the vehicle or not | |
if player.money >= vehicle.cost then | |
-- buy the vehicle and deduct its cost from the player money | |
player.money = player.money - vehicle.cost | |
-- assign the vehicle to the route and set its progress to 0 | |
player.route.vehicle = {type = vehicle.type, capacity = vehicle.capacity, progress = 0} | |
-- play a sound to indicate a successful purchase | |
SOUNDS.buy_vehicle:play() | |
else | |
-- show a message that the player does not have enough money to buy the vehicle | |
love.window.showMessageBox("Not enough money", "You do not have enough money to buy a " .. vehicle.type .. ". It costs $" .. vehicle.cost .. ".", {"OK"}) | |
end | |
end | |
else | |
-- show a message that the route is not valid | |
love.window.showMessageBox("Invalid route", "The route is not valid. There must be a road connecting the start and end points.", {"OK"}) | |
end | |
-- reset the player route | |
player.route= nil | |
end | |
end | |
elseif player.tool == "train" then | |
-- check if there is a route selected or not | |
if not player.route then | |
-- check if there is a city or a node on the tile | |
for i,city in ipairs(cities) do | |
if city.x == tx and city.y == ty then | |
-- select the city as the start point of the route | |
player.route = {start = {city = city, x = tx, y = ty}, type = "rail"} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
for i,node in ipairs(nodes) do | |
if node.x == tx and node.y == ty then | |
-- select the node as the start point of the route | |
player.route = {start = {node = node, x = tx, y = ty}, type = "rail"} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
else | |
-- check if there is a city or a node on the tile | |
for i,city in ipairs(cities) do | |
if city.x == tx and city.y == ty then | |
-- select the city as the end point of the route | |
player.route.routeend = {city = city, x = tx, y = ty} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
for i,node in ipairs(nodes) do | |
if node.x == tx and node.y == ty then | |
-- select the node as the end point of the route | |
player.route.routeend = {node = node, x = tx, y = ty} | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
-- check if both start and end points of the route are selected | |
if player.route.start and player.route.routeend then | |
-- check if there is a rail connecting the start and end points of the route | |
local valid = true | |
local dx = math.abs(player.route.start.x - player.route.routeend.x) | |
local dy = math.abs(player.route.start.y - player.route.routeend.y) | |
if dx == dy then | |
-- check if the rail is diagonal | |
for i=0,dx-1 do | |
local x = math.min(player.route.start.x, player.route.routeend.x) + i | |
local y = math.min(player.route.start.y, player.route.routeend.y) + i | |
local tile = map:getTile(x,y) | |
if tile:getColor() ~= COLORS.rail then | |
-- the rail is not valid | |
valid = false | |
break | |
end | |
end | |
elseif dx == 0 or dy == 0 then | |
-- check if the rail is horizontal or vertical | |
for i=0,dx-1 do | |
local x = math.min(player.route.start.x, player.route.routeend.x) + i | |
local y = player.route.start.y | |
local tile = map:getTile(x,y) | |
if tile:getColor() ~= COLORS.rail then | |
-- the rail is not valid | |
valid = false | |
break | |
end | |
end | |
for i=0,dy-1 do | |
local x = player.route.start.x | |
local y = math.min(player.route.start.y, player.route.routeend.y) + i | |
local tile = map:getTile(x,y) | |
if tile:getColor() ~= COLORS.rail then | |
-- the rail is not valid | |
valid = false | |
break | |
end | |
end | |
else | |
-- the rail is not valid | |
valid = false | |
end | |
-- check if the rail is valid | |
if valid then | |
-- add the route to the list of routes | |
table.insert(routes, player.route) | |
-- ask the player to choose a train type from the list of trains | |
local train_type = love.window.showMessageBox("Choose a train", "Please choose a train type for your route:", {"steam", "diesel", "electric", "cancel"}) | |
-- check if the player has chosen a train type or not | |
if train_type ~= 4 then | |
-- get the train object from the list of trains based on its type | |
local train = trains[train_type] | |
-- check if the player has enough money to buy the train or not | |
if player.money >= train.cost then | |
-- buy the train and deduct its cost from the player money | |
player.money = player.money - train.cost | |
-- assign the train to the route and set its progress to 0 | |
player.route.train = {type = train.type, capacity = train.capacity, progress = 0, goods = {}} | |
-- play a sound to indicate a successful purchase | |
SOUNDS.buy_train:play() | |
else | |
-- show a message that the player does not have enough money to buy the train | |
love.window.showMessageBox("Not enough money", "You do not have enough money to buy a " .. train.type .. ". It costs $" .. train.cost .. ".", {"OK"}) | |
end | |
end | |
else | |
-- show a message that the route is not valid | |
love.window.showMessageBox("Invalid route", "The route is not valid. There must be a rail connecting the start and end points.", {"OK"}) | |
end | |
-- reset the player route | |
player.route= nil | |
end | |
end | |
elseif player.tool == "route" then | |
-- check if there is a route selected or not | |
if not player.route then | |
-- check if there is a route on the tile | |
for i,route in ipairs(routes) do | |
if (route.start.x == tx and route.start.y == ty) or (route.routeend.x == tx and route.routeend.y == ty) then | |
-- select the route | |
player.route= route | |
-- play a sound to indicate a successful selection | |
SOUNDS.set_route:play() | |
-- break the loop | |
break | |
end | |
end | |
else | |
-- reset the player route | |
player.route= nil | |
end | |
end | |
end | |
end | |
end | |
end | |
-- create a function to handle keyboard input | |
local function keypressed(key) | |
-- check what key was pressed | |
if key == "escape" then | |
-- quit the game | |
love.event.quit() | |
elseif key == "1" then | |
-- set the game speed to 1x | |
timer.speed = 1 | |
elseif key == "2" then | |
-- set the game speed to 2x | |
timer.speed = 2 | |
elseif key == "4" then | |
-- set the game speed to 4x | |
timer.speed = 4 | |
end | |
end | |
-- register the functions to the love callbacks | |
love.draw = drawMap | |
love.draw = drawToolbar | |
love.draw = drawInfo | |
love.update = update | |
love.keypressed = keypressed | |
-- load the isometric library and initialize the map offset and angle | |
iso.load() | |
map:setOffset(love.graphics.getWidth()/2 - TILE_SIZE/2, TILE_SIZE) | |
map:setAngle(0.25 * math.pi) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment