help with collisions

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
pgimeno
Party member
Posts: 1769
Joined: Sun Oct 18, 2015 2:58 pm

Re: help with collisions

Post by pgimeno » Sun Sep 08, 2019 10:01 pm

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.

User avatar
bobbymcbobface
Prole
Posts: 31
Joined: Tue Jun 04, 2019 8:31 pm

Re: help with collisions

Post by bobbymcbobface » Wed Sep 11, 2019 7:47 pm

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
I make games that run on potatoes :P

User avatar
D0NM
Party member
Posts: 214
Joined: Mon Feb 08, 2016 10:35 am
Location: Zabuyaki
Contact:

Re: help with collisions

Post by D0NM » Thu Sep 12, 2019 7:35 pm

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
Our LÖVE Gamedev blog Zabuyaki (an open source retro beat 'em up game). Follow @Zabuyaki.
Twitter @FaMeSoft / GP32 Free Platformer: SUPER PLUSHA
:joker: LÖVE & Lua Video Lessons in Russian / Видео уроки по LÖVE и Lua :joker:

User avatar
pgimeno
Party member
Posts: 1769
Joined: Sun Oct 18, 2015 2:58 pm

Re: help with collisions

Post by pgimeno » Thu Sep 12, 2019 9:15 pm

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.

User avatar
bobbymcbobface
Prole
Posts: 31
Joined: Tue Jun 04, 2019 8:31 pm

Re: help with collisions

Post by bobbymcbobface » 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:

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
I make games that run on potatoes :P

User avatar
pgimeno
Party member
Posts: 1769
Joined: Sun Oct 18, 2015 2:58 pm

Re: help with collisions

Post by pgimeno » Fri Sep 13, 2019 4:21 pm

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.

User avatar
bobbymcbobface
Prole
Posts: 31
Joined: Tue Jun 04, 2019 8:31 pm

Re: help with collisions

Post by bobbymcbobface » Sat Sep 14, 2019 8:45 am

sorry about that here's my love file

1st game.love
Game.love
(7.16 MiB) Downloaded 2 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
I make games that run on potatoes :P

User avatar
pgimeno
Party member
Posts: 1769
Joined: Sun Oct 18, 2015 2:58 pm

Re: help with collisions

Post by pgimeno » Sat Sep 14, 2019 10:23 am

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.

User avatar
bobbymcbobface
Prole
Posts: 31
Joined: Tue Jun 04, 2019 8:31 pm

Re: help with collisions

Post by bobbymcbobface » Sun Sep 15, 2019 5:02 pm

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"
I make games that run on potatoes :P

User avatar
pgimeno
Party member
Posts: 1769
Joined: Sun Oct 18, 2015 2:58 pm

Re: help with collisions

Post by pgimeno » Sun Sep 15, 2019 7:49 pm

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.

Post Reply

Who is online

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