Page 2 of 3

Re: help with collisions

Posted: Sun Sep 08, 2019 10:01 pm
by pgimeno
bobbymcbobface wrote:
Sat Sep 07, 2019 6:31 am
EDIT: ok i managed to experiment with the code and so far i have this:

Code: Select all

[...]
      if collidable_chars['o'] then
[...]
Use instead:

Code: Select all

      if collidable_chars[character] then
That's the variable named character, which contains the current character from the map at that point. That will tell you if the current map position is collidable.

To sort out collisions, you still need to use the world:move() function to move the collidable entities. The entity has a current position, right? Well, given a destination position, that function will move your entity according to the collisions, e.g. in slide mode, it will slide without penetrating walls, etc. Check the docs.

Re: help with collisions

Posted: Wed Sep 11, 2019 7:47 pm
by bobbymcbobface
Thanks :D (again) I'll try that when I get the chance

edit: Thanks pgimeno that has completely solved my problem

edit again: ok nvm that! now there seems to be a weird drop in fps when colliding with things and moving either left or right while trying to collide with them - here's my code:

Code: Select all

local bump = require 'bump'
local cols_len = 0
local world = bump.newWorld()
local allowmove = false
local sprite = {}

local consoleBuffer = {}
local consoleBufferSize = 15
for i=1,consoleBufferSize do consoleBuffer[i] = "" end
local function consolePrint(msg)
  table.remove(consoleBuffer,1)
  consoleBuffer[consoleBufferSize] = msg
end

-- helper function
local function drawBox(box, r,g,b)
  love.graphics.setColor(r,g,b,70)
  love.graphics.rectangle("fill", box.x, box.y, box.w, box.h)
  love.graphics.setColor(r,g,b)
  love.graphics.rectangle("line", box.x, box.y, box.w, box.h)
  love.graphics.setColor(255,255,255,100)
end


local player = { x=50,y=50,w=20,h=20, speed = 80 }

local function updatePlayer(dt)
  local dx, dy = 0, 0
  local speed = player.speed
  --local goalX, goalY = player.x + dx * dt, player.y + dy * dt
  --local actualX, actualY, cols, len = world:move(player, goalX, goalY)
  player.x, player.y, cols, cols_len = world:move(player, player.x + dx, player.y + dy)
  --player.x, player.y = actualX, actualY
  
  --for i=1,len do
    --print('collided with ' .. tostring(cols[i].other))
  --end
  
  if love.keyboard.isDown('right') then
    dx = speed * dt
  elseif love.keyboard.isDown('left') then
    dx = -speed * dt
  end
  if love.keyboard.isDown('down') then
    dy = speed * dt
  elseif love.keyboard.isDown('up') then
    dy = -speed * dt
  end
  
  if dx ~= 0 or dy ~= 0 then
    player.x, player.y, cols, cols_len = world:move(player, player.x + dx, player.y + dy)
    --player.x, player.y = actualX, actualY
  end
end

local function drawPlayer()
  drawBox(player, 0, 255, 0)
end

-- Block functions

local blocks = {}

local function drawBlocks()
  for _,block in ipairs(blocks) do
    drawBox(block, 255,0,0)
  end
end

function sprite:load()
  world:add(player, player.x, player.y, player.w, player.h)
end

function sprite:update(dt)
  updatePlayer(dt)
end

function sprite:draw()
  drawPlayer()
end



function sprite:keypressed(k)
  if k=="escape" then love.event.quit() end
end

function sprite:add_collision(item, x, y, w ,h)
    world:add(item, x, y, w, h)
end

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

return sprite







---local sprite = {}
---local allowmove = false


---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"))
    
    
---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
            ---dx = dx - 1
            --player.x = player.x - 80 * dt
            --themap:moveMap(90  * dt, 0)
        ---elseif love.keyboard.isDown("right") then
            ---dx = dx + 1
            --player.x = player.x + 80 * dt
            --themap:moveMap(-90 * dt, 0)
        ---end
    
        ---if love.keyboard.isDown("up") then
            ---dy = dy - 1
            --player.y = player.y - 80 * dt
            --themap:moveMap(0,  90  * dt)
        ---elseif love.keyboard.isDown("down") then
            ---dy = dy + 1
            --player.y = player.y + 80 * dt
            --themap:moveMap(0, -90  * dt)
            
        ---end

---end

---function sprite:draw()
    ---camera:attach()
    
    ---love.graphics.draw(tilesetBatch)
    ---love.graphics.print("FPS: "..love.timer.getFPS(), 10, 20)
    
    
    ---camera:detach()
    ---camera:draw()
    
    ---end
---end

can anyone help, thankyou!

also leaving the window minimized makes the fps drop to 5 so be carefull

Re: help with collisions

Posted: Thu Sep 12, 2019 7:35 pm
by D0NM
Here is a simple solution of your problem.
At least there is an idea and its implementation in C++
https://gamedev.stackexchange.com/quest ... -collision

Re: help with collisions

Posted: Thu Sep 12, 2019 9:15 pm
by pgimeno
bobbymcbobface wrote:
Wed Sep 11, 2019 7:47 pm
edit again: ok nvm that! now there seems to be a weird drop in fps when colliding with things and moving either left or right while trying to collide with them - here's my code:

<snip>
If you don't provide a complete runnable example, it's much harder to debug. Also, often the problem is not in the posted code.

Re: help with collisions

Posted: Fri Sep 13, 2019 2:49 pm
by bobbymcbobface
sorry about that pgimeno here's lobby.lua which i think is the main cause of the drop in fps all you need to do is run sprite:load() in a main.lua file:

lobby.lua

Code: Select all

lobby = {}

local sprite = require('sprite')
local bump = require('bump')

function lobby:load()
  sprite:move_true()
  --sprite:add_collision({x=columnIndex, y=rowIndex}, columnIndex, rowIndex, 1, 1)
  
  world = bump.newWorld(32)

  TileW, TileH = 32,32
  
  Tileset = love.graphics.newImage('mytileset.png')
  
  local tilesetW, tilesetH = Tileset:getWidth(), Tileset:getHeight()
  
    --
  local collidable_chars = {['['] = true,
                            ['-'] = true,
                            [']'] = true,
                            ['p'] = true,
                            [';'] = true,
                            ['{'] = true,
                            ['_'] = true,
                            ['}'] = true }
    --
    
  local quadInfo = {
    { 'o', 64, 0 },
    { 'O', 96, 0},
    
    { '[', 65, 32 },
    { '{', 65, 64 },
    
    { '-', 96, 32 },
    { '_', 96, 64 },
    
    { ']', 125, 32},
    { '}', 125, 64},
    
    { 'p', 224, 32},
    { ';', 224, 64}
  }

  Quads = {}
  for _,info in ipairs(quadInfo) do
    -- info[1] = character, info[2]= x, info[3] = y
    Quads[info[1]] = love.graphics.newQuad(info[2], info[3], TileW, TileH, tilesetW, tilesetH)
  end


  local tileString = [[
[----------]p[----------]
{__________};{__________}
ooooooooooooooooooooooooo
ooooooooooooooOoooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooOoooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooOoooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
oooooooooooOooooooooooooo
ooooooooooooooooooooooooo
]]

  TileTable = {}
  
  local width = #(tileString:match("[^\n]+"))
  
  for x = 1,width,1 do TileTable[x] = {} end

  local rowIndex,columnIndex = 1,1
  for row in tileString:gmatch("[^\n]+") do
    assert(#row == width, 'Map is not aligned: width of row ' .. tostring(rowIndex) .. ' should be ' .. tostring(width) .. ', but it is ' .. tostring(#row))
    columnIndex = 1
    for character in row:gmatch(".") do
      TileTable[columnIndex][rowIndex] = character
      
      if collidable_chars[character] then
        sprite:add_collision({x=columnIndex, y=rowIndex}, (columnIndex - 1)*TileW, (rowIndex - 1)*TileH, TileW, TileH)
        
      end
      columnIndex = columnIndex + 1
    end
    rowIndex=rowIndex+1
  end
end


function lobby:draw()
  for columnIndex,column in ipairs(TileTable) do
    for rowIndex,char in ipairs(column) do
      local x,y = (columnIndex-1)*TileW, (rowIndex-1)*TileH
      love.graphics.draw(Tileset, Quads[char], x, y)
    end
  end
  
  sprite:draw()
  love.graphics.print("FPS: "..love.timer.getFPS(), 10, 20)
end

return lobby

--- exit to room needed
--- character needed
---                       |
--- remember to use these V
---                      sprite:move_true()
---                      sprite:draw()
---                      menu:allow()
---                      themap:load()
---                      love.graphics.draw(tilesetBatch)
as well as that I'll try your suggestion D0NM

Re: help with collisions

Posted: Fri Sep 13, 2019 4:21 pm
by pgimeno
bobbymcbobface wrote:
Fri Sep 13, 2019 2:49 pm
sorry about that pgimeno here's lobby.lua which i think is the main cause of the drop in fps all you need to do is run sprite:load() in a main.lua file:
I copied the code in the last post as lobby.lua, the code in the previous post as sprite.lua, added bump.lua and added this code as main.lua, following your instructions:

Code: Select all

local sprite = require 'sprite'
sprite:load()
It does nothing. Can you provide a complete, runnable example preferably as a .love file or as a .zip file? You're making it hard for us to help you.

Re: help with collisions

Posted: Sat Sep 14, 2019 8:45 am
by bobbymcbobface
sorry about that here's my love file

1st game.love
Game.love
(7.16 MiB) Downloaded 45 times
just a warning close the love file immediately after your done with it or else (like mine) your PC will be on the verge of crashing

Re: help with collisions

Posted: Sat Sep 14, 2019 10:23 am
by pgimeno
Thanks for posting the code.

The immediate reason is that introh:draw() is calling lobby:load() once per frame (you have lobby:load() and lobby:draw() in a row, therefore both are called every frame). This causes every collidable tile in the map to be re-added to the bump world every frame, making the number of boxes in the world grow and grow uncontrollably. That of course fills the memory quickly and makes bump extremely slow. The function lobby.load() should be called only once, and it probably should clear the bump world in case you want to also call it to reinitialize the game.

Re: help with collisions

Posted: Sun Sep 15, 2019 5:02 pm
by bobbymcbobface
Thanks pgimeno it worked! I'll leave this topic unsolved for now just in case i have any more questions but for now thankyou for the help and also thanks to anyone else who helped :)

edit: yeah I'm back already.... how would i detect which tile my character collides with and give the tiles names for when they are collided with i.e "player collided with tile_grass"

Re: help with collisions

Posted: Sun Sep 15, 2019 7:49 pm
by pgimeno
world:move gives you information about what object was collided. It returns several things, including the table that you passed to world:add; check the docs. If you include any information you want in that table, for example the terrain type, you can get it back when world:move detects a collision.