Page 2 of 3

Re: Checking pixels in tmx files

Posted: Thu Apr 10, 2014 7:50 pm
by HugoBDesigner
szmol96 wrote:
HugoBDesigner wrote:The problem with pixel collision is that it is slow under most circumstances. Making the computer check thousands of pixels everytime is slow. Are you checking them every frame? If you are, just compare the pixels in an area close to the player (for example, pixels in a radius of 50 pixels around the player). Depending on what you have this can work very well :)
I only check pixels around the player and at some bullets' position. Is that still slow?
That depends on how exactly you are doing this. If you're making something like:

Code: Select all

for x = 1, imagewidth do
    for y = 1, imageheight do
        if x >= playerx-50 and x <= playerx+50 and y >= playery-50 and y <= playery+50 then
            --your code here
        end
    end
end
This WILL work, but even by checking if the pixel is close to the player (or whatever it is) you're still making the game check thousands of pixels everytime.

If you were doing this, try doing this instead:

Code: Select all

for x = playerx-50, playerx+50 do
    for y = playery-50, playery+50 do
        --your code here
    end
end
This way you can still check the collisions around the player, but you don't make your computer HAVE to check every single pixel.

If this wasn't the problem, I'd like to have the code (or, if you don't wanna share, at least part of it) so I can see your problem :)

Re: Checking pixels in tmx files

Posted: Thu Apr 10, 2014 8:13 pm
by szmol96
Here it is.

Edit: I forgot to tell, but I made it with 0.8.0.

Re: Checking pixels in tmx files

Posted: Sun Apr 13, 2014 4:38 pm
by szmol96
Have you found a solution?

Re: Checking pixels in tmx files

Posted: Sun Apr 13, 2014 5:47 pm
by HugoBDesigner
szmol96 wrote:Have you found a solution?
Oh, sorry, I almost forgot to post here again :oops:

Well, I don't know exactly what way you were doing it. I looked through your code and I found it a bit confusing. You have 2 functions to calculate collisions: one that checks a vertical line, other that checks an horizontal. You were checking them only once, and from the first pixel until a bit after the player's position. That means that the further you go, the slower your game gets. If I were to choose another way of doing it, I'd use the the way I told before:

Code: Select all

for x = 1, imagewidth do
    for y = 1, imageheight do
        if x >= playerx-50 and x <= playerx+50 and y >= playery-50 and y <= playery+50 then
            --your code here
        end
    end
end
This will be slow too, so here's another solution I came up with:

If you've got all the pixels maped somewhere already, in the code's place you can just check them. If not, make this while loading each level:

Code: Select all

pixelmap = {}
for x = 1, imagewidth do
    for y = 1, imageheight do
        local r, g, b, a = imagedata:getPixel(x-1, y-1)
        if a == 255 then
            pixelmap[x.."-"..y] = true
        end
    end
end
And on your last code, make this:

Code: Select all

for x = math.max(1, playerx-50), math.min(imagewidth, playerx+50) do
    for y = math.max(1, playery-50), math.min(imageheight, playery+50) do
        if pixelmap[x.."-"..y] then
            --your collision code here
        end
    end
end
Storing data is a lot quicker than loading it every frame, and checking only the necessary pixels instead of all them is even more quicker. Instead of reading lines and columns as you were doing, check a rectangle area. It's more accurate, and not too laggy :)

Re: Checking pixels in tmx files

Posted: Mon Apr 14, 2014 4:07 pm
by szmol96
Does the checking speed depend on the image color? I mean, would a seperate black and white collision mask speed up the process?

Re: Checking pixels in tmx files

Posted: Mon Apr 14, 2014 4:13 pm
by HugoBDesigner
szmol96 wrote:Does the checking speed depend on the image color? I mean, would a seperate black and white collision mask speed up the process?
No, it isn't. If you use my method, the only thing that will matter is transparency. Fully opaque pixels will be solid, others (with alpha smaller than 255) won't.
I don't know if there is a way of compressing the image, though, nor if this matter. But, f it is still laggy, try changing the value on the collision checking to a smaller one (for example, change the 50 - in the example I gave - by 30) :)

Re: Checking pixels in tmx files

Posted: Thu Apr 17, 2014 5:37 pm
by szmol96
I have tried your method, and i think nothing is wrong with it. But there is a problem...again. I made a 2560x1920 map image for testing and the game was stuck with loading it, that's why i was asking the original question. If I can't check pixels in .tmx files, then can I make a tilemap and check the pixels in the tile images?

Re: Checking pixels in tmx files

Posted: Thu Apr 17, 2014 6:49 pm
by HugoBDesigner
szmol96 wrote:I have tried your method, and i think nothing is wrong with it. But there is a problem...again. I made a 2560x1920 map image for testing and the game was stuck with loading it, that's why i was asking the original question. If I can't check pixels in .tmx files, then can I make a tilemap and check the pixels in the tile images?
Even though it is wrote RIGHT IN THE SUBJECT, I didn't realized you were working with tmx files. I'm dumb, sorry :(

Anyway, the code I wrote is for normal images (love.image.newImageData(path) ), but it works very well. I don't know about .tmx files, though. Also, as far as I know, in a lot of computers LÖVE doesn't loads images bigger than 512x512. If I were you, I'd split it in a few sections and read them one by one.

If you're going to use my code (must use images as .png, .jpg or .gif, but .png is more likely to work), I can make a code pretty easily to detect collisions in each image without slowing down your PC. Otherwise, I'm sorry, but I don't think I can help you...

Re: Checking pixels in tmx files

Posted: Thu Apr 17, 2014 6:59 pm
by szmol96
I was thinking about making a tilemap like this:

Code: Select all

map={
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
   { 0, 1, 0, 0, 2, 2, 2, 0, 3, 0, 3, 0, 1, 1, 1, 0, 0, 0, 0, 0},
   { 0, 1, 0, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0},
   { 0, 1, 1, 0, 2, 2, 2, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
   { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
   { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0},
   { 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
   { 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
   { 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 2, 2, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
And then checking pixels in each tile or at least which are on screen.

Re: Checking pixels in tmx files

Posted: Thu Apr 17, 2014 7:07 pm
by HugoBDesigner
So I think you can pretty much still use my code, just make these change:
HugoBDesigner wrote:

Code: Select all

pixelmap = {}
for y = 1, #map do
    for x = 1, #map[y] do
        local a = map[y][x]
        if a == 1 then
            pixelmap[x.."-"..y] = true
        end
    end
end

Code: Select all

for y = math.max(1, playery-50), math.min(#map, playery+50) do
    for x = math.max(1, playerx-50), math.min(#map[y], playerx+50) do
        if pixelmap[x.."-"..y] then
            --your collision code here
        end
    end
end
Just one last thing: In the first code, in the "if a == 1 then " part, I kind of guessed "1" as a collideable tile. If it isn't, or if there is more than 1 collision tile, just change that line :)