[Help]2D tile map lighting

First attempt didn’t work -

public static boolean tileVisible(int x1, int x2, int y1, int y2, map m){
        
        int deltax = x2 - x1;
        int deltay = y2 - y1;
        int y = y1;
        int ynum = deltax/2;
        for(int x = x1; x <= x2; x++){
            if(m.Map[(int)(x-m.mapPosX)/m.TILE_SIZE_X][(y-m.mapPosY)/m.TILE_SIZE_Y].lightBlock){
                return false;
            }
            ynum+= deltay;
            if(ynum >= deltax){
                ynum -= deltax;
                y++;        
            }
        }
        return true;
    }

I assume you were reading from here:
http://www.gamedev.net/page/resources/_/technical/game-programming/line-drawing-algorithm-explained-r1275

Basically, like the one I showed, what you have coded there only works for 1/8th of the possible lines, you need to scroll down a bit on the page to learn what to change for the others. It is very similar to the first one, but just has a few signs changed and the like.

Also, would you mind explaining why you are accessing map tiles in that array, by minusing and dividing and casting?

Well, because the tile map moves, you need to make it relative to the tile map rather than the canvas surely?
EDIT: Also, shouldn’t that code at the bottom work then?

wait… are your x1, x2, y1, y2 coordinates referring to 2 individual pixels or 2 individual tiles?

If you use the bresenham on tile coordinates rather than pixels, you will need to do far fewer calculations, so it will be much faster. Sorry if I was unclear :wink:

For logic in tile based games, most calculations, such as pathfinding, lighting, etc. will use the tile as the smallest unit for calculation.

You’ve adapted the short bit of code from the middle of the page, the stuff at the very bottom should work, yes.

Right well currently it’s working on pixels… so yeah… I guess I should change that

To use it for tiles would it be exactly the same, but I just have to supply it with tile numbers instead of pixels then at the end check for tile numbers instead of the mess of code I currently have?

yep. You would access the array just by going

m.Map[x][y]

I hope it works out :wink:

hmm… I’ve changed it to that and it’s now not working… the joys of bug fixing, here I come!
EDIT: Derp, just didn’t change what I was printing to system xD may be why…

Well, I’ve got no errors, however my program just sits there on load… I think that it may be a little slow…

It should definitely not be so slow that your code doesn’t run… You should not even notice a low frame rate with only one light…

What actually happens? Does any lighting show up at all?

Nothing shows up… I was using 2 for loops to run through the x/y positions I wanted to check for lighting…
EDIT: Oh, It was due to a stupid error I made… no worries, seems to be working great :smiley: - Just need to clean it all up now, bit messy currently

hmm… would you like to post your code for some help, or try at it yourself some more? I can’t really tell much more without actually seeing what you’ve done…

It’ll work out in the end, don’t you worry :stuck_out_tongue:

Nah, it seems to be working fine now, thanks, I’ll fiddle around with it, to get it looking exactly how I want it, but the hard work I feel is pretty much done for now, I shall clean up my code and post it up, in case anyone else wants a peek at it…
Thanks for all the help! Everyone’s been really helpful. I’ll probably make a thread about my Game at some point so I can post more about it…

Oh, looks like some angles/lines may not be working… oops, will just check that out…
EDIT: Yeah it looks like when the line goes upwards and to the left it’s not working… need to check why that is…
I’ll post up my code and possibly some screenshots tomorrow, so you can see what’s happening, for now Im off to bed, as I am tired…
but it’s looking better than yesterday :slight_smile:

Ok, I’ll post up the code now, it’s not working for the top left hand side, when the line gets past the tile above the one that I’m checking from…

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package kingdom.blue;

import java.awt.Point;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

/**
 *
 * @author Tom
 */
public class TileTorch extends Tile {

    public TileTorch(int x, int y, map m){
        lightLevel = 5;
        floorBlock = false;
        lightSurroundings(x,y,m);
    }
    
    public void lightSurroundings(int x, int y,map m){
        
        int firstx = x-4;
        int firsty = y-4;
        
        
        for(int x1 = firstx;x1 < x+4;x1++){
            for(int y1 = firsty;y1 < y+4;y1++){
               if(tileVisible(x,x1,y,y1,m)){
                   if(x1 > -1 && x1 < map.WIDTH){
                       if(y1 > -1 && y1 < map.HEIGHT){
                            if(m.Map[x1][y1] != null){
                                m.Map[x1][y1].lightLevel = 5;
                                System.out.println("lighting tile!");
                            }
                        }
                    }    
               }
            }
        }

    }
    
    
    public static boolean tileVisible(int x1, int x2, int y1, int y2, map m){
        
        int xinc1;
        int xinc2;
        int yinc1;
        int yinc2;
        int abs;
        int den;
        int num;
        int numadd;
        int numTiles;
        int deltax = (int)(x2 - x1);          
        int deltay = (int)(y2 - y1);         
        int x = x1;                                 
        int y = y1;                                 

        if (x2 >= x1)                           
        {
            xinc1 = 1;
            xinc2 = 1;
        }
        else                                              
        {
            xinc1 = -1;
            xinc2 = -1;
        }

        if (y2 >= y1)                          
        {
            yinc1 = 1;
            yinc2 = 1;
        }
        else                                              
        {
            yinc1 = -1;
            yinc2 = -1;
        }

        if (deltax >= deltay)           
        {
            xinc1 = 0;                              
            yinc2 = 0;                              
            den = deltax;
            num = deltax / 2;
            numadd = deltay;
            numTiles = deltax;           
        }
        else                                              
        {
            xinc2 = 0;                              
            yinc1 = 0;                              
            den = deltay;
            num = deltay / 2;
            numadd = deltax;
            numTiles = deltay;           
        }

        for (int currentTile = 0; currentTile <= numTiles; currentTile++)
        {
            if(x > -1 && x <= map.WIDTH){
                if(y > -1 && y <= map.HEIGHT){
                    if(m.Map[x][y] != null){
                        if(m.Map[x][y].lightBlock){
                            return false;
                        }
                    }
                }
            }
            num += numadd;                          
            if (num >= den)                       
            {
                num -= den;                     
                x += xinc1;                     
                y += yinc1;                     
            }
            x += xinc2;                           
            y += yinc2;                           
        }
        return true;
    }

}

Now I really am off to bed, I’ll check back in the morning…

I’ve solved the problem, I used (int) instead of Maths.abs for some strange reason, can’t work out what I was thinking… maybe it was too late for my brain to work properly… who knows?

I’m now trying to figure out how to smooth the shadows, so they’re not so sharp… I thought about having it check all the tiles that the torch has lit and checking if they have any unlit tiles next to them, if they do, changing the unlit tile’s light value to something slightly higher… but that’d be messy…

I think that whatever you do, it’s going to involve iterating through all of the tiles in the range of the light. A different technique might be to check for dark tiles and make the dark tile brighter, depending on how many light tiles it borders with, but its a matter of lighting style choice, best way to do it is probably just to try a few different things yourself. Implement different ways of calculating lighting values for unlit tiles, until you find something you like.