Custom map loading technique

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

Re: Custom map loading technique

Post by pgimeno » Tue Jul 09, 2019 1:43 pm

I haven't tested the code, but that sounds like the usual problem of gaps between squares. Just be careful to make your quads always be drawn at integer coordinates.

User avatar
raidho36
Party member
Posts: 1919
Joined: Mon Jun 17, 2013 12:00 pm

Re: Custom map loading technique

Post by raidho36 » Tue Jul 09, 2019 1:45 pm

Alternatively, pad the textures with 1 pixel of the same color on each side, outside of the quad.

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

Re: Custom map loading technique

Post by bobbymcbobface » Tue Jul 09, 2019 4:32 pm

alright upon doing a bit of research i found this example:

Code: Select all

function love.load()
	-- our tiles
	tile = {}
	for i=0,3 do -- change 3 to the number of tile images minus 1.
		tile[i] = love.graphics.newImage( "tile"..i..".png" )
	end
 
	-- the map (random junk + copy and paste)
	map={
	{ 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0},
	{ 3, 1, 0, 0, 2, 2, 2, 0, 3, 0, 3, 0, 1, 1, 1, 0, 0, 3, 0, 0, 0},
	{ 3, 1, 0, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0},
	{ 3, 1, 1, 0, 2, 2, 2, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 0},
	{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3},
	{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 2},
	{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 1},
	{ 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 0, 2, 2, 2, 0, 3, 0, 3, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 1, 0, 2, 2, 2, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3},
	{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	}
 
	-- map variables
	map_w = #map[1] -- Obtains the width of the first row of the map
	map_h = #map -- Obtains the height of the map
	map_x = 0
	map_y = 0
	map_display_buffer = 2 -- We have to buffer one tile before and behind our viewpoint.
                               -- Otherwise, the tiles will just pop into view, and we don't want that.
	map_display_w = 20
	map_display_h = 15
	tile_w = 16
	tile_h = 16
end

function draw_map()
	offset_x = map_x % tile_w
	offset_y = map_y % tile_h
	firstTile_x = math.floor(map_x / tile_w)
	firstTile_y = math.floor(map_y / tile_h)
 
	for y=1, (map_display_h + map_display_buffer) do
		for x=1, (map_display_w + map_display_buffer) do
			-- Note that this condition block allows us to go beyond the edge of the map.
			if y+firstTile_y >= 1 and y+firstTile_y <= map_h
				and x+firstTile_x >= 1 and x+firstTile_x <= map_w
			then
				love.graphics.draw(
					tile[map[y+firstTile_y][x+firstTile_x]],
					((x-1)*tile_w) - offset_x - tile_w/2,
					((y-1)*tile_h) - offset_y - tile_h/2)
			end
		end
	end
end

function love.update( dt )
	local speed = 300 * dt
	-- get input
	if love.keyboard.isDown( "up" ) then
		map_y = map_y - speed
	end
	if love.keyboard.isDown( "down" ) then
		map_y = map_y + speed
	end
 
	if love.keyboard.isDown( "left" ) then
		map_x = map_x - speed
	end
	if love.keyboard.isDown( "right" ) then
		map_x = map_x + speed
	end
	if love.keyboard.isDown( "escape" ) then
		love.event.quit()
	end
 
	-- check boundaries. remove this section if you don't wish to be constrained to the map.
	--if map_x < 0 then
	--    map_x = 0
	--end
 
	--if map_y < 0 then
		--map_y = 0
	--end
 
	--if map_x > map_w * tile_w - map_display_w * tile_w - 1 then
		--map_x = map_w * tile_w - map_display_w * tile_w - 1
	--end
 
	--if map_y > map_h * tile_h - map_display_h * tile_h - 1 then
	--	map_y = map_h * tile_h - map_display_h * tile_h - 1
	--end
end

function love.draw()
	draw_map()
end
here are the images:
tile0.png
tile0.png (1.43 KiB) Viewed 2159 times
tile1.png
tile1.png (1.37 KiB) Viewed 2159 times
tile2.png
tile2.png (1.38 KiB) Viewed 2159 times
btw you will have to add an extra image called tile3.png but you can just copy one of these tiles twice

i know this is of the wiki but it meets all my requirements so I'm using it but the only problem is how can i make this infinite like in spyryth previous example and add variables to it such as mapwidth and mapheight can anyone supply some code so i can understand how i would implement this -

Edit: forgot to tell you this is my backup I'm just posting it here so I remember it and if editing the tilset image doesn't work I can hopefully try one of your answers you've given me (so don't worry spyrthh I'm not dumping your idea)

And to respond to pgimeno I'll try changing the X y cordinates when I have I chance and maybe that will fix it
thankyou! :)
I make games that run on potatoes :P

sphyrth
Party member
Posts: 108
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth » Wed Jul 10, 2019 11:31 am

So I got a clue from pgimeno's comment. The cause of the black lines are y coordinates being set to decimals. Rounding them up or down with math.ceil() and math.floor() fixed the issue.

Here's the love file for the people who want to check it out.
loopingmap.love
(114.77 KiB) Downloaded 60 times
Although using Spritebatch is still recommended, I'll try to port that concept in bobbymcbobface's code.

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

Re: Custom map loading technique

Post by bobbymcbobface » Wed Jul 10, 2019 11:41 am

Thankyou! I look forward to trying the result 😀
I make games that run on potatoes :P

User avatar
pgimeno
Party member
Posts: 1872
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

Re: Custom map loading technique

Post by pgimeno » Wed Jul 10, 2019 3:16 pm

sphyrth wrote:
Wed Jul 10, 2019 11:31 am
So I got a clue from pgimeno's comment. The cause of the black lines are y coordinates being set to decimals. Rounding them up or down with math.ceil() and math.floor() fixed the issue.

Here's the love file for the people who want to check it out.
loopingmap.love

Although using Spritebatch is still recommended, I'll try to port that concept in bobbymcbobface's code.
You can both use spritebatch and round the coordinates. Just don't set the quads in the spritebatch to be at non-integer coordinates, nor draw the spritebatch to the screen at non-integer coordinates.

Changing this line in updateTilesetBatch() from the code you posted earlier gets rid of the black lines:

Code: Select all

      tilesetBatch:add(tileQuads[map[x][y].tile], math.floor(map[x][y].x), math.
floor(map[x][y].y))

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

Re: Custom map loading technique

Post by bobbymcbobface » Wed Jul 10, 2019 3:28 pm

i finally got round to adding your code and it works thank you!

PS: still gonna leave this post unsolved in case i found any other problems and also i need to work out how to make my own tile set image.

edit: back already! Is it possible to add a zoom to my game since increasing the tile size doesn't work and if so can someone show me how thank you! :)

edit:
Capture.PNG
Capture.PNG (38.57 KiB) Viewed 2086 times
as well as that is there a way to make this more efficient because otherwise I'll have 200 commands defining each tile quad and I'll get confused

edit (sorry for nagging but I'm a complete noob so i do need help): how would i add collision to tiles such as rocks?
I make games that run on potatoes :P

sphyrth
Party member
Posts: 108
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth » Thu Jul 11, 2019 12:25 pm

Those are a lot, let's see...

Zooming, Scaling, Bigger Tiles
I'm not sure if what you want to accomplish is to really "zoom" in, scale the image up, or just want bigger tiles without the zoom feature.
On Zooming and Scaling, there's a tutorial on how to use love.graphics.push(), love.graphics.pop(), etc... I'm planning on having that on my repertoire, but I leave that to the people more adept at it.
If you want bigger tiles, just edit the png file and stretch the image to the tileSize of your liking (the number of pixels determine the width and height of each tile, so you can control that when stretching the image... or you can make those tiles yourself).

More Efficient Quad Declaration
Since you're using numbers to access each Quad in the Sprite, loading them using a nested loop is the way to go.

Collision
I struggle with this the most. I don't really use love.physics, nor Bump... but those are your goto tools when detecting collisions.

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

Re: Custom map loading technique

Post by bobbymcbobface » Thu Jul 11, 2019 5:19 pm

sphyrth wrote:
Thu Jul 11, 2019 12:25 pm
More Efficient Quad Declaration
Since you're using numbers to access each Quad in the Sprite, loading them using a nested loop is the way to go.
sorry to be a pain but I'm having trouble with this
so far i have this
Capture.PNG
Capture.PNG (17.58 KiB) Viewed 2004 times
but it clears the previous variable out and overrides it (i.e i wanted 500 grass and underneath adding 500 grass i put add 200 dirt the dirt would then override 200 out of the 500 of the grass) and as well as that i feel that still not that efficient as it could be could anyone give some example code please or how i would introduce a nesting loop

~thankyou
I make games that run on potatoes :P

sphyrth
Party member
Posts: 108
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Custom map loading technique

Post by sphyrth » Fri Jul 12, 2019 11:01 pm

Code: Select all

function tilequad(x, y, count)
   local start = #tileQuads + 1 -- The #<tablename> (in this case, the tablename is tileQuads) counts the number of max tiles.
                                           -- the +1 means we'll start at the number NEXT to the last tile.
                                           -- This means we won't override anything before the table.

   for i = start, start + count do
      tileQuads[i] = love.graphics.newQuad(x * tileSize, y * tileSize, tileSize, tileSize, tilesetImage:getWidth(), tilesetImage:getHeight())
   end
end

--Now try this
tilequad(0, 0, 2000)
tilequad(0, 3, 500)

Post Reply

Who is online

Users browsing this forum: No registered users and 12 guests