Guest User

CurrentCode

a guest
Jun 14th, 2016
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.07 KB | None | 0 0
  1. require("lovedebug")
  2. local gamera = require "gamera" -- camera modifier, important.
  3. local lume = require "lume" -- Useful functions, mostly random table stuff.
  4. local flux = require "flux" -- Animations and tweening
  5. local timer = require "hump.timer" -- obviously used for timers. Simple and functional.
  6.  
  7. -- general variables
  8. math.randomseed(os.time()) -- makes things actually random. Super useful line.
  9. local mainWidth, mainHeight = love.graphics.getDimensions() -- grabs the screen dimensions. Useful.
  10. local modeNum = 1 -- technical variable, controls modeName.
  11. local modeName -- the string name of the current mode. locate mouseModeSwitch() to see list.
  12. local preload = true
  13.  
  14. -- grid variables
  15. local grid = {} -- stores the entire grid
  16. local initGrid = true -- initializes the "invisible" grid coords into tGrid.
  17. local gridPos = {}
  18. local mouseGridX, mouseGridY = nil, nil -- keep nil, not empty. Some code relies on ensuring these have values and will crash otherwise.
  19. local loadedTiles = {}
  20. local gridSizeX, gridSizeY = 50, 50 -- grid size. Likely keep 50,50. Maybe change based on planet size and other things later, like certain techs.
  21. local terrain = {} -- placed tiles
  22. local gridValuesLoaded = false
  23. local initialPlacement = true -- waits for the initial tile placement.
  24. local debugGrid = false -- controls whether or not the grid is visible.
  25.  
  26. -- screen variables
  27. local moveVariable = 50 -- the initial moving speed for WASD movement.
  28. local screenScale = 1 -- set the initial zoom to 1x
  29.  
  30. -- soul variables
  31. local playerList = {}
  32. local interactDist = 3 -- how far they can check when pathfinding
  33.  
  34. -- pathfinding variables
  35. local xPathSign, yPathSign = "none" -- whether to go up or down with signs
  36. local testPath = {}
  37. local path = {} -- the real path to take
  38.  
  39. local function screenSize() -- setup the gamera world based upon the current grid.
  40.   sWidth, sHeight = (gridSizeX * 64)*1.25, (gridSizeY * 64)*1.25 -- calculate the size taken by full pixels, modified to look nice on edges. (25% increase)
  41.   xTop = 0 -- start at 0, don't head negative. Makes things difficult.
  42.   xBot = sHeight -- modified height from above equation.
  43.   yTop = 0
  44.   yBot = sWidth
  45.   cam = gamera.new(xTop,yTop,xBot,yBot)
  46.   left, top, width, height = cam:getWorld() -- width = right, height = bottom
  47.   startX, startY = sWidth/2, sHeight/2
  48.   cam:setPosition(startX, startY) -- set the center point of the camera to the center of the world.
  49. end
  50.  
  51. local function gridLoad() -- creates a [x][y] format numbered list to iterate and assign variables to (keep first, everything relies upon this)
  52.   if preload then
  53.     for x=1, gridSizeX do
  54.       grid[x] = {}
  55.       for y=1, gridSizeY do
  56.         grid[x][y] = { x = 0, y = 0, img = "none"}
  57.         if x == gridSizeX and y == gridSizeY then
  58.           preload = false
  59.         end
  60.       end
  61.     end
  62.   end
  63. end
  64.  
  65. local function mouseModeSwitch() -- detects when you hit the mode key, triggers only once, and changes modeName to the proper variable.
  66.   function love.keypressed(key)
  67.     if key == "m" then -- mode cycle. move to something easier on release.
  68.       if modeNum < 3 then -- # == number of available modes, listed at bottom of this function.
  69.         modeNum = modeNum + 1
  70.       else
  71.         modeNum = 1
  72.       end
  73.     elseif key == "o" then -- testing key for values. Remove in public releases.
  74.       debugGrid = true
  75.     elseif key == "p" then -- testing key for values. Remove in public releases.
  76.       debugGrid = false
  77.     elseif key == "t" then -- testing key for values. Remove in public releases.
  78.     end
  79.   end
  80.   if modeNum == 1 then
  81.     modeName = "land"
  82.   elseif modeNum == 2 then
  83.     modeName = "souls"
  84.   elseif modeNum == 3 then
  85.     modeName = "build"
  86.   end
  87. end
  88.  
  89. local function screenMove(dt) -- allows the use of WASD and arrow keys for screen movement.
  90.   local camXPos, camYPos = cam:getPosition() -- finds the center of the visible screen, tracks boundaries.
  91.   local moveMin = 50 -- the minimum movement speed. Tweak as needed.
  92.   local moveMax = 300 -- the max movement speed. Tweak as needed.
  93.   if love.keyboard.isDown('w') then
  94.     if moveVariable < moveMax then -- if the current movement speed is under the maximum, go down a line and increase it by 1 every delta frame.
  95.       moveVariable = moveVariable + 1
  96.     end
  97.     if love.keyboard.isDown('a') then
  98.       cam:setPosition(camXPos - moveVariable * dt, camYPos - moveVariable * dt) -- detect if another specified key is being pressed at the same time as W.
  99.     elseif love.keyboard.isDown('d') then
  100.       cam:setPosition(camXPos + moveVariable * dt, camYPos - moveVariable * dt)
  101.     else
  102.       cam:setPosition(camXPos, camYPos - moveVariable * dt) -- changes the position based upon moveVariable and delta time to run similarly on all systems.
  103.     end
  104.   elseif love.keyboard.isDown('s') then -- keep 'w' and 's' first, so they trigger first. keeps it from having to run every option, keep it as the two main directions.
  105.     if moveVariable < moveMax then
  106.       moveVariable = moveVariable + 1
  107.     end
  108.     if love.keyboard.isDown('a') then
  109.       cam:setPosition(camXPos - moveVariable * dt, camYPos + moveVariable * dt)
  110.     elseif love.keyboard.isDown('d') then
  111.       cam:setPosition(camXPos + moveVariable * dt, camYPos + moveVariable * dt)
  112.     else
  113.       cam:setPosition(camXPos, camYPos + moveVariable * dt)
  114.     end
  115.   elseif love.keyboard.isDown('d') then
  116.     if moveVariable < moveMax then
  117.       moveVariable = moveVariable + 1
  118.     end
  119.     cam:setPosition(camXPos + moveVariable * dt, camYPos)
  120.   elseif love.keyboard.isDown('a') then
  121.     if moveVariable < moveMax then
  122.       moveVariable = moveVariable + 1
  123.     end
  124.     cam:setPosition(camXPos - moveVariable * dt, camYPos)
  125.   elseif love.keyboard.isDown('c') then -- center the camera.
  126.     cam:setPosition(sWidth/2, sHeight/2)
  127.   else
  128.     if moveVariable > moveMin then
  129.       moveVariable = moveVariable - 5 -- ensures the movement doesn't come to a full stop, it'll ease back down.
  130.     end
  131.   end
  132. end
  133.  
  134. local function screenZoom()
  135.   function love.wheelmoved(x, y) -- records mouse wheel movement. Possibly add a keypress to this later.
  136.     scaleMin = .6 -- minimum zoom
  137.     scaleMax = 2.4 -- maximum zoom
  138.     if y > 0 then -- mouse wheel forward. wheel moved returns a positive or negative value.
  139.         if scaleMax > screenScale then
  140.           screenScale = screenScale + 0.2 -- modifies screenScale with every wheel movement.
  141.           cam:setScale(screenScale)
  142.         end
  143.     elseif y < 0 then
  144.         if scaleMin < screenScale then
  145.           screenScale = screenScale - 0.2
  146.           cam:setScale(screenScale)
  147.       end
  148.     end
  149.   end
  150. end
  151.  
  152. local function visualAssets() -- loads in all the visual assets (only in a function for organization).
  153.   tileg1 = love.graphics.newImage('assets/grass1.png')
  154.   tilegrid = love.graphics.newImage('assets/grid.png')-- first grass texture caching
  155.   playerex = love.graphics.newImage('assets/ExamplePlayer.png')
  156.   farmerex = love.graphics.newImage('assets/farmer.png')
  157.   debugtile = love.graphics.newImage('assets/fulltile.png')
  158.  
  159.   block_width = tileg1:getWidth()
  160.   block_height = tileg1:getHeight()
  161.   block_depth = tileg1:getHeight()/2 -- the height of the back of the block
  162. end
  163.  
  164. function love.load()
  165.   small = love.graphics.newFont(8) -- differently sized fonts. May have to modify for localization later.
  166.   medium = love.graphics.newFont(12)
  167.   large = love.graphics.newFont(16)
  168.  
  169.   love.graphics.setDefaultFilter( 'nearest', 'nearest' ) -- keeps things from being blurry when zooming.
  170.  
  171.   screenSize() -- sets the screen size in accordance to the function.
  172.   visualAssets() -- loads in all the visual assets.
  173. end
  174.  
  175. local function mousePos()
  176.   local x, y = love.mouse.getPosition()
  177.   xM, yM = cam:toWorld(math.floor(x),math.floor(y))
  178. end
  179.  
  180. local function closestPoint () -- assigns the closest point (modified) to mouseGridX/Y.
  181.   local gridCompare = 25 -- how many pixels out constitutes association.
  182.   for xMi = 1, gridSizeX do
  183.     for yMi = 1, gridSizeY do
  184.       if xM - gridCompare <= grid[xMi][yMi].x and grid[xMi][yMi].x <= xM + gridCompare then
  185.         if yM - gridCompare <= grid[xMi][yMi].y and grid[xMi][yMi].y <= yM + gridCompare then
  186.           mouseGridX, mouseGridY = xMi, yMi -- the minus 1 is due to the size of the texture, not a code glitch. Work around this.
  187.         return
  188.         end
  189.       end
  190.     end
  191.   end
  192. end
  193.  
  194. function love.update(dt)
  195.   gridLoad() -- create the listings within tGrid
  196.   mouseModeSwitch() -- Change the mouse mode.
  197.   screenMove(dt) -- WASD
  198.   screenZoom() -- Zooming
  199.   mousePos() -- locate and record mouse world positions.
  200.   closestPoint() -- tracks the closest grid location.
  201. end
  202.  
  203. local function gridXY() -- optionally draw the grid points, record their world x and y as values attached to the grid[x][y] function.
  204.   if preload == false then -- after the grid loading function finishes
  205.     love.graphics.setFont(small)
  206.     for x = 1,gridSizeX do -- iterate over #gridSizeX in tGrid, same for Y. Will record over every possible value.
  207.       for y = 1,gridSizeY do
  208.         gridX = (sWidth/2) -- find world width
  209.         gridY = (sHeight/2) -- find world height
  210.         if debugGrid then
  211.           love.graphics.print((x.." "..y), gridX + ((y-x) * (block_width / 2)), gridY + ((x+y) * (block_depth / 2)) - (block_depth * (gridSizeY / 2))) -- this and next 2 lines are optional, draws grid
  212.           love.graphics.setColor(255,255,255)
  213.           love.graphics.circle("fill", gridX + ((y-x) * (block_width / 2)), gridY + ((x+y) * (block_depth / 2)) - (block_depth * (gridSizeY / 2)), 2.5, 25)
  214.         end
  215.         grid[x][y] = {x = (gridX + ((y-x) * (block_width / 2))), -- add x value to [x][y].x
  216.           y = (gridY + ((x+y) * (block_depth / 2)) - (block_depth * (gridSizeY / 2))), -- add y value to [x][y].y
  217.           t = "none"} -- add a terrain value to grid
  218.       end
  219.     end
  220.   end
  221. end
  222.  
  223. local function plotCheck(plotA) -- checks to see if a plot is occupied, and if so, by what.
  224.   for i, plotB in ipairs(terrain) do
  225.     if plotA.x == plotB.x and plotA.y == plotB.y then -- if there is a matching tile in terrain, move on
  226.       if plotA.img == tileg1 then -- remember to change this based upon the grass tile's name! (if current tile is grass, move)
  227.         if plotB.img == tilegrid then -- if placed tile is grid, move on.
  228.           plotB.img = tileg1 -- change grid to grass
  229.           return false -- uhh, look into.
  230.         end
  231.       else
  232.         return false -- just a catch if current tile isn't grass.
  233.       end
  234.     end
  235.   end
  236. end
  237.  
  238. local function gridCheck (gridX, gridY) -- checks to see if there's a grid (for use with tilePlacement())
  239.   for i, plotB in ipairs(terrain) do
  240.     if grid[gridX][gridY].x - 32 == plotB.x and grid[gridX][gridY].y - 16 == plotB.y then
  241.       if plotB.img ~= tilegrid then
  242.         --print("wasn't grid")
  243.         return false, "grid"
  244.       elseif plotB.img == tilegrid then
  245.         return true
  246.       end
  247.     else
  248.       --print("no tiles around")
  249.     end
  250.   end
  251.   return false
  252. end
  253.  
  254. local function tilePlacement (mGridX, mGridY) -- places the "star pattern" around any terrain.
  255.   if not initialPlacement then -- initial tiles have been placed.
  256.     if gridCheck(mGridX, mGridY) == false then
  257.       --print("not a grid")
  258.       return false
  259.     end
  260.   end
  261.   if mGridX ~= 1 then--mGridY ~= 1 and mGridX ~= 1 then -- to ensure that these pieces aren't placed if they're on the edge.
  262.     terrain1 = {img = tilegrid, x = grid[mGridX - 1][mGridY - 0].x - 32, y = grid[mGridX - 1][mGridY - 0].y - 16, imgN = "tilegrid"} -- top right  -> ^
  263.     grid[mGridX - 1][mGridY - 0].img = "tilegrid"
  264.     if plotCheck(terrain1) ~= false and mGridX ~= 1 then
  265.       table.insert(terrain, terrain1)
  266.     end
  267.   end
  268.   if  mGridY ~= 1 then
  269.     terrain2 = {img = tilegrid, x = grid[mGridX - 0][mGridY - 1].x - 32, y = grid[mGridX - 0][mGridY - 1].y - 16, imgN = "tilegrid"} -- top left  <- ^
  270.     grid[mGridX - 0][mGridY - 1].img = "tilegrid"
  271.     if plotCheck(terrain2) ~= false then
  272.       table.insert(terrain, terrain2)
  273.     end
  274.   end
  275.   terrain3 = {img = tileg1, x = grid[mGridX][mGridY].x - 32, y = grid[mGridX][mGridY].y - 16, imgN = "tileg1"} -- middle--print(grid[25][25].x.." "..grid[25][25].y)
  276.   grid[mGridX][mGridY].img = "tileg1"
  277.   if plotCheck(terrain3) ~= false then
  278.     table.insert(terrain, terrain3)
  279.   end
  280.   if mGridX ~= gridSizeX then
  281.     terrain4 = {img = tilegrid, x = grid[mGridX + 1][mGridY + 0].x - 32, y = grid[mGridX + 1][mGridY + 0].y - 16, imgN = "tilegrid"} -- bottom left  <- v
  282.     grid[mGridX + 1][mGridY - 0].img = "tilegrid"
  283.     if plotCheck(terrain4) ~= false then
  284.       table.insert(terrain, terrain4)
  285.     end
  286.   end
  287.   if mGridY ~= gridSizeY then
  288.     terrain5 = {img = tilegrid, x = grid[mGridX + 0][mGridY + 1].x - 32, y = grid[mGridX + 0][mGridY + 1].y - 16, imgN = "tilegrid"} -- bottom right  -> v
  289.     grid[mGridX - 0][mGridY + 1].img = "tilegrid"
  290.     if plotCheck(terrain5) ~= false then
  291.       table.insert(terrain, terrain5)
  292.     end
  293.   end
  294. end
  295.  
  296. function love.mousepressed(x, y, button, istouch) -- the singular mouse-detection function. Handles everything from UI to building.
  297.   if mouseGridX and mouseGridY ~= nil then
  298.     if button == 1 then
  299.       if modeName == "land" then
  300.         print("Land-ho!"..modeName)
  301.         tilePlacement(mouseGridX, mouseGridY)
  302.         return
  303.       end
  304.     end
  305.   end
  306. end
  307.  
  308. local function sortDrawTerrain() -- ensures that lower tiles overlap higher tiles, then draws the tiles.
  309.   local function ySorting (a, b )
  310.     return a.y < b.y
  311.   end
  312.   table.sort(terrain, ySorting)
  313.   for i, plot in ipairs(terrain) do -- draws the terrain
  314.       if modeName == "land" then -- draw everything.
  315.         love.graphics.draw(plot.img, plot.x, plot.y)
  316.       else
  317.         if plot.img ~= tilegrid then -- if not land mode, exclude grids from being drawn.
  318.           love.graphics.draw(plot.img, plot.x, plot.y)
  319.         end
  320.       end
  321.   end
  322. end
  323.  
  324. local function initialPlace() -- place the initial tiles in the center of the map.
  325.   if initialPlacement then
  326.     tilePlacement(gridSizeX/2,gridSizeY/2)
  327.     initialPlacement = false
  328.   end
  329. end
  330.  
  331. local function pathFinder(startGrX, startGrY, finishGrX, finishGrY) -- the pathfinding module. Much of this is still on paper, and hasn't actually been created due to not knowing how to transmit the info
  332.   local startX, startY, finishX, finishY = grid[startGrX][startGrY].x, grid[startGrX][startGrY].y, grid[finishGrX][finishGrY].x, grid[finishGrX][finishGrY].y -- get the actual x,y coords
  333.   local xTiles, yTiles = finishGrX - startGrX, finishGrY - startGrY
  334.   if lume.sign(xTiles) == 1 then
  335.     xPathSign = "add" -- head down v
  336.   else
  337.     xPathSign = "sub" -- head up ^ (negative number found)
  338.   end
  339.   if lume.sign(yTiles) == 1 then
  340.     yPathSign = "add"
  341.   else
  342.     yPathSign = "sub"
  343.   end
  344.  
  345. end -- find difference between start and finish, find if it's positive or negative, attempt to ease the way through by iterating through terrain, and finding if there's a possible connection.
  346.  
  347. function love.draw(dt) -- place anything screen locked outside of cam:draw, preferably below so it loads sooner.
  348.   cam:draw(function(l,t,w,h) -- gamera world locked.
  349.     gridXY() -- record .x and .y into tGrid
  350.     sortDrawTerrain()
  351.     initialPlace()
  352.   end)
  353.   love.graphics.setFont(medium)
  354.   love.graphics.print("Use 'm' to cycle the mode. Currently: "..modeName, 5, 5) -- temporary way to visualize the current mode
  355.   love.graphics.print("Use 'WASD' to move the camera, 'c' to center it", 5, 20) -- temporary way to visualize the current mode
  356.   love.graphics.print("Your current zoom level is "..screenScale.."x", 5, 35) -- temporary way to visualize the current mode
  357.   love.graphics.print("Your mouse coords are: "..math.floor(xM).." "..math.floor(yM), 5, 50) -- temporary way to visualize the current mode
  358.   if mouseGridX ~= nil then
  359.     love.graphics.print("The closest point is "..mouseGridX..","..mouseGridY, 5, 65) -- temporary way to visualize the current position on the grid
  360.     if grid[mouseGridX][mouseGridY].img ~= nil then
  361.       love.graphics.print("The closest point's image is "..grid[mouseGridX][mouseGridY].img, 5, 80) -- temporary way to visualize the current tile's image
  362.     end
  363.   end
Advertisement
Add Comment
Please, Sign In to add comment