Love - Creating a Map

From TRCCompSci - AQA Computer Science
Revision as of 08:29, 28 June 2019 by Admin (talk | contribs) (Taking this further)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Requirements

You need to have followed the installation process for the Love engine.

You also need to have created a minimal game (ie a new folder, with a 'main.lua' file)

You need to have added this code to 'main.lua':

function love.load()

end

function love.update(dt)

end
 
function love.draw()

end

My code will use this image: Tiles.png

Creating a Map Array

We need a way of storing a map of the tiles. This code below creates a 1D array, a 0 represents no tile and then any number above zero is a specific tile. Add the following before your 'love.load()':

 map = { 
			0, 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, 4, 4, 0, 0, 0, 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, 3, 3, 3, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
		}

Loading the tileset

Now in the 'love.load()' we need to load in your tileset image, and also we can create rectangles for each different tile in the tileset:

function love.load()
	tilesheet = love.graphics.newImage("tiles.png")
	grass = love.graphics.newQuad(0, 0, 32, 32, tilesheet:getDimensions())
	boxtop = love.graphics.newQuad(32, 0, 32, 32, tilesheet:getDimensions())
	flowers = love.graphics.newQuad(0, 32, 32, 32, tilesheet:getDimensions())
	box=love.graphics.newQuad(32, 32, 32, 32, tilesheet:getDimensions())
end

Drawing the map

The map array contains 100 values to create a 10 x 10 map. We will therefore have two for loops which iterate from 0 to 9, these are nested so that we cycle through each element of the map.

Remember count is needed because the map array is just 1D, you could make your array 2D if you wanted:

function love.draw()
	count = 0
		for y=0, 9 do 
			for x=0, 9 do
				if map[count] == 1 then
					love.graphics.draw(tilesheet, grass, x*32, y*32, 0, 1, 1)
				elseif map[count] == 2 then
					love.graphics.draw(tilesheet, boxtop, x*32, y*32, 0, 1, 1)
				elseif map[count] == 3 then
					love.graphics.draw(tilesheet, flowers, x*32, y*32, 0, 1, 1)
				elseif map[count] == 4 then
					love.graphics.draw(tilesheet, box, x*32, y*32, 0, 1, 1)
				end
				count=count+1
			end
		end
end

Inside the nested for loops, the value in the map is checked to see if it is a 1,2,3, or 4. The if statement will then draw the appropriate tile. Also notice how the current values for x & y are used to work out the position of the tile.

Taking this further

This approach works well for a small tile set, however for a larger tile set it would be inefficient.

The solution is to calculate which tile to draw, based upon the number entered in the map. Check out this example:

 cols=2

 map = { 
			0, 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, 4, 4, 0, 0, 0, 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, 3, 3, 3, 0, 0, 0, 0, 0, 
			0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
		}

function love.load()
	tilesheet = love.graphics.newImage("tiles.png")
end

function love.update(dt)

end
 
function love.draw()
	count = 0
	for y=0, 9 do 
		for x=0, 9 do
			if map[count] ~= 0  and map[count] ~= nil then
				xpos = (map[count]-1)%cols
				ypos = math.floor((map[count]-1)/cols)
				tile = love.graphics.newQuad(xpos*32, ypos*32, 32, 32, tilesheet:getDimensions())
				love.graphics.draw(tilesheet, tile, x*32, y*32, 0, 1, 1)
			end
			count=count+1
		end
	end
end