Tilemap drawing issues

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
CutePenguin
Prole
Posts: 20
Joined: Sat Dec 21, 2024 7:35 am

Tilemap drawing issues

Post by CutePenguin »

I am making a simple prototype for the LÖVE jam and i seem to have ran into some issues. I was updating the tileset image and all the sudden my tilemap drawing stoped working. i do have a bad habit of not making variables for things and just hard coding it and making new tile quads in love.draw().

the issue is that i am getting the wrong tile quads where a couple minutes later after the update for the tilesets, i was getting the wrong quads. my tile id's are zero based if you need to know.

main.lua:

Code: Select all

local csv = require ("libs/lua-csv/lua/csv")

function love.load ()
  love.graphics.setDefaultFilter ("nearest", "nearest")
  love.window.setMode (672, 672)
  
  _G.tileset_image = love.graphics.newImage("assets/tileset.png")
  
  _G.tilemap = {}
  tilemap.layers = {}
  tilemap.layers.bg, tilemap.layers.fg, tilemap.layers.wires = loadTilemapLayer (1)
  
  for y = 1, #tilemap.layers.wires do
    local row_str = ""
    for x = 1, #tilemap.layers.wires[1] do
      row_str = row_str .. tostring(tilemap.layers.wires[y][x]) .. " "
    end
    print(row_str)
  end
  
  tilemap.wire_data = {}
  tilemap.wire_data.enum = {
    START = 6,
    ON_WIRE = 1,
    OFF_WIRE = 0,
    VERT_SWITCH = 9,
    HOR_SWITCH = 10,
    ON_HOUSE = 5,
    OFF_HOUSE = 4
  }
  
  _G.timer = {}
  timer.maxTime = 1.25
  timer.time = timer.maxTime
  timer.isActive = false
  
  bfs(tilemap.layers.wires)
end

function love.update (dt)
  if timer.isActive then
    timer.time = timer.time - dt
  end
  
  if timer.time <= 0 then
    timer.isActive = false
    timer.time = timer.maxTime
    --tilemap.layers.bg, tilemap.layers.fg, tilemap.layers.wires = loadTilemapLayer (2)
    bfs(tilemap.layers.wires)
  end
end

function love.draw ()
  drawTilemapLayer(tilemap.layers.bg)
  drawTilemapLayer(tilemap.layers.fg)
  drawTilemapLayer(tilemap.layers.wires)
end

function love.mousepressed (x, y, button, istouch, presses)
  if button == 1 and (not timer.isActive) then
    local mouse_tile_x = (math.floor(love.mouse.getX() / 48)) + 1
    local mouse_tile_y = (math.floor(love.mouse.getY() / 48)) + 1
    print(mouse_tile_x .. ", " .. mouse_tile_y .. "Tile ID" .. tilemap.layers.wires[mouse_tile_y][mouse_tile_x])
    if tilemap.layers.wires[mouse_tile_y][mouse_tile_x] == tilemap.wire_data.enum["HOR_SWITCH"] then
      tilemap.layers.wires[mouse_tile_y][mouse_tile_x] = tilemap.wire_data.enum["VERT_SWITCH"]
      bfs(tilemap.layers.wires)
    elseif tilemap.layers.wires[mouse_tile_y][mouse_tile_x] == tilemap.wire_data.enum["HOR_SWITCH"] then
      tilemap.layers.wires[mouse_tile_y][mouse_tile_x] = tilemap.wire_data.enum["VERT_SWITCH"]
      bfs(tilemap.layers.wires)
    end
    
    local off_house_found = false
    for y = 1, #tilemap.layers.wires do
      for x = 1, #tilemap.layers.wires[1] do
        if tilemap.layers.wires[y][x] == tilemap.wire_data.enum["OFF_HOUSE"] then
          off_house_found = true
        end
      end
    end -- 7, 
    if not off_house_found then
      timer.isActive = true
    end
  end
end

function loadTilemapLayer (levelnum)
  local map_file_bg_l = csv.open("maps/level" .. tostring(levelnum) .. "_bg.csv")
  local map_file_fg_l = csv.open("maps/level" .. tostring(levelnum) .. "_fg.csv")
  local map_file_wires_l = csv.open("maps/level" .. tostring(levelnum) .. "_wires.csv")
  
  local map_data_bg_l = {}
  local map_data_fg_l = {}
  local map_data_wires_l = {}
  
  for row in  map_file_bg_l:lines() do
    local row_data = {}
    for i, value in ipairs(row) do
      row_data[i] = tonumber(value)
    end
    table.insert(map_data_bg_l, row_data)
  end
  
  for row in  map_file_fg_l:lines() do
    local row_data = {}
    for i, value in ipairs(row) do
      row_data[i] = tonumber(value)
    end
    table.insert(map_data_fg_l, row_data)
  end
  
  for row in  map_file_wires_l:lines() do
    local row_data = {}
    for i, value in ipairs(row) do
      row_data[i] = tonumber(value)
    end
    table.insert(map_data_wires_l, row_data)
  end
  
  return map_data_bg_l, map_data_fg_l, map_data_wires_l
end

function drawTilemapLayer (map_data)
  for y=1, #map_data do
    for x=1, #map_data[1] do
      local tile_id = map_data[y][x]
      local tile_quad = love.graphics.newQuad(
        (tile_id % (tileset_image:getWidth() / 8)) * 8,
        math.floor(tile_id / (tileset_image:getWidth() / 8)) * 8,
        8,
        8,
        tileset_image:getWidth(),
        tileset_image:getHeight()
        )
      love.graphics.draw(tileset_image, tile_quad, (x-1)*8*6, (y-1)*8*6, nil, 6, 6)
    end
  end
end

function bfs(gridd)
  local grid = gridd
  local queue = {}
  local visited = {}
  local start_pos = {}
  start_pos.x = -1
  start_pos.y = -1
  
  local direction_tbl = {
    left = {x = -1, y = 0},
    right = {x = 1, y = 0},
    up = {x = 0, y = -1},
    down = {x = 0, y = 1}
  }
  
  for y = 1, #grid do
    for x = 1, #grid[1] do
      if grid[y][x] == tilemap.wire_data.enum["START"] then
        start_pos.x = x
        start_pos.y = y
        break
      end
    end
    if start_pos.x ~= -1 then
      break
    end
  end
  
  if start_pos == -1 then
    print("No Power Source Found...")
    return
  end
  
  visited[start_pos.y] = {}
  visited[start_pos.y][start_pos.x] = true
  table.insert(queue, start_pos)
  
  for y = 1, #grid do
    visited[y] = {}
    for x = 1, #grid[1] do
      visited[y][x] = false
    end
  end
  
  for y = 1, #grid do
    for x = 1, #grid[1] do
      if grid[y][x] == tilemap.wire_data.enum["ON_WIRE"] then
        grid[y][x] = tilemap.wire_data.enum["OFF_WIRE"]
      end
      if grid[y][x] == tilemap.wire_data.enum["ON_HOUSE"] then
        grid[y][x] = tilemap.wire_data.enum["OFF_HOUSE"]
      end
    end
  end

  while #queue > 0 do
    local current_pos = table.remove(queue, 1)

    if grid[current_pos.y][current_pos.x] == tilemap.wire_data.enum["OFF_WIRE"] then
      grid[current_pos.y][current_pos.x] = tilemap.wire_data.enum["ON_WIRE"]
    end
    
    for i, direction in pairs(direction_tbl) do
      local neighbor_pos = {
        x = current_pos.x + direction.x,
        y = current_pos.y + direction.y
      }
      if
      (not ((grid[current_pos.y][current_pos.x] == tilemap.wire_data.enum["VERT_SWITCH"]) and (i == "left" or i == "right"))) and
      (not ((grid[current_pos.y][current_pos.x] == tilemap.wire_data.enum["HOR_SWITCH"]) and (i == "up" or i == "down"))) then
        if neighbor_pos.x > 0 and neighbor_pos.x < 15 and neighbor_pos.y > 0 and neighbor_pos.y < 15 then
          if
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["OFF_WIRE"] or
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["ON_WIRE"] or
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["HOR_SWITCH"] or
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["VERT_SWITCH"] or
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["ON_HOUSE"] or
          grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["OFF_HOUSE"]
          then
            if not visited[neighbor_pos.y][neighbor_pos.x] then
              if not
              (grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["OFF_HOUSE"] or
              grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["OFF_HOUSE"]) then
                visited[neighbor_pos.y][neighbor_pos.x] = true
                table.insert(queue, neighbor_pos)
              else
                visited[neighbor_pos.y][neighbor_pos.x] = true
                if grid[neighbor_pos.y][neighbor_pos.x] == tilemap.wire_data.enum["OFF_HOUSE"] then
                  grid[neighbor_pos.y][neighbor_pos.x] = tilemap.wire_data.enum["ON_HOUSE"]
                end
              end
            end
          end
        end
      end
    end
  end
  tilemap.layers.wires = grid
end

help would be very helpful (hehe) so i can move on in my project :) :)
User avatar
pgimeno
Party member
Posts: 3709
Joined: Sun Oct 18, 2015 2:58 pm

Re: Tilemap drawing issues

Post by pgimeno »

I tried, but stumbled on some errors when I attempted to make up some assets in order to run and debug it. If you can provide a fully runnable program with just enough assets as for it to run (the assets can be just placeholders, they don't need to be your original assets), that would help me help you.
CutePenguin
Prole
Posts: 20
Joined: Sat Dec 21, 2024 7:35 am

Re: Tilemap drawing issues

Post by CutePenguin »

I might have found the issue. in the drawTilemapLayer() function, i forgot to check if the tile was -1 (empty tile) before drawing. i should have posted that -1 was empty tile on my orignial post. :crazy:
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 3 guests