Page 1 of 1
Can anyone help me with simple Tile Collisons?
Posted: Sat Jun 08, 2013 2:52 pm
by Deltise
I have no idea how to approach this problem, except trying to assign certain tiles to be collideable and other tiles as not, I've seen many solutions but found them difficult to integrate into my code without breaking my brain. My code uses ASCII maps to create it's levels, and the Arrow Keys to move the player, as of now there are no collisions, and the player is free to float around whimsically. Can anyone please aid in helping me with code to create tile collisions for the darker walls around the level, and after that I could probably figure out the rest for other tiles.
(Oh yeah, I also don't have camera scrolling yet, so much of the map will be off of the 300 x 300 window, I'll mess with scaling later and cameras later)
The game has a rather simple main menu, with 'esc' allowing you to return to the main menu from the game.
The zip is below. Thanks ahead of time for your help.
Re: Can anyone help me with simple Tile Collisons?
Posted: Sat Jun 08, 2013 4:23 pm
by Joemag
Before you change the position of the player you should save the new position in an other variable:
Code: Select all
function playerMove(dt)
local newx, newy = player.x, player.y
if love.keyboard.isDown("right") then
newx = newx + player.speed * dt
end
if love.keyboard.isDown("left") then
newx = newx - player.speed * dt
end
if love.keyboard.isDown("up") then
newy = newy - player.speed * dt
end
if love.keyboard.isDown("down") then
newy = newy + player.speed * dt
end
end
Next check if the player can be at the new position.
This returns the block which is at the new position of the left top corner:
Code: Select all
TileTable[ math.floor( newx / TileW ) + 1 ][ math.floor( newy / TileH ) + 1 ]
You should check all four corners of the player and change the x and y positions separately:
Code: Select all
player.height = 19
player.width = 19
collideTiles = {
b = true,
x = true
}
function collision(newx, newy)
if collideTiles[ TileTable[ math.floor( newx / TileW ) + 1 ][ math.floor( newy / TileH ) + 1 ] ] or
collideTiles[ TileTable[ math.floor( (newx + player.width) / TileW ) + 1 ][ math.floor( newy / TileH ) + 1 ] ] or
collideTiles[ TileTable[ math.floor( newx / TileW ) + 1 ][ math.floor( (newy + player.height) / TileH ) + 1 ] ] o
collideTiles[TileTable[math.floor((newx + player.width) / TileW)+ 1][math.floor((newy + player.height)/TileH)+ 1]] then
return true
end
return false
end
function playerMove(dt)
local newx, newy = player.x, player.y
if love.keyboard.isDown("right") then
newx = newx + player.speed * dt
end
if love.keyboard.isDown("left") then
newx = newx - player.speed * dt
end
if love.keyboard.isDown("up") then
newy = newy - player.speed * dt
end
if love.keyboard.isDown("down") then
newy = newy + player.speed * dt
end
if not collision(newx, player.y) then
player.x = newx
end
if not collision(player.x, newy) then
player.y = newy
end
end
Re: Can anyone help me with simple Tile Collisons?
Posted: Sat Jun 08, 2013 9:28 pm
by Deltise
Joemag wrote:
This is all great, but quick question, which part of the code dictates which tiles the player can walk on, and which tiles the player runs into?
Re: Can anyone help me with simple Tile Collisons?
Posted: Sat Jun 08, 2013 9:33 pm
by Robin
Deltise wrote:This is all great, but quick question, which part of the code dictates which tiles the player can walk on, and which tiles the player runs into?
Code: Select all
collideTiles = {
b = true,
x = true
}
Re: Can anyone help me with simple Tile Collisons?
Posted: Sun Jun 09, 2013 3:05 am
by Deltise
Robin wrote:Deltise wrote:This is all great, but quick question, which part of the code dictates which tiles the player can walk on, and which tiles the player runs into?
Code: Select all
collideTiles = {
b = true,
x = true
}
I feel a bit silly actually
Thank you
Re: Can anyone help me with simple Tile Collisons?
Posted: Sun Jun 09, 2013 10:06 am
by MadByte
I don't want to create a new topic for this:
I'm also trying to apply collision, but I use a img to load my map and got this so far:
Code: Select all
function player:move(dt)
local newx, newy = player.x, player.y
if left and not right then
newx = newx - self.xVel * dt
if not collision(newx, player.y) then
player.x = newx
end
elseif right and not left then
newx = newx + self.xVel * dt
if not collision(newx + player.w, player.y) then
player.x = newx
end
end
end
function collision( xval, yval )
local x = math.floor( xval/tileSize )
local y = math.floor( yval/tileSize )
if x >= 0 and x < getWidth() and y >= 0 and y <= getHeight() then
local r, g, b, a = mapdata:getPixel( x, y )
if compare( {r,g,b,a}, {255,0,0,255} ) then -- Collidable tile
return true
end
return false
end
end
It kinda works but I'm still struggling with the tile width & tile height a bit. the player still goes through the first tile in a raw.
Here you can test what I mean:
tileCollision.love
Any ideas ? :/
Re: Can anyone help me with simple Tile Collisons?
Posted: Sun Jun 09, 2013 6:10 pm
by Joemag
MadByte wrote:I don't want to create a new topic for this:
I'm also trying to apply collision, but I use a img to load my map and got this so far:
Code: Select all
function player:move(dt)
local newx, newy = player.x, player.y
if left and not right then
newx = newx - self.xVel * dt
if not collision(newx, player.y) then
player.x = newx
end
elseif right and not left then
newx = newx + self.xVel * dt
if not collision(newx + player.w, player.y) then
player.x = newx
end
end
end
function collision( xval, yval )
local x = math.floor( xval/tileSize )
local y = math.floor( yval/tileSize )
if x >= 0 and x < getWidth() and y >= 0 and y <= getHeight() then
local r, g, b, a = mapdata:getPixel( x, y )
if compare( {r,g,b,a}, {255,0,0,255} ) then -- Collidable tile
return true
end
return false
end
end
It kinda works but I'm still struggling with the tile width & tile height a bit. the player still goes through the first tile in a raw.
Here you can test what I mean:
tileCollision.love
Any ideas ? :/
When you go down, it checks only if the bottom-left corner of the player collides.
Code: Select all
collision(player.x, newy + player.h)
The same problem is in the other directions.
You have to check also the bottom-right corner. And a point between that, because the player is bigger than the tiles.
Re: Can anyone help me with simple Tile Collisons?
Posted: Sun Jun 09, 2013 6:27 pm
by MadByte
hm I didn't updated the post,
in the .love I included above I tried this :
Code: Select all
-- Move the player
if left and not right then
newx = newx - self.xVel * dt
if not collision(newx, player.y) then
player.x = newx
end
elseif right and not left then
newx = newx + self.xVel * dt
if not collision(newx + player.w, player.y) then
player.x = newx
end
end
if up and not down then
newy = newy - self.xVel * dt
if not collision(player.x, newy) then
player.y = newy
end
elseif down and not up then
newy = self.y + self.xVel * dt
if not collision(player.x, newy + player.h) then
player.y = newy
end
end
But there still seems to be a problem with it.
Thanks for the reply!
edit:
Now I understand what you said!
... it works now, thanks!
(bit ugly but ... yeah :/ )
Code: Select all
-- Move the player
if left and not right then
newx = newx - self.xVel * dt
if not collision(newx, player.y)
and not collision( newx, player.y + player.h )
and not collision( newx, player.y + (player.h / 2) ) then
player.x = newx
end
elseif right and not left then
newx = newx + self.xVel * dt
if not collision(newx + player.w, player.y)
and not collision( newx + player.w, player.y + player.h )
and not collision( newx + player.w, player.y + (player.h / 2) ) then
player.x = newx
end
end
if up and not down then
newy = newy - self.xVel * dt
if not collision(player.x, newy)
and not collision(player.x + player.w , newy)
and not collision(player.x + (player.w / 2) , newy) then
player.y = newy
end
elseif down and not up then
newy = self.y + self.xVel * dt
if not collision(player.x, newy + player.h)
and not collision(player.x + player.w , newy + player.h)
and not collision(player.x + (player.w / 2) , newy + player.h) then
player.y = newy
end
end