Page 2 of 2

Re: Collision detection without physics?

Posted: Thu Apr 25, 2019 1:17 pm
by Przemator
I've been considering this, but each track also has parameters: acceleration and turn rate per each update (e.g. move by 10 pixels and rotate by 4 degrees). It's just all not physics-based.

Re: Collision detection without physics?

Posted: Thu Apr 25, 2019 3:27 pm
by pgimeno
I've implemented this kind of pixel-based collision in Thrust II Reloaded (see my sig for the full code).

What I do is draw in a small canvas the portion of the collision mask corresponding to the map and enemies around the player, then switch to multiplicative blending and draw the player's collision mask. Then I take the ImageData of the canvas and convert it to string, and compare the string with a precalculated string (don't create it every frame!) filled with all zeros.

Re: Collision detection without physics?

Posted: Fri Apr 26, 2019 8:54 am
by Przemator
Yes, I saw your code. It's a neat trick with the string. But I decided against it, since I would not like to use graphics functions for collision detections. Graphics functions can only run from the main thread, so this would be a limitation, should I choose to separate update from drawing. In the end I think I will just go for a simple getPixel(x,y) to see if the middle of the car is still on the track.

Re: Collision detection without physics?

Posted: Fri Apr 26, 2019 7:35 pm
by grump
Przemator wrote: Fri Apr 26, 2019 8:54 am I would not like to use graphics functions for collision detections. Graphics functions can only run from the main thread, so this would be a limitation, should I choose to separate update from drawing. In the end I think I will just go for a simple getPixel(x,y) to see if the middle of the car is still on the track.
If you want to solve this problem on a level that does not involve the actual rendered graphics, you need to build a representation of your game data that is on a higher level than just plain image files. Track boundaries can be represented by line segments; cars should be represented by geometric primitives, like boxes. Detecting and responding to collisions between boxes and line segments is "easy". Doing the same with pixels is hard - you won't be able to implement it, expect for trivial scenarios (no rotation, no scaling, and ideally no scrolling).

Re: Collision detection without physics?

Posted: Wed May 01, 2019 7:57 am
by Przemator
I implemented my collisions the following way: the collisions between cars are made using distance. I measure the distance between all cars then get the smallest distance that is below the threshold (say, 32 pixels). Then i "push" the cars away from each other. I repeat until all cars are at least 32 pixels away.

Then I apply track collision. For this I've been using ImageData, but it's been kind of slow. So i've tried a few other methods:

Code: Select all

    local cnt = 20000000
    local tab_x = {}
    local tab_y = {}

    local t0 = love.timer.getTime()
    for i = 1, cnt do
        tab_x[i] = love.math.random() * w
        tab_y[i] = love.math.random() * h
    end
    local t1 = love.timer.getTime()
    print("random", t1 - t0)

    for i = 1, cnt do
        local x, y = tab_x[i], tab_y[i]
        local r, g, b, a = self.maskdata:getPixel(x, y)
    end
    local t2 = love.timer.getTime()
    print("getpix", t2 - t1)

    for i = 1, cnt do
        local x, y = tab_x[i], tab_y[i]
        local r = self.masktab[math.floor(x)][math.floor(y)]
    end
    local t3 = love.timer.getTime()
    print("tables", t3 - t2)

    for i = 1, cnt do
        local x, y = tab_x[i], tab_y[i]
        local loc = (math.floor(y) * w + math.floor(x)) * 4 + 1
        local r = string.byte(self.masktext, loc)
    end
    local t4 = love.timer.getTime()
    print("string", t4 - t3)
And the result:

Code: Select all

random  1.0678514140891
getpix  1.0594320619712
tables  0.17795943294186
string  0.11870640702546
So working with string is somehow the fastest, 10x faster than getPixel.