## [SOLVED] Tiled collision maps help

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.
DudeJonte
Prole
Posts: 4
Joined: Sun Oct 20, 2019 1:14 pm

### [SOLVED] Tiled collision maps help

Hello dear forum users. Please have mercy on my soul if you dare to help me, as I am new to both Lua and Love2d. I am currently working on a top-down rpg zelda clone-ish. I will try to only show relevant pieces of code so you don't have to look at all of it

Importing the map is done via STI. It imports a tilemap done in Tiled. Very simple right? Which is then being updated and drawn to the screen.

Code: Select all

function love.load()
map = sti("assets/maps/testmapbig.lua", {"box2d"})
end

function love.update(dt)
map:update(dt)
end

function love.draw()
map:draw(-dx, -dy, mapScale, mapScale)
end

Now, the player is being created, updated and drawn in it's own seperate class "player.lua" which looks like this...

Code: Select all

player = {}
player.width = 16
player.height = 23
player.ismoving = false

player.collider = world:newCircleCollider(width/2, height/2, 15)

--Creates a grid table and places spreadsheet into it
player.grids = {}
player.grids.walk = anim8.newGrid(player.width, player.height, sprites.linkSpriteSheet:getDimensions())

--Creates animations out of these grids
player.animations = {}
player.animations.walkDown = anim8.newAnimation(player.grids.walk('1-8', 1), 0.1)
player.animations.walkUp = anim8.newAnimation(player.grids.walk('1-8', 2), 0.1)
player.animations.walkRight = anim8.newAnimation(player.grids.walk('1-8', 3), 0.1)
player.animations.walkLeft = anim8.newAnimation(player.grids.walk('1-8', 4), 0.1)

--Stores players current animation
player.anim = player.animations.walkDown

function player:update(dt)

--Freeze animation if player isn't moving
if player.isMoving then
player.anim:update(dt)
end

local vectorX = 0
local vectorY = 0

playerX = player.collider:getX()
playerY = player.collider:getY()

--Keyboard direction checks for movement and changes animation
if love.keyboard.isDown("a", "left") then
vectorX = -1
player.anim = player.animations.walkLeft
end

if love.keyboard.isDown("d", "right") then
vectorX = 1
player.anim = player.animations.walkRight
end

if love.keyboard.isDown("w", "up") then
vectorY = -1
player.anim = player.animations.walkUp
end

if love.keyboard.isDown("s", "down") then
vectorY = 1
player.anim = player.animations.walkDown
end

player.collider:setLinearVelocity(vectorX * 100, vectorY* 100)
--Checks if player is moving
--(if players previous position if different from current position)
if vectorX == 0 and vectorY == 0 then
player.isMoving = false
player.anim:gotoFrame(1) -- Go to standing frame in current grid
else
player.isMoving = true
end
end

function player:draw()
local px = player.collider:getX()
local py = player.collider:getY()

--Sets stylesheet filter so scaling doesn't blur

--Draws current animation frame
player.anim:draw(sprites.linkSpriteSheet, px, py, nil, 2, 2, player.width/2, player.height/1.3)
end

Here I am using anim8 to animate the character, and windfield to create a collision box for the player which follows him wherever he goes. Everything so far works just as I want, producing this result if I choose to draw the collision boxes...

The problem comes when I try to implement collisionboxes for my map. The way I've figured out to do this is to loop through every object in my map.lua file an retrieve it's x and y cords. Then the loop also creates a new collision rectangle at those specific coordinates.

Code: Select all

function love.load()
--Gets number of tables(objects) in currently loaded map
colliderLayer = map.layers[2].objects
--Loops through all objects and gets their respective x, y values
--this then creates a new collider rectangle at respective coordinates
for i, v in pairs(colliderLayer) do
local colliderObjectX = map.layers[2].objects[i].x
local colliderObjectY = map.layers[2].objects[i].y
colliderBox = world:newRectangleCollider(
(colliderObjectX*2+6), --Multiplies current cordinate by 2 too make up for map scaling in draw()
(colliderObjectY*2-28), --then adds specific numbers to allign them just perfect
20,
25)
colliderBox:setType('static')
end
end

This works absolutely fine. The rectangles are placed where I want them to and the player collides with them just fine. The problem arose when I wanted to implement some kind of camera that follows the player around as he moved, scrolling the map accordingly. After testing library after library with my limited understanding for anything I came to this solution, which needed no library whatsoever

Code: Select all

function love.draw()

dx = player.collider:getX() - (love.graphics.getWidth()/2)
dy = player.collider:getY() - (love.graphics.getHeight()/2)

love.graphics.scale(scale)
love.graphics.translate(-dx, -dy)
--Scales map to double size to fit screen
--Draws map and sets new scale
map:draw(-dx, -dy, mapScale, mapScale)
player:draw()
world:draw()
end

This achieves-ish what I want, as now when the player moves, the map does aswell, revealing the rest of the map depending on where you go. NOW, if you are still reading this, MY MAIN PROBLEM that I have been trying to fix for days now is to move my collision map along with my main map.lua. Which will not work the way I want. For some reason I can't post images in here so I will reply to my own post which the needed attachments and source code. Any help would be highly appreciated as I am slowly losing hope for this project.
Last edited by DudeJonte on Mon Oct 21, 2019 7:12 pm, edited 1 time in total.

pgimeno
Party member
Posts: 1943
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: Tiled collision maps help

Hello, welcome to the forums.

Edit: Scratched the request for code because I didn't read all the way to the end, sorry. I await the rest of the code, as I can't make heads or tails from what you've posted so far.

DudeJonte
Prole
Posts: 4
Joined: Sun Oct 20, 2019 1:14 pm

### Re: Tiled collision maps help

Here I have attached the entire project file plus some images that were supposed to go into the post above. Have a look and don't hesitate to ask if anything is unclear to you. I really appreciate any help
Attachments
2D RPG MAYBE.rar

pgimeno
Party member
Posts: 1943
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: Tiled collision maps help

OK, found the issue, thanks for attaching the project. The problem is that the coordinates that STI requires are map pixels, but you're passing screen pixels to it. Dividing the coordinates by mapScale does the trick:

Code: Select all

    map:draw(-dx/mapScale, -dy/mapScale, mapScale, mapScale)


DudeJonte
Prole
Posts: 4
Joined: Sun Oct 20, 2019 1:14 pm

### Re: Tiled collision maps help

pgimeno wrote:
Mon Oct 21, 2019 10:28 am
OK, found the issue, thanks for attaching the project. The problem is that the coordinates that STI requires are map pixels, but you're passing screen pixels to it. Dividing the coordinates by mapScale does the trick:

Code: Select all

    map:draw(-dx/mapScale, -dy/mapScale, mapScale, mapScale)

You my friend, are a lifesaver! This solved my problem. Thank you so much. May I ask one more thing just so I understand what I did wrong? What is the difference between the map pixels that STI requires and the screen pixels that I was passing in? Thank you once again for helping!

pgimeno
Party member
Posts: 1943
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: Tiled collision maps help

DudeJonte wrote:
Mon Oct 21, 2019 7:11 pm
What is the difference between the map pixels that STI requires and the screen pixels that I was passing in?
It's easy to understand the difference. You use a zoom factor of 2, so disregarding translation, each pixel on the map occupies 4 pixels on the screen, as follows:
• The map pixel at (0, 0) is drawn at screen pixels (0, 0), (1, 0), (0, 1) and (1, 1).
• The map pixel at (1, 0) is drawn at screen pixels (2, 0), (3, 0), (2, 1) and (3, 1).
• The map pixel at (2, 0) is drawn at screen pixels (4, 0), (5, 0), (4, 1) and (5, 1).
• ...
• The map pixel at (0, 1) is drawn at screen pixels (0, 2), (1, 2), (0, 3) and (1, 3).
• ...
• Profit! (kidding)
Your player coordinates are expressed in screen pixels, but STI requires map pixels, therefore you need to convert them, by dividing them by your scale factor, before sending them to STI's draw function.

By the way, this difference in coordinate systems could cause issues later if you're not careful.

DudeJonte
Prole
Posts: 4
Joined: Sun Oct 20, 2019 1:14 pm

### Re: Tiled collision maps help

pgimeno wrote:
Mon Oct 21, 2019 7:58 pm
DudeJonte wrote:
Mon Oct 21, 2019 7:11 pm
What is the difference between the map pixels that STI requires and the screen pixels that I was passing in?
Your player coordinates are expressed in screen pixels, but STI requires map pixels, therefore you need to convert them, by dividing them by your scale factor, before sending them to STI's draw function.

By the way, this difference in coordinate systems could cause issues later if you're not careful.
Thanks a lot for the explanation. And as you say, different coordinate systems have already been driving me a little crazy sometimes. I'm gonna try to figure out a solution for this at some point. But thank you once again for your help. Have a good one!

### Who is online

Users browsing this forum: No registered users and 6 guests