[solved] Not sure why I'm getting Circular Collisions drawn

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

[solved] Not sure why I'm getting Circular Collisions drawn

Post by Vmpwraith »

Hi this is a simple love program. Spawn a random circle every 5 secs that don't overlap with previous circles in the array until it cant fill any more. I'm not sure why it starts drawing overlapping circles when there is still plenty of space available onscreen for circles to be drawn in. I cant see the error in my collision function am i not checking distance between circled and radius's correctly?

cheers in advance for you help.

Code: Select all

rings = {}
rings[1] = {x=100,y=250,storedRadius=25}

ringColour = {}

ringColour['green'] = {r=70,g=140,b=38,a=255}
ringColour['pink'] = {r=163,g=73,b=115,a=255}
ringColour['blue'] = {r=93,g=132,b=166,a=255}
ringColour['yellow'] = {r=242,g=222,b=160,a=255}
ringColour['tan'] = {r=242,g=220,b=201,a=255}

count =0

function spawntimer(time)
spawntime = time or 5
return spawntime
end

function randRings()
    ringRadius = love.math.random(15 , 100)
    xRand = love.math.random(0 + ringRadius, love.graphics.getWidth() - ringRadius )
    yRand = love.math.random(0 + ringRadius, love.graphics.getHeight() - ringRadius )
    randColourNumber = love.math.random(1, #ringColour)
    return ringRadius, xRand, yRand, randColourNumber
end

function checkCircularCollision(ax, ay, bx, by, ar, br)
    randRings()
    local    bx = xRand
    local    by = yRand
    local    br = ringRadius

    for i,v in ipairs(rings) do
        ax = rings[i].x
        ay = rings[i].y
        ar = rings[i].storedRadius
    end

	local dx = bx - ax
	local dy = by - ay
	-- local dist = math.sqrt(dx * dx + dy * dy)
if dx^2 + dy^2 > (ar + br)^2 then

return    true
else
    return false
--	return dist > 2*(ar + br)
end
end

function love.load(arg)
    -- body...
    spawntimer()
end

function love.draw(dt)
    -- body...
        love.graphics.setBackgroundColor(ringColour.pink.r, ringColour.pink.g, ringColour.pink.b, ringColour.pink.a)

        love.graphics.print(spawntime, 100 , 100)
        love.graphics.print(count, 100 ,200)
    for i,v in ipairs(rings) do

        love.graphics.circle("line", v.x, v.y, v.storedRadius, 32)
    end



end

function love.update(dt)
    -- body...
if spawntime > 0 then
spawntime = spawntime - dt
end

if  spawntime <= 0  then
    checkCircularCollision()
    if checkCircularCollision() == true then
        table.insert(rings, {x= xRand,
                            y = yRand,
                            storedRadius = ringRadius,
                            })
    spawntimer()
else
    checkCircularCollision()
end
end

end
Attachments
circles.love
(900 Bytes) Downloaded 132 times
Last edited by Vmpwraith on Mon Aug 07, 2017 11:44 am, edited 1 time in total.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Not sure why I'm getting Circular Collisions drawn

Post by bartbes »

Perhaps because you're only checking for collision with the last circle?

Code: Select all

    for i,v in ipairs(rings) do
        ax = rings[i].x
        ay = rings[i].y
        ar = rings[i].storedRadius
    end

    local dx = bx - ax
    local dy = by - ay
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

Re: Not sure why I'm getting Circular Collisions drawn

Post by Vmpwraith »

Ah makes sense. I'll try to fix that.
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

Re: Not sure why I'm getting Circular Collisions drawn

Post by Vmpwraith »

Still having issues getting this to loop correctly through all values in the array.Currently crashes trying to create 2nd circle. Any help greatly appreciated.

Code: Select all

spawntimer = 1

rings ={}

function love.load(arg)
    -- body...
end

function love.draw()
    -- body...
    love.graphics.print(spawntimer)
for i,v in ipairs(rings) do
    -- body...
    love.graphics.circle('line', v.x, v.y, v.r, 32)
end

end

function love.update(dt)
    -- body...
    local   function newRing()
                if (#rings) == 0 then
                    rR = love.math.random(20, 100)
                    rX = love.math.random(0+rR, love.graphics.getWidth())
                    rY = love.math.random(0+rR, love.graphics.getHeight())
                    newRing = {r= rR,x= rX,y =rY}
                    table.insert(rings, newRing)
                    spawntimer = 2
                else
                    newDist = true
                        while newDist == true do
                            rR = love.math.random(20, 100)
                            rX = love.math.random(0 + rR, love.graphics.getWidth() - rR)
                            rY = love.math.random(0 + rR, love.graphics.getHeight() + rR)
                            for i=1,#rings do
                                -- body...
                                for k,v in pairs(rings[i]) do
                                        -- body...
                                    local dx = rX - rings[i].x
                                    local dy = rY - rings[i].y
                                    local distCalc = math.sqrt(dx * dx + dy * dy)
                                        if distCalc > (rings[i].r + rR)^2 then
                                            newRing = {r= rR,x= rX,y =rY}
                                            table.insert(rings, newRing)
                                            spawntimer = 3
                                            newDist = false
                                            else
                                            newDist = true
                                        end
                                end
                            end
                        end
                end
            end

    if spawntimer > 0 then
        spawntimer = spawntimer - dt
        else
        newRing()
    end

end
Attachments
CirclesNew.love
(1010 Bytes) Downloaded 127 times
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Not sure why I'm getting Circular Collisions drawn

Post by bartbes »

You should really fix your indentation.. it looks like you're mixing tabs and spaces.

Code: Select all

newDist = true
while newDist == true do
	rR = love.math.random(20, 100)
	rX = love.math.random(0 + rR, love.graphics.getWidth() - rR)
	rY = love.math.random(0 + rR, love.graphics.getHeight() + rR)
	for i=1,#rings do
		for k,v in pairs(rings[i]) do
			local dx = rX - rings[i].x
			local dy = rY - rings[i].y
			local distCalc = math.sqrt(dx * dx + dy * dy)
			if distCalc > (rings[i].r + rR)^2 then
				newRing = {r= rR,x= rX,y =rY}
				table.insert(rings, newRing)
				spawntimer = 3
				newDist = false
			else
				newDist = true
			end
		end
	end
end
There's a couple of weird things here. First, you probably want to move that function definition out of love.update, you don't need to define the function again every single frame. Anyway, past that, there's this useless pairs, which means you loop way more often than you need to, since you'll loop over ring[1].r, ring[1].x and ring[1].y. And that's also where the problem lies, since you're setting newDist to true once you find a colliding ring, and you'll look at your newly inserted ring right after inserting it, you'll find a colliding ring. Try something like..

Code: Select all

newDist = true
while newDist == true do
	rR = love.math.random(20, 100)
	rX = love.math.random(0 + rR, love.graphics.getWidth() - rR)
	rY = love.math.random(0 + rR, love.graphics.getHeight() + rR)
	for i=1,#rings do
		local dx = rX - rings[i].x
		local dy = rY - rings[i].y
		local distCalc = math.sqrt(dx * dx + dy * dy)
		if distCalc > (rings[i].r + rR) then
			newRing = {r= rR,x= rX,y =rY}
			table.insert(rings, newRing)
			spawntimer = 3
			break
		end
	end
end
Note the break to stop iteration early.
By the way, you were also comparing the non-squared distance to the squared distance, so I fixed that too.

Or perhaps cleaner..

Code: Select all

while true do
	local rR = love.math.random(20, 100)
	local rX = love.math.random(0 + rR, love.graphics.getWidth() - rR)
	local rY = love.math.random(0 + rR, love.graphics.getHeight() + rR)
	local collides = false
	for i, v in ipairs(rings) do
		local dx = rX - v.x
		local dy = rY - v.y
		local distCalc = dx * dx + dy * dy
		if distCalc <= (v.r + rR)^2 then
			collides = true
			break
		end
	end
	if not collides then
		table.insert(rings, {r = rR, x = rX, y = rY})
		spawntimer = 3
		break
	end
end
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

[SOLVED] Not sure why I'm getting Circular Collisions drawn

Post by Vmpwraith »

Awesome. Thank-you for the advice, I was having difficulty with the break logic, and getting it to restart with new randoms. I hadn't even known "while true do" loops existed will do a little brushing up on them. Will also fix the indentation, looks like tabs were 4 spaces not 2.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: [solved] Not sure why I'm getting Circular Collisions drawn

Post by Ref »

You trying something like this?
Best!
Attachments
Bubbles.love
Simple circle drawing
(1.22 KiB) Downloaded 134 times
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 90 guests