hi i am trying to create a game of Sokoban,
but I can not make the collide with other blokes.
eg
block 1 >= block2 == collide.
screenshot
code
help with creating a game sokoban - (solved)
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- luislasonbra
- Citizen
- Posts: 60
- Joined: Sun Jun 24, 2012 1:57 pm
help with creating a game sokoban - (solved)
Last edited by luislasonbra on Mon Aug 26, 2013 4:09 pm, edited 1 time in total.
Re: help with creating a game sokoban
Before I come to your specific problem, one general remark:
You can simplify you code a lot. First of all, all boxes have the size of a grid cell, so there is no real need to store width and height of the boxes. The same goes for the player itself. Second, you don't need the generic AABB-Collision check, since you know that all boxes and the player are grid aligned. Third, I very much suggest you store the player's and all other coordinates in grid coordinates, not in screen coordinates (that means e.g. (2,1) instead of (64,32)). Then you can save the math.floor(player.y/32)-part and just use player.y. Only the drawing then needs to know the grid size so for the drawing you write or even better and you can change dx later, if you decide you want to zoom in more.
Now for the box-box collision: I suggest you put your boxes into the map-array(table) itsself. Your code would then look like this:
I put a 2 for each box.
That way checking should be easy: If the player presses a button, then first check if the new cell is empty. If so-> no problem. Otherwise, if there is a 2 in the cell, check the next cell (the one behind the new cell). If this is empty, then move both player and the box otherwise, don't move.
By the way, I suggest you do not split the movement code into both love.keypressed and love.update. Everything of the collision detection, including the boxes, should be done in the love.keypressed.
You can simplify you code a lot. First of all, all boxes have the size of a grid cell, so there is no real need to store width and height of the boxes. The same goes for the player itself. Second, you don't need the generic AABB-Collision check, since you know that all boxes and the player are grid aligned. Third, I very much suggest you store the player's and all other coordinates in grid coordinates, not in screen coordinates (that means e.g. (2,1) instead of (64,32)). Then you can save the math.floor(player.y/32)-part and just use player.y. Only the drawing then needs to know the grid size so for the drawing you write
Code: Select all
love.graphics.rectangle(player.x*32,player.y*32,32,32)
Code: Select all
love.graphics.rectangle(player.x*dx,player.y*dx,dx,dx)
Now for the box-box collision: I suggest you put your boxes into the map-array(table) itsself. Your code would then look like this:
Code: Select all
map = {
{1, 1, 1, 1},
{1, 0, 0, 1},
{1, 0, 0, 1, 1, 1},
{1, 2, 0, 0, 0, 1},
{1, 0, 0, 2, 0, 1},
{1, 0, 0, 1, 1, 1},
{1, 1, 1, 1},
}
That way checking should be easy: If the player presses a button, then first check if the new cell is empty. If so-> no problem. Otherwise, if there is a 2 in the cell, check the next cell (the one behind the new cell). If this is empty, then move both player and the box otherwise, don't move.
By the way, I suggest you do not split the movement code into both love.keypressed and love.update. Everything of the collision detection, including the boxes, should be done in the love.keypressed.
Check out my blog on gamedev
- luislasonbra
- Citizen
- Posts: 60
- Joined: Sun Jun 24, 2012 1:57 pm
Re: help with creating a game sokoban
micha wrote:Before I come to your specific problem, one general remark:
You can simplify you code a lot. First of all, all boxes have the size of a grid cell, so there is no real need to store width and height of the boxes. The same goes for the player itself. Second, you don't need the generic AABB-Collision check, since you know that all boxes and the player are grid aligned. Third, I very much suggest you store the player's and all other coordinates in grid coordinates, not in screen coordinates (that means e.g. (2,1) instead of (64,32)). Then you can save the math.floor(player.y/32)-part and just use player.y. Only the drawing then needs to know the grid size so for the drawing you writeor even betterCode: Select all
love.graphics.rectangle(player.x*32,player.y*32,32,32)
and you can change dx later, if you decide you want to zoom in more.Code: Select all
love.graphics.rectangle(player.x*dx,player.y*dx,dx,dx)
Now for the box-box collision: I suggest you put your boxes into the map-array(table) itsself. Your code would then look like this:I put a 2 for each box.Code: Select all
map = { {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1, 1, 1}, {1, 2, 0, 0, 0, 1}, {1, 0, 0, 2, 0, 1}, {1, 0, 0, 1, 1, 1}, {1, 1, 1, 1}, }
That way checking should be easy: If the player presses a button, then first check if the new cell is empty. If so-> no problem. Otherwise, if there is a 2 in the cell, check the next cell (the one behind the new cell). If this is empty, then move both player and the box otherwise, don't move.
By the way, I suggest you do not split the movement code into both love.keypressed and love.update. Everything of the collision detection, including the boxes, should be done in the love.keypressed.
hi sorry for the delay in my response.
thanks for your help achieve make colipciones call in total, plus the code is now cleaner
here I leave the code in case anyone is interested.
Code: Select all
function love.load()
map = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 3, 1},
{1, 0, 2, 0, 0, 0, 2, 0, 3, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 3, 1},
{1, 0, 2, 0, 0, 0, 2, 0, 3, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
}
texto = ""
ShearTileMap()
totalBlockAcert = 0
isGameFinish = ""
player = {}
player.x = 2
player.y = 2
end
function love.update(dt)
if totalBlockAcert == 4 then
isGameFinish = "Juego terminado."
end
end
function love.keypressed(key)
if key == "up" then
if IsPlayerMove(player.x, player.y - 1, "up") and MoveBox(player.x, player.y - 1, "up") then
player.y = player.y - 1
end
elseif key == "down" then
if IsPlayerMove(player.x, player.y + 1, "down") and MoveBox(player.x, player.y + 1, "down") then
player.y = player.y + 1
end
elseif key == "left" then
if IsPlayerMove(player.x - 1, player.y, "left") and MoveBox(player.x - 1, player.y, "left") then
player.x = player.x - 1
end
elseif key == "right" then
if IsPlayerMove(player.x + 1, player.y, "right") and MoveBox(player.x + 1, player.y, "right") then
player.x = player.x + 1
end
end
end
function love.draw()
DrawMap()
PlayerDraw()
love.graphics.print(texto, 400, 32)
love.graphics.print("Blokes Colocados: " .. totalBlockAcert, 0, 0)
love.graphics.print("GameState: " .. isGameFinish, 150, 0)
end
local count = 0
function ShearTileMap()
texto = ""
count = 0
for y = 1, #map do
for x = 1, #map[y] do
if count == #map then texto = texto .. "\n"; count = 0 end
if count < #map - 1 then texto = texto .. map[y][x] .. ", " else texto = texto .. map[y][x] end
count = count + 1
end
end
end
function DrawMap()
for y = 1, #map do
for x = 1, #map[y] do
if map[y][x] == 1 then love.graphics.rectangle("line", x * 32, y * 32, 32, 32) end
love.graphics.setColor(255, 0, 0)
if map[y][x] == 2 then love.graphics.rectangle("line", x * 32, y * 32, 32, 32) end
love.graphics.setColor(255, 255, 255)
love.graphics.setColor(88, 90, 234)
if map[y][x] == 3 then love.graphics.rectangle("line", x * 32, y * 32, 32, 32) end
love.graphics.setColor(255, 255, 255)
love.graphics.setColor(0, 195, 254)
if map[y][x] == 4 then love.graphics.rectangle("line", x * 32, y * 32, 32, 32) end
love.graphics.setColor(255, 255, 255)
end
end
end
function PlayerDraw()
love.graphics.rectangle("fill", player.x * 32, player.y * 32, 32, 32)
end
function IsPlayerMove(ax, ay, direct)
if direct == "up" then
if map[ay][ax] == 1 then return false end
elseif direct == "down" then
if map[ay][ax] == 1 then return false end
elseif direct == "left" then
if map[ay][ax] == 1 then return false end
elseif direct == "right" then
if map[ay][ax] == 1 then return false end
end
return true
end
function CheckFinishBlock()
totalBlockAcert = 0
for y = 1, #map do
for x = 1, #map[y] do
if map[y][x] == 4 and totalBlockAcert <= 3 then
totalBlockAcert = totalBlockAcert + 1
end
end
end
end
-- Function para saber si hay collipcion entre las cajas....
function MoveBox(ax, ay, direct)
if direct == "up" then
if map[ay][ax] == 2 or map[ay][ax] == 4 then
if (map[ay-1][ax] == 4) or (map[ay-1][ax] == 2) or (map[ay-1][ax] == 1) then return false end
if map[ay-1][ax] == 3 then map[ay-1][ax] = 4 else map[ay-1][ax] = 2 end
if map[ay][ax] == 4 then map[ay][ax] = 3 else map[ay][ax] = 0 end
ShearTileMap() -- Actualiza el texto que aparece al lado derecho.....
CheckFinishBlock()
return true
end
elseif direct == "down" then
if map[ay][ax] == 2 or map[ay][ax] == 4 then
if (map[ay+1][ax] == 4) or (map[ay+1][ax] == 2) or (map[ay+1][ax] == 1) then return false end
if map[ay+1][ax] == 3 then map[ay+1][ax] = 4 else map[ay+1][ax] = 2 end
if map[ay][ax] == 4 then map[ay][ax] = 3 else map[ay][ax] = 0 end
ShearTileMap() -- Actualiza el texto que aparece al lado derecho.....
CheckFinishBlock()
return true
end
elseif direct == "left" then
if map[ay][ax] == 2 or map[ay][ax] == 4 then
if (map[ay][ax-1] == 4) or (map[ay][ax-1] == 2) or (map[ay][ax-1] == 1) then return false end
if map[ay][ax-1] == 3 then map[ay][ax-1] = 4 else map[ay][ax-1] = 2 end
if map[ay][ax] == 4 then map[ay][ax] = 3 else map[ay][ax] = 0 end
ShearTileMap() -- Actualiza el texto que aparece al lado derecho.....
CheckFinishBlock()
return true
end
elseif direct == "right" then
if map[ay][ax] == 2 or map[ay][ax] == 4 then
if (map[ay][ax+1] == 4) or (map[ay][ax+1] == 2) or (map[ay][ax+1] == 1) then return false end
if map[ay][ax+1] == 3 then map[ay][ax+1] = 4 else map[ay][ax+1] = 2 end
if map[ay][ax] == 4 then map[ay][ax] = 3 else map[ay][ax] = 0 end
ShearTileMap() -- Actualiza el texto que aparece al lado derecho.....
CheckFinishBlock()
return true
end
end
return true
end
- Ranguna259
- Party member
- Posts: 911
- Joined: Tue Jun 18, 2013 10:58 pm
- Location: I'm right next to you
Re: help with creating a game sokoban - (solved)
Are you Portuguese or Spanish ?
- luislasonbra
- Citizen
- Posts: 60
- Joined: Sun Jun 24, 2012 1:57 pm
Re: help with creating a game sokoban - (solved)
SpanishRanguna259 wrote:Are you Portuguese or Spanish ?
- Ranguna259
- Party member
- Posts: 911
- Joined: Tue Jun 18, 2013 10:58 pm
- Location: I'm right next to you
Re: help with creating a game sokoban - (solved)
Welcome to the forum
- luislasonbra
- Citizen
- Posts: 60
- Joined: Sun Jun 24, 2012 1:57 pm
Re: help with creating a game sokoban - (solved)
ThanksRanguna259 wrote:Welcome to the forum
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 4 guests