Custom map loading technique [Solved]

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
bobbymcbobface
Citizen
Posts: 78
Joined: Tue Jun 04, 2019 8:31 pm

Re: Custom map loading technique

Post by bobbymcbobface »

sorry i didn't manage to get back to you so quickly sphyrth I'm been a bit busy

anyway i tried your code and it works perfectly thank you

ok next challenge, i need the character to move and not the map and then when he hits the boundaries I've set using this: https://github.com/adnzzzzZ/STALKER-X (topdown boundaries have been set with a lerp of 0.2 and a lead of 0)
the map will move and not the character, although i have made this partially work the map doesn't generate and black lines have re appeared again can anyone help me - thank you

edit: oh yeah here's the code

sprite.lua

Code: Select all

local themap = require 'map'

local sprite = {}
local allowmove = false
local player = {
        x = 400,
        y = 250,
        size = 25,
        image = love.graphics.newImage("sprites/jumphero1.png")
    }

function sprite:move_false()
    allowmove = false
end

function sprite:move_true()
    allowmove = true
end

function sprite:playery()
    return player.y
end

function sprite:playerx()
    return player.x
end

function sprite:load()
    Camera = require 'camera'
    camera = Camera()
    camera:setFollowLerp(0.2)
    camera:setFollowLead(0)
    camera:setFollowStyle('TOPDOWN')
    
    love.mouse.setCursor(love.mouse.getSystemCursor("crosshair"))
    
    TTimage = love.graphics.newImage("sprites/guy1.png")
    Bimage = love.graphics.newImage("Background.png")

    coins = {}
 
end

function sprite:update(dt)
    camera:follow(player.x, player.y, -0, 1, 1, player.image:getWidth()/2, player.image:getHeight()/2)
    camera:update(dt)
    
    if allowmove == true then
        if love.keyboard.isDown("s") then
            camera:shake(2, 1, 100)
        end
        
        if love.keyboard.isDown("left") then
            player.x = player.x - 80 * dt
           -- themap:moveMap(90  * dt, 0)
        elseif love.keyboard.isDown("right") then
            player.x = player.x + 80 * dt
           -- themap:moveMap(-90 * dt, 0)
        end
    
        if love.keyboard.isDown("up") then
            player.y = player.y - 80 * dt
           -- themap:moveMap(0,  20  * dt)
        elseif love.keyboard.isDown("down") then
            player.y = player.y + 80 * dt
            --themap:moveMap(0, -20  * dt)
        end
end

function sprite:draw()
    camera:attach()
    
    love.graphics.draw(tilesetBatch)
    love.graphics.print("FPS: "..love.timer.getFPS(), 10, 20)
    
    love.graphics.circle("line", player.x, player.y, player.size)
    love.graphics.draw(player.image, player.x, player.y,
    -0, 1, 1, player.image:getWidth()/2, player.image:getHeight()/2)
    
    camera:detach()
    camera:draw()
    
    end
end

return sprite
map.lua

Code: Select all

local tilesetImage
local tileSize = 32 -- size of tiles in pixels
local tileQuads = {} -- parts of the tileset used for different tiles
local tilesetSprite
local themap = {}
local map -- stores tiledata
local mapX, mapY -- view x,y in tiles. can be a fractional value like 3.25.
local mapWidth, mapHeight -- width and height in tiles

function themap:load()
  setupMap()
  setupTileset()
  updateTilesetBatch()
  themap:moveMap(-150, 0)
end

function setupMap()
  -- We only need a tiny map for this example
  mapWidth = 60
  mapHeight = 60
  
  --Leaving a space on the right and topsides so we know if the tiles are being "deleted"
  mapX = -20
  mapY = -20
  map = {}
  for x=0, mapWidth do
    map[x] = {}
    for y=0, mapHeight do
      map[x][y] = { --Let's turn this into a table that stores 3 things:
        tile = love.math.random(1, 100),
        x = x * tileSize,
        y = y * tileSize
      }
    end
  end
end

function tilequad(x, y, count)
   local start = #tileQuads + 1 -- The #<tablename> (in this case, the tablename is tileQuads) counts the number of max tiles.
                                           -- the +1 means we'll start at the number NEXT to the last tile.
                                           -- This means we won't override anything before the table.
   for i = start, start + count do
      tileQuads[i] = love.graphics.newQuad(x * tileSize, y * tileSize, tileSize, tileSize, tilesetImage:getWidth(), tilesetImage:getHeight())
   end
  return count
end

function setupTileset()
  tilesetImage = love.graphics.newImage( "mytileset.png" )
  --tilesetImage:setFilter("nearest", "linear")
  
  ---tileQuads[1] = love.graphics.newQuad(0 * tileSize, 1 * tileSize, tileSize, tileSize,
    ---tilesetImage:getWidth(), tilesetImage:getHeight())
  
  -- function tilequad has to add up to given number in map.tile
  
  tilequad(0, 0, 96)   --grass
  tilequad(0, 2, 4)    --rocks
  
  print(count)
  
  tilesetBatch = love.graphics.newSpriteBatch(tilesetImage, mapWidth * mapHeight)
end

function updateTilesetBatch()
  tilesetBatch:clear()
  for x=0, mapWidth do
    for y=0, mapHeight do
        tilesetBatch:add(tileQuads[map[x][y].tile], math.floor(map[x][y].x), math.
        floor(map[x][y].y))
    end
  end
  tilesetBatch:flush()
end

-- central function for moving the map
function themap:moveMap(dx, dy)
  for x = 0, mapWidth do
    for y = 0, mapHeight do
      map[x][y].x = map[x][y].x + dx
      map[x][y].y = map[x][y].y + dy
      
      -- Okay so I'm not "deleting" the tiles, but transferring their x and y coordinates
      
      --X
      if map[x][y].x < mapX - (tileSize / 2) then
         map[x][y].x = map[x][y].x + (tileSize * mapWidth)
      end
      if map[x][y].x > mapX + (mapWidth * tileSize) - (tileSize / 2) then
         map[x][y].x = map[x][y].x - (tileSize * mapWidth)
      end
      
      --Y
      if map[x][y].y < mapY - (tileSize / 2) then
         map[x][y].y = map[x][y].y + (tileSize * mapHeight)
      end
      if map[x][y].y > mapY + (mapHeight * tileSize) - (tileSize / 2) then
         map[x][y].y = map[x][y].y - (tileSize * mapHeight)
      end
    end
  end
  updateTilesetBatch()
end

return themap, tilesetBatch
I make games that run on potatoes :P
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth »

lol - This time I'm out of that league. I can only help with the map-loading part. I think it's better that you create another thread concerning the Camera. You're on the right track anyway.

Happy coding!
User avatar
bobbymcbobface
Citizen
Posts: 78
Joined: Tue Jun 04, 2019 8:31 pm

Re: Custom map loading technique

Post by bobbymcbobface »

sphyrth wrote: Sun Jul 14, 2019 12:02 pm lol - This time I'm out of that league. I can only help with the map-loading part. I think it's better that you create another thread concerning the Camera. You're on the right track anyway.

Happy coding!
Well thankyou for the help 😀

edit: thankyou everyone for the help I'm creating a new post concerning camera setup for a topdown game i may come back to here later for more help but thanks for now :)

edit: here's the link to the new topic if anyone wants to see it https://love2d.org/forums/viewtopic.php?f=3&t=86895

edit: I'm back again! ok the newest problem is my 3rd function is not being called:

tilequad(a:0, B:0, c:98) --grass
tilequad(a:0, B:2, c:1) --rocks
tilequad(a:0, B:3, c:1) --trees

(note: a:, B:, c: are not in the actual code so need to be removed when in use)

and so i only end up with grass and rocks and also is there an equation to to add up all of C: and see it adds up to 100 since this would help with debugging a TON

also here's the tilequad() code:

Code: Select all

function tilequad(a, b, c)
   local start = #tileQuads + 1 -- The #<tablename> (in this case, the tablename is tileQuads) counts the number of max tiles.
                                           -- the +1 means we'll start at the number NEXT to the last tile.
                                           -- This means we won't override anything before the table.
   for i = start, start + count do
      tileQuads[i] = love.graphics.newQuad(x * tileSize, y * tileSize, tileSize, tileSize,
      tilesetImage:getWidth(), tilesetImage:getHeight())
   end
end
what's more is the values seem to be scewed and by scewed i mean that although my random.int is set to 1, 100 and normally throws an error if C: doesn't add up to 100 it now doesn't even recognize any errors and this seems to work fine

Code: Select all

tilequad(0, 0, 96)   --grass
tilequad(0, 2, 1)    --rocks
tilequad(0, 3, 1) 
the random.int code i was talking about:

Code: Select all

function setupMap()
  -- We only need a tiny map for this example
  mapWidth = 60
  mapHeight = 60
  
  --Leaving a space on the right and topsides so we know if the tiles are being "deleted"
  mapX = -20
  mapY = -20
  map = {}
  for x=0, mapWidth do
    map[x] = {}
    for y=0, mapHeight do
      map[x][y] = { --Let's turn this into a table that stores 3 things:
        tile = love.math.random(1, 101),                <------- here's the random.int bit 
        x = x * tileSize,
        y = y * tileSize
      }
    end
  end
end
I make games that run on potatoes :P
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth »

Remember #tileQuads? That counts how many tiles you have. That means you don't have to manually set the 2nd argument of random to that:

Code: Select all

tile = love.math.random(1, #tileQuads) -- or tile = love.math.random(#tileQuads) since the default min is "1"
This way, you don't have to count how many tiles you have since #tileQuads does it for you.
User avatar
bobbymcbobface
Citizen
Posts: 78
Joined: Tue Jun 04, 2019 8:31 pm

Re: Custom map loading technique

Post by bobbymcbobface »

I should of seen that sorry :roll: :P

ok after testing your code it seems now that not even the second function is called and no matter how much i increase the count on the others it doesn't seem to change one bit?
I make games that run on potatoes :P
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth »

That's odd. May I see the main.lua?
User avatar
bobbymcbobface
Citizen
Posts: 78
Joined: Tue Jun 04, 2019 8:31 pm

Re: Custom map loading technique

Post by bobbymcbobface »

I can't supply it at the moment but the only code in main.lua is my load functions update functions and draw functions
I make games that run on potatoes :P
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth »

I just re-checked your tilequad code:
Change

Code: Select all

function tilequad(a, b, c)
   ...
end
To

Code: Select all

function tilequad(x, y, count)
   ...
end
The variables inside that function are dependent on those names. Otherwise (if you still want a, b, c instead of x, y, count) you have to change the variable names inside that function accordingly.
User avatar
bobbymcbobface
Citizen
Posts: 78
Joined: Tue Jun 04, 2019 8:31 pm

Re: Custom map loading technique

Post by bobbymcbobface »

sphyrth wrote: Thu Jul 18, 2019 10:31 am I just re-checked your tilequad code:
Change

Code: Select all

function tilequad(a, b, c)
   ...
end
To

Code: Select all

function tilequad(x, y, count)
   ...
end
The variables inside that function are dependent on those names. Otherwise (if you still want a, b, c instead of x, y, count) you have to change the variable names inside that function accordingly.
i tried changing this and it seems to have no effect :P

what's more i tried returning the variables after the function and still nothing changes

Also if I change the tilequad command to rocks it just generates the whole map as rocks and ignores the rest

edit: ok after alot of testing around i seem to have have a hint to whats causing my problem

Code: Select all

function setupMap()
  -- We only need a tiny map for this example
  mapWidth = 60
  mapHeight = 60
  
  --Leaving a space on the right and topsides so we know if the tiles are being "deleted"
  mapX = -20
  mapY = -20
  map = {}
  for x=0, mapWidth do
    map[x] = {}
    for y=0, mapHeight do
      map[x][y] = { --Let's turn this into a table that stores 3 things:
        tile = love.math.random(#tilequads), --it's this bit specifically
        x = x * tileSize,
        y = y * tileSize
      }
    end
  end
end


so this part of the code - tile = love.math.random(#tilequads) - is causing the problem whereas if i change it to - tile = love.math.random(1, 3) - it seems to start to vary the map but rocks have an increased percentage for some reason so i tried changing the count on the other 2 to 100 and then again it only calls the rocks due to the count not adding up to 3 so I'm completely stuck on how i could solve this please can someone help?

also dunno if this helps solve the problem but #tilequads seems to have no change in value since it's always calling rocks when i put it in the tile command (tile = love.math.random(#tilequads)) instead of 1,3

edit again: this might help dunno but at the start of the game #tilequads returns a steady 0 but after updateTilesetBatch()
it returns 6
I make games that run on potatoes :P
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth »

It's been awhile since I last checked up on this, so I would ask you to show the whole code. As I remember it, the code I gave you was a twisted mess... because I have to look all over the functions as to what the code was doing in order... specifically:
1. Are the tilequads being added first? or are we defining the map first?
2. If we define the map first, doesn't that mean we have no tilequad definitions (rocks, trees, ground, etc) to check up on?
3. Since map definition different from map generation when should I define the tilequads?
Post Reply

Who is online

Users browsing this forum: No registered users and 52 guests