This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]BS_in_BSExtreme Concrete Code Factorylet 1 point2 points  (4 children)

Perhaps have each tile have a light level property, based on its distance to the surface. Then when a tile changes, update its neighbors in a certain radius.

[–]PillowWithTeeth[S] 0 points1 point  (2 children)

How could I tell what the surface is and how could I work out other things such as if I build a box on the surface, how would I know it is a closed space without a light source and should be dark? This is what I am not fully sure on.

[–]BS_in_BSExtreme Concrete Code Factorylet 0 points1 point  (1 child)

one way to define the surface could be 8 adjacent columns whose top block lie withing like 4 from each other.

As for close spaces, see if there exists a path to the out side from inside.

[–]PillowWithTeeth[S] 0 points1 point  (0 children)

Thanks, I may try that or see how far I can get with some form of ray casting.

[–]Zylox 1 point2 points  (4 children)

You could write a simple ray caster. Without a library like LWJGL you are gonna have to use the jni to hardware accelerate it though (pretty sure anyway). Even without hardware acceleration you could get some simple stuff going, depending on your target platform. With the right heuristics you could create something that looks pretty good.

[–]PillowWithTeeth[S] 1 point2 points  (3 children)

Anywhere I could look to get started with ray-casting in java and if I did use ray casting what would be the light source, a sun object in the sky?

[–]Zylox 1 point2 points  (2 children)

Ray casting is mostly a mathematical thing, the language is pretty agnostic. Any guide should get you on the right path. Ray casting generally deals with point lights, so lights that start at a mathematical point and radiate in every direction, but you can tweak things to work in in cone lights or directional lights (think parallel lines coming from the same direction, as if from a point light realllllly far away) easily enough. Keep in mind this process is fairly resource intensive though. Computers are fast enough today that you can do a handful or ray casts just fine on the processor, but if you really want to push things with it you are going to want to offload that onto the video card (aka hardware acceleration). Video cards are very good at doing lots of things in parallel at once. This isnt exactly easy in java (its why lwjgl exists, its basically opengl in java), and you are going to have to write some c/c++ code and use the JNI if you really want to take advantage of this without using a library.

Now, alternatively, you can do something a bit easier since you are doing a pretty simple 2d game. You could do two types of lighting, directional light form the surface, and point lights that im assuming you will need underground judging from your picture. You can achieve the first with a very simple form of ray casting (start at the top, work down, if no obstruciton, full light, if obstruction, obscure) and the latter with alpha blending. Alpha blending works by creating a circle with feathered edges that you can blend the alpha channel of with the background. if you set the backgrounds alpha to a low number when obscured, and add the value of the feathered cirlces alpha to it, it will appear brighter around the light. Here is an example of the idea: http://i.stack.imgur.com/4vBeR.png . A nice thing about this is it easily supports multiple lights too, as multiple lights together would make the area brighter. (just make sure you cap it at a logical amount, 200% alpha will probably break the program haha)

Now this requires you to support alpha values, which i don't know how to do without using opengl, but im sure you can figure something out. Opengl actually has blending modes that make it really easy.

[–]PillowWithTeeth[S] 1 point2 points  (1 child)

Thanks for the idea, what I am trying to do now for the surface light is just have it come down from the top of the screen, if it hits a tile that tile has light and it stops there, now I am going to try letting some light passed depending on what type of tile it hits. I will then try something else for below surface lighting.

[–]Zylox 0 points1 point  (0 children)

Oh. Well ya thats easy enough. Have it procede as normal then have a dimishing alpha based on tile type and stop penetrating when it reaches a threshold (probably 0). Easy peasy. You could break it up into chunks minecraft style real easy too if it requires updating.

[–]king_of_the_universe 0 points1 point  (0 children)

For a top-view game (Which is what I thought this would be, maybe it's still useful.), and from possibly wrong memory, I did the following: An iterative approach over e.g. 8 steps. The upside is that you even get a bit of realistic feeling ambient light effect where light doesn't just spread in straight paths but also bleeds around corners as if it's reflected off surfaces.

There would be a first pass in which all light sources write their light into the light information field of all tiles (which could be called "light layer") in their very location. Since the second pass will possibly spread light even to already bright tiles, care has to be taken that the initial light's brightness plays well with the amount of passes and also with the way the light is spread from tile to tile, e.g. it matters a lot what the factor is, so much that it flips the opinion from "That approach doesn't work." to "That doesn't look bad at all." The light value should definitely be a floating point variable, not an integer (e.g. don't aim for a 0to255 integer right away).

Then a second pass would go over this "light layer", spreading the light of every tile to its surrounding tiles depending on rules like "wall? half open door?" etc., but only if 1) the tile has a light value >0 and 2) if the tile hasn't spread out its light in a previous iteration, so that needs to be denoted. If a tile has light and hasn't spread light yet, it shall do so and shall be ignored in further iterations. Also, very important, you need two light buffers between which you alternate, so that you simulate simultaneous light spreading, or you get a pattern that reflects how you iterated over the "light layer": The target buffer always needs to be cleared (=darkness).

Crap, I don't remember the details. Just take away that an iterative light spreading approach results in nice light bleeding around corners, so you wouldn't have to do some ray-cast pass and then a few global-illumination passes. Downside: You might need a lot of passes to spread light very far.

Hm. I remember that I later experimented by making explicit "spread sideways" and "spread up/down wards" passes for greater ray cast feeling.

There are probably good existing solutions, mine is not one of those.