Primitive "Tiled" map loader and 2D game lighting

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
ninwa
Party member
Posts: 118
Joined: Tue Oct 12, 2010 1:21 am
Location: Metro Detroit
Contact:

Primitive "Tiled" map loader and 2D game lighting

Post by ninwa » Sun Nov 07, 2010 9:25 pm

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

User avatar
ninwa
Party member
Posts: 118
Joined: Tue Oct 12, 2010 1:21 am
Location: Metro Detroit
Contact:

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

Post by ninwa » Sun Nov 07, 2010 11:44 pm

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.

User avatar
SiENcE
Party member
Posts: 782
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

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

Post by SiENcE » Sun Nov 07, 2010 11:49 pm

Looks good.

btw. i like your game ideas.

User avatar
ninwa
Party member
Posts: 118
Joined: Tue Oct 12, 2010 1:21 am
Location: Metro Detroit
Contact:

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

Post by ninwa » Mon Nov 08, 2010 6:38 am

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.

User avatar
adrix89
Party member
Posts: 135
Joined: Fri Oct 15, 2010 10:58 am

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

Post by adrix89 » Mon Nov 08, 2010 12:01 pm

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
I use Workflowy but you can check out Dynalist as its the better offer.

User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

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

Post by Ryne » Mon Nov 08, 2010 1:18 pm

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 :)
@rynesaur

User avatar
ninwa
Party member
Posts: 118
Joined: Tue Oct 12, 2010 1:21 am
Location: Metro Detroit
Contact:

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

Post by ninwa » Mon Nov 08, 2010 8:13 pm

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! :]

User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

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

Post by Ryne » Mon Nov 08, 2010 9:16 pm

I cant wait :), I think adding lighting to my zombie shooter would make it significantly more awesome/immersing .
@rynesaur

User avatar
ninwa
Party member
Posts: 118
Joined: Tue Oct 12, 2010 1:21 am
Location: Metro Detroit
Contact:

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

Post by ninwa » Tue Nov 09, 2010 7:24 am

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.
Image

Inside that house from the perspective of the map editor, Tiled.
Image

User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

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

Post by Ryne » Tue Nov 09, 2010 10:18 am

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?
@rynesaur

Post Reply

Who is online

Users browsing this forum: Hydrogen Maniac and 9 guests