Page 1 of 3

Primitive "Tiled" map loader and 2D game lighting

Posted: Sun Nov 07, 2010 9:25 pm
by ninwa
Feel free to steal from the code,

press 1, 2, or 3 to set the lighting to different brightnesses. Notice the lightsource underneath the player. Also, this map is being loaded in from a map created with Tiled. There are a few demo maps, just look in the directory and change the map name that's being loaded.

http://www.josephbleau.com/PC_Light.love

Requires Love 0.7.0 for use of framebuffers in lighting code

The lighting is still proof of concept, it's not abstracted out to be useful unless you gut it and do it yourself, but I'll get there.

Cheers!
Ninwa

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Sun Nov 07, 2010 11:44 pm
by ninwa
I abstracted the lighting code out. Feel free to use it for whatever you want.

Code: Select all

require "MiddleClass.lua"

Candle = class('Candle')
Flame  = class('Flame')

-- The Candle library is going to take the liberty
-- of keeping track of all of your current Flames.
-- I need to do this because of how I'm doing the drawing.
-- At least for now until I refactor/rethink it.
Candle.flames = {}

function Candle.new(x,y,max_shimmer,min_shimmer)
	table.insert(Candle.flames, Flame:new(x,y,max_shimmer,min_shimmer))
end

function Candle.update(dt)
	for _, v in ipairs(Candle.flames) do
		v:update(dt)
	end
end

-- We need to use a frame buffer so we can do
-- independent blending of our light sources and
-- our shroud without having to worry about
-- anything else being drawn. One is good
-- for all of our Flames though!
Candle.buffer = love.graphics.newFramebuffer()

function Candle.draw()
	Candle.buffer:renderTo(function() 	
		love.graphics.draw(Candle.shrouds[Candle.shroud_intensity],0,0) -- draw our shroud
		for _, v in ipairs(Candle.flames) do
			love.graphics.setColor(v.light_intensity,v.light_intensity,v.light_intensity)
			love.graphics.circle('fill',v.x,v.y,v.shimmer_radius,256) 
		end
	end)
	
	love.graphics.setBlendMode("multiplicative")
	local draw_me = love.graphics.newImage(Candle.buffer:getImageData())
	love.graphics.draw(draw_me,0,0)
	love.graphics.setBlendMode("alpha")
end

--[[ Note: Currently the shroud_intensity is fixed, you can change it but
           you must also change the for loop in generateShrouds also. I initially
		   wanted to load all possible shrouds up-front, but this takes way too long.
		   I will find a new approach, but in the meantime... deal with it? ]]
   
Candle.shrouds = {}
Candle.shroud_intensity = 200 -- Fixed for now until I figure this shit out.

-- I wouldn't use this if I were you!
function Candle.setShroudIntensity(intensity)
	self.shroud_intensity = intensity
end

-- You can call this in love.load
-- so that it wont stall us when we
-- create our first Candle.
function Candle.generateShrouds() 
	for i=200, 200 do
		-- TODO: Replace dimensions with a variable
		-- screen size.
		Candle.shrouds[i] = love.image.newImageData(768,768)
		
		for x=1, Candle.shrouds[i]:getWidth() do
			for y=1, Candle.shrouds[i]:getHeight() do
				Candle.shrouds[i]:setPixel(x,y,0,0,0,i)
			end
		end
		
		Candle.shrouds[i] = love.graphics.newImage(Candle.shrouds[i])
	end
end


function Flame:initialize(x,y,max_shimmer,min_shimmer)
	if #Candle.shrouds == 0 then
		Candle.generateShrouds()
	end
	
	self.x = x
	self.y = y
	if max_shimmer == nil then self.max_shimmer = 50 
	else self.max_shimmer = max_shimmer end
	if min_shimmer == nil then self.min_shimmer = 50
	else self.min_shimmer = min_shimmer end
	
	self.light_intensity = 255
	self.shimmer_radius = self.max_shimmer-1
	self.shroud_intensity = 200
	self.magic = 1 -- Every code needs a little bit of magic.
end

function Flame:update(dt)
	-- "Shimmer" effect by growing and
	-- shrinking Candle radius
	
	if self.min_shimmer ~= self.max_shimmer then
		self.shimmer_radius  = self.shimmer_radius - 50 * dt * self.magic
		self.shimimer_radius = math.floor(self.shimmer_radius)
		if self.shimmer_radius >= self.max_shimmer then
			self.magic = self.magic * -1
		end

		if self.shimmer_radius <= self.min_shimmer then
			self.magic = self.magic * -1
		end
	end
end
foo = Candle.new(x,y) creates a new source.

and make sure to do Candle.update(dt) in your update-loop and Candle.draw() in your draw loop. It must be the last thing drawn.

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Sun Nov 07, 2010 11:49 pm
by SiENcE
Looks good.

btw. i like your game ideas.

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Mon Nov 08, 2010 6:38 am
by ninwa
I think lighting looks a lot better this way. I changed how multiple lightsources blend so it works better, plus am now able to create the effect you see on the star on the house.

http://dl.dropbox.com/u/13836131/PC.love

Also, press 'm' to load a different map. Was seeing how well my code handled doing this on the fly, and it works pretty well.

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Mon Nov 08, 2010 12:01 pm
by adrix89
Can you post a screenshot?
Seems the frame buffer is screwing with me,that or the blend mode(or both)
Got it not crashing by setting it up to 1024

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Mon Nov 08, 2010 1:18 pm
by Ryne
This looks interesting, I was going to do some fake 2D lighting by making separate sprites but this seems much better, I may end up using it :)

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Mon Nov 08, 2010 8:13 pm
by ninwa
I'll post a screenshot up later, I'm currently at work, but the tileset the demo is using is not PO2-friendly, which I suspect may be causing the problems. It supports any Tiled map, with any tileset, so I may have to fix that even if I'm just padding the tiles.

@Ryne, thank you! And you're more than welcome to. I probably wouldn't use it just yet as it's really limited and the interface is likely to change but I will be releasing any changes to the library as I go along, so you're welcome to play with it! :]

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Mon Nov 08, 2010 9:16 pm
by Ryne
I cant wait :), I think adding lighting to my zombie shooter would make it significantly more awesome/immersing .

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Tue Nov 09, 2010 7:24 am
by ninwa
adrix89 wrote:Can you post a screenshot?
Seems the frame buffer is screwing with me,that or the blend mode(or both)
Got it not crashing by setting it up to 1024
Ask and you shall receive! :o)

Outdoor area with lighting (check out the start) in real time it shimmers a little.
LmqAn.png
LmqAn.png (290.8 KiB) Viewed 929 times
Inside that house from the perspective of the map editor, Tiled.
KTe0o.png
KTe0o.png (240.31 KiB) Viewed 929 times

Re: Primitive "Tiled" map loader and 2D game lighting

Posted: Tue Nov 09, 2010 10:18 am
by Ryne
Thats just awesome. I wonder how hard It would be to implement this. Maybe I can leave it for last and you can give me a hand with it?