Page 1 of 1

Random terrain collision

Posted: Wed Feb 07, 2024 9:07 pm
by PoPCaT6800
I am working on a top down game with randomly generated tiles. I am not sure how to make the player collide with the walls, I've tried to log the generated wall tiles in a table and then detecting if the player is at one of those but it won't run.

Code: Select all

function love.load()
  detectioncounter = 0
  plrx = 0
  plry = 0
  collidecounter = 0
  collidablex = {}
  collidabley = {}
	tileSize = 16 -- for image 32x32 pixels
	g = {image = love.graphics.newImage("/textures/tiles/ground_1.png")} -- image 32x32 pixels
	a = {image = love.graphics.newImage("/textures/tiles/stone_1.png")} -- image 32x32 pixels
  
	local w, h = 50, 50
	map = {}
	for y = 1, h do
		map[y] = {}
		for x = 1, w do
			local value = love.math.noise( 0.08*x, 0.2*y)
			if value > 0.8 then -- 80% air and 20% ground
				map[y][x] = g -- floor
        
        
			else
				map[y][x] = a -- walls
        collidecounter = collidecounter + 1
        table.insert(collidablex, collidecounter, x)
        table.insert(collidabley, collidecounter, y)
			end
		end
	end
  print(collidablex[2], collidabley[2])
  _playerinit()
end

function love.update(dt)
  _playermove(dt)
end

function love.draw()
  _playerdraw()
	for y, xs in ipairs (map) do
    
		for x, tile in ipairs (xs) do
			love.graphics.draw(tile.image, (x-1)*tileSize, (y-1)*tileSize)
		end
	end
  _playerdraw()
end
function _playerinit()
  hero = love.graphics.newImage("/textures/entities/warrior.jpg")
end


function _playerdraw()
  love.graphics.draw(hero, plrx, plry)
end
function _playermove()
  love.keypressed( key, scancode, isrepeat )
end
function love.keypressed( key, scancode, isrepeat )
   if scancode == "right" then -- move right
      plrx = plrx + 16
      while detection < 2501 and x ~= collidablex[detection] and y ~= collidabley[detection] do
        detection = detection + 1
        if collidablex[detection]=x and collidabley[detection]=y then
          plrx = plrx - 16
        end
   elseif scancode == "left" then -- move left
      plrx = plrx - 16
   elseif scancode == "down" then -- move down
      plry = plry + 16
   elseif scancode == "up" then -- move up
      plry = plry - 16
   end
end
If anyone can help I would really appreciate it!

Re: Random terrain collision

Posted: Fri Feb 09, 2024 7:33 pm
by Azzla
While I applaud you for attempting to write collision detection + resolution entirely on your own, I can't say I recommend it unless you are very experienced with game development and the related math. You should definitely consider using Box2D (love's built in physics engine) or something like bump for a more lightweight solution. Bump seems perfect for your needs.

As for your code, it is very hard to decipher what you are trying to do (or what's wrong with it) without seeing it in action. Please provide a .love archive for testing.

Re: Random terrain collision

Posted: Fri Feb 09, 2024 7:44 pm
by dusoft
I second what Azzla said. Love physic module is recommended or use some helpers like Bump or HC, if you must.

Re: Random terrain collision

Posted: Sat Feb 10, 2024 6:04 am
by knorke
He is trying to make a gridbased map like in Sokoban, love.physics is not needed/suitable for that and overkill.

This line has two typos, it shoud be == instead of =:

Code: Select all

        if collidablex[detection]=x and collidabley[detection]=y then
Löve tells you about that when trying to run:
Error: Syntax error: main.lua:64: 'then' expected near '='
You are also missing an "end" somewhere.

Not sure what you are trying to do with the " while detection" loop.
You could do something like this:

Code: Select all

--store player position
local oldX, oldY = plrx, plry
if scancode == "right" then plrx = plrx + 16 end --move right
if scancode == "left" then plrx = plrx - 16 end  --move left
...
--which tile of the map is the player on?
local tileX, tileY = plrx/16, plry/16
--new position is blocked?
if map[tileX][tileY] == wall then
--reset player to previous position
plrx, plry = oldX, oldY
end
Also, in your map table you currently store images for each tile.
Instead only store numbers (like wall=1, air=0)

Re: Random terrain collision

Posted: Sat Feb 10, 2024 10:08 am
by dusoft
Well top-down game with tiles can still use polygons for other stuff. But fair enough. If it is just blocks than basic AABB collision checking will work.

Re: Random terrain collision

Posted: Sun Feb 11, 2024 6:19 am
by RNavega
There was an article on GameDev.net many years ago, something like "So you want to be a game developer?", where it'd posit that the best way to learn how to program games, is to make clones of classic games of progressing complexity.
It suggested starting with Pong, then Arkanoid, then Tetris and finally something with some simple AI like Pac-Man or a 2D platformer with multiple characters.
At each point you'd have to study all these different topics (like with Arkanoid, you'd need to learn about how to calculate tile collisions etc), that would also be used in the next games.

So, in the interest of learning, I'm also for writing your own tile handling code. The problem is finding good material to learn from...

There seems to be a lot of stuff for Unity, like video tutorials, which for programming I don't usually like because it depends a lot on the speaking skills of the presenter, their pacing and such.

Since I prefer text tutorials, the top two results that I could find were these:
- https://sheepolution.com/learn/book/18
- https://jonathanwhiting.com/tutorial/collision/

Sometimes you can find good results by searching for something other than the language and engine you're using, so searching for Flash, Java etc can yield a good tutorial that explains the thing just the way you needed to hear it.
Also using image searches, so you can use vague queries like "tilemap collision tutorial" and see what images come up, to find a tutorial with great material.