using draw.graphics.rectangle to draw tiles

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
IAmTheRealSpartacus
Prole
Posts: 9
Joined: Mon Nov 07, 2011 8:08 pm

using draw.graphics.rectangle to draw tiles

Post by IAmTheRealSpartacus »

Hi.

I recently started using Love to shape a longtime dream into reality (agreed that sounds weird).

I'm making a 2D, tile-based, turn-based sim/strategy game. Right now I'm at the stage where I'm trying to draw a scrolling 2d map onto the screen. This works well using tilesets and some newSpriteBatch magic. So far, so good.

However, I want to impose a sense of altitude in each tile by having an altitude value (each tile gets a value between 0 and 255 assigned which is it's altitude) determine the background color of the tile, and put trees, animals, buildings etc. on top of that using tilesets. So instead of using preloaded background tiles I use draw.graphics.rectangle() directly to build my background.

This works well in terms of FPS (my tiles are 16x16 and I draw on a 1024x640 screen)--everything renders quickly even while scrolling. But since I use a double for/next loop to draw each rectangle, there's a delay in drawing between the 1st and last rectangle, which is very annoying to the eyes.

I initially wanted to use framebuffers but I get the dreaded "Cannot create framebuffer: Not supported by your OpenGL implementation" message, so I turned to rectangles.

My question: is there any other way to do this? Can I draw rectangles into quads and put those into tilesets?

I use Love 0.7.2 on a mid-2009 MBP13" 4GB 2.53GHz Core2Duo, running Mac OS X 10.5.8.

Oh and what code editor do you guys recommend?

cheers
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: using draw.graphics.rectangle to draw tiles

Post by tentus »

I'm all about Notepad++, but that's just if you're on Windows.

Something you may want to consider: you could render the elevation to an image and then scale the image up using nearest. That way you don't get blurring, just nice crisp square values.

Code: Select all

local data = love.image.newImageData(32,32)
for x=0, 31 do	-- loop through the xs first, starting at pixel 0
	for y=0, 31 do	-- now do the ys, also starting at pixel 0
		local c = getValue(x, y)
		data:setPixel(x, y, c, c, c, 255)
	end
end
img = love.graphics.newImage(data)		-- the original colors are saved into an image for easy rendering
img:setFilter("nearest", "nearest")
The above code assumes your map is 32x32 (could changed easily) and it also assumes you have a function to get the value of each tile, called getValue(). getValue() would return an int between 0 and 255, inclusive. In love.draw() you will have to use the scale parameter like this:

Code: Select all

love.graphics.draw(img, 0, 0, 0, 16, 16)
Last edited by tentus on Mon Nov 07, 2011 9:20 pm, edited 1 time in total.
Kurosuke needs beta testers
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: using draw.graphics.rectangle to draw tiles

Post by Robin »

Could you give us a .love with your current code, so we can check that out? Then we can help you better.

If everything is normal, there shouldn't be a delay. Everything should be drawn to the screen in one go. So I don't know what's causing it.
Help us help you: attach a .love.
IAmTheRealSpartacus
Prole
Posts: 9
Joined: Mon Nov 07, 2011 8:08 pm

Re: using draw.graphics.rectangle to draw tiles

Post by IAmTheRealSpartacus »

Thanks for the quick responses! I'll try to render it to an image, see if that works.

Here is the function that does the drawing and is the first to be called in the love.draw() handler. (FYI, tileSize = 16, waterLevel = 127, and mapX, mapY denote where the screen is focusing on.)

Code: Select all

function love.draw()
  drawBkg()
end

function drawBkg()

   offsetX = math.floor(-zoomX*(mapX%1)*tileSize)
   offsetY = math.floor(-zoomY*(mapY%1)*tileSize)
	
   for y=0, tilesDisplayHeight-1 do
      for x=0, tilesDisplayWidth-1 do  
	alt = map[math.floor(mapY) + y][math.floor(mapX) + x]
	if alt > waterLevel then
	  love.graphics.setColor(0, alt, 0, 255)
	else
	  love.graphics.setColor(0, 0, alt * 255 / waterLevel, 255)
	end                                                       
        love.graphics.rectangle('fill', offsetX + x*tileSize, offsetY + y*tileSize, tileSize, tileSize)
      end
   end
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Majestic-12 [Bot], zorg and 2 guests