## [Solved] Mouse click weirdness

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

### [Solved] Mouse click weirdness

hi
I made a little game out of what I've been learning in Love2d but I have a weird issue happening with the mouse clicks. If you start the game and click the circles they disappear fine, but if you let a couple spawn sometimes the one you are clicking will become immune and a random circle will disappear, then it will start working again, on and off. Anyone have any ideas about this, maybe its not updating mouse position or miss reading it.
cheers for taking a look.

Code: Select all

--[[
Rings Game
Digitalrecline
Auckland(NZ)
Practice exersie with Lua and Love2D August 2017
]]

-- Declcare Variables
spawntimer = 1 -- time to spawn

rings ={} -- table to hold the rings we create

ringWidth = 20 -- line width for our rings

ringColour = {} -- our colour palete
ringColour[1] = {col='green',r=70,g=140,b=38,a=255,vel=0.15,score= 15}
ringColour[2] = {col='pink',r=163,g=73,b=115,a=255,vel=0.16,score= 16}
ringColour[3] = {col='blue',r=93,g=132,b=166,a=255,vel=0.14,score= 14}
ringColour[4] = {col='yellow',r=242,g=222,b=160,a=255,vel=0.2,score= 20}
ringColour[5] = {col='tan',r=242,g=220,b=201,a=255,vel=0.13,score= 13}

ringToBig = 250 -- ring explodes as got to big - points from player score
playerScore = 0

--[[
Our functions
]]

function randomCircle() -- randomCircle() creates our randomCircle variables
rR = love.math.random(20, 100) -- random radius
rX = love.math.random(0+rR, love.graphics.getWidth() - (rR + ringWidth) - ringToBig) --random x
rY = love.math.random(0+rR, love.graphics.getHeight()- (rR + ringWidth) - ringToBig) -- random y
rColour = love.math.random(1, #ringColour) --sets random colour and velocity
end

--[[newRing() creates our rings and test to see if the collide on creation.
1st ring created before it starts seeing if they subsequent ones overlap.]]
local function newRing()
if (#rings) == 0 then -- makes first ring if no exist
randomCircle()
myNewRing = {
r= rR,x= rX,y =rY, colr=ringColour[rColour].r,
colg=ringColour[rColour].g,colb=ringColour[rColour].b,
cola=ringColour[rColour].a,vel=ringColour[rColour].vel,
score=ringColour[rColour].score
}
table.insert(rings, myNewRing) -- adds new ring to our table
spawntimer = 1 -- sets the time before next ring is spawned
else
while true do -- infinate loop to create new rings
randomCircle()
local collides = false
for i, v in ipairs(rings) do
--[[ collison calculations on all rings in table until a collison
is detected using pythagoras to calculate distance]]
local dx = rX - v.x
local dy = rY - v.y
local distCalc = dx * dx + dy * dy
if distCalc <= ((v.r + ringWidth) + (rR + ringWidth))^2 then
collides = true
break -- restarts while loop once one collision is found
end -- end if distCalc block
end -- i,v block
if not collides then -- adds to rings table if no collisions
myNewRing = {
r= rR,x= rX,y =rY, colr=ringColour[rColour].r,
colg=ringColour[rColour].g,colb=ringColour[rColour].b,
cola=ringColour[rColour].a,vel=ringColour[rColour].vel,
score=ringColour[rColour].score
}
table.insert(rings, myNewRing)
spawntimer = 1
break
end -- end if not collides block
end -- end while loop
end
end

function collision()

-- remove all collided rings
for k = #rings, 1, -1 do
local rX = rings[k].x
local rY = rings[k].y
local rR = rings[k].r
local collides
for j = k + 1, #rings do
local dx = rX - rings[j].x
local dy = rY - rings[j].y
sj = rings[j].score
sk = rings[k].score

local distCalc = dx * dx + dy * dy
if distCalc <= ((rings[j].r + ringWidth) + (rR ))^2 then
collides = true
break
end
end
if collides then
-- do something here (erase ring[k] from the screen, etc.)
table.remove(rings, k)
table.remove(rings, j)
playerScore = playerScore - (sj + sk)
end
end
end

-- remove ring if radius greater than 150
function ringsRemove()
if (#rings) > 1 then
for i, v in ipairs(rings) do
if rings[i].r > 150 then
playerScore = playerScore - rings[i].score
table.remove(rings, i)
end -- end if
end -- i,v block
end -- end while loop
end

function mouseRemove(R)
local collides = false
for i, v in ipairs(rings) do
--[[ collison calculations on all rings in table until a collison
is detected using pythagoras to calculate distance between
mouse x,y + a little radius around pointer (rR) and
local dx = mX - v.x
local dy = mY - v.y
local distCalc = dx * dx + dy * dy
if distCalc <= (v.r + R)^2 + ringWidth then
collides = true
playerScore = playerScore + rings[i].score
end -- end if distCalc block
end -- i,v block
if collides then -- removes ring from table if mouse clicks it
table.remove(rings, i)

end -- end if not collides block
end -- end

-- remove ring if radius greater than ringToBig
function ringsRemove()
if (#rings) > 1 then
for i, v in ipairs(rings) do
if rings[i].r + ringWidth > ringToBig then
playerScore = playerScore - rings[i].score
table.remove(rings, i)
end -- end if
end -- i,v block
end -- end while loop
end

--[[***************************************************************************
******************************************************************************]]
--  local collides = false
-- body...
mX = 0 -- set mouse x to 0
mY = 0 --set mouse y to 0
--font40 = love.graphics.newFont("BAUHS93.TTf", 40)
--font18 = love.graphics.newFont("BAUHS93.TTf", 18)
end

function love.draw()
love.graphics.setBackgroundColor(252, 251, 227, 255) -- sets background colour

--[[Scoreboard]]
love.graphics.setColor(0, 0, 0, 255)
--  love.graphics.setFont(font40)
love.graphics.print(playerScore, 100,50)

--[[Debugging]]
--    love.graphics.setFont(font18)
--    love.graphics.print(mX .. " " .. mY, mX, mY) -- mouse position
--    love.graphics.setColor(0, 0, 0, 255) -- temp graphics colour ** Black
--    love.graphics.print(spawntimer) -- prits spawntimer to screen for debugging
--[[Draw my rings]]
for i,v in ipairs(rings) do -- draws our rings and changes the colour
love.graphics.setLineWidth(ringWidth) -- sets ring linewidth
love.graphics.setColor(rings[i].colr, rings[i].colg, rings[i].colb, rings[i].cola)
love.graphics.circle('line', v.x, v.y, v.r, 64)
end

end

function love.update(dt)

--mouse clicked position
function love.mousepressed(x, y, button, istouch)
if button == 1 then
mX = x
mY = y
mouseRemove(10) -- removes circle if clicked mouseRemove(mousePointerRadius)
end
end

if #rings >= 2 then
collision() -- removes rings that grow and collide
end

for i,v in ipairs(rings) do
--[[grows our rings via the vel set in ringColour then added to rings table when
the ring is created ]]
rings[i].r = rings[i].r + rings[i].vel
end

ringsRemove() -- rings get to big remove it

if spawntimer > 0 then  -- countdown to spawn rings if time remaining greater than 0
spawntimer = spawntimer - dt
else
newRing() -- creates new ring if spawntimer runs out
end

end

regards
Attachments
cClicker.love
Last edited by Vmpwraith on Tue Aug 08, 2017 8:27 pm, edited 1 time in total.

0x72
Citizen
Posts: 51
Joined: Thu Jun 18, 2015 9:02 am

### Re: Mouse click weirdness

In mouseRemove function in line table.remove(rings, i): i variable is always nil because it's not set in this scope. The i variable form the for loop is scoped to the for loop.

table.remove(a, nil) is the same as table.remove(a) is the same as table.remove(a, #a) (docs)

Instead of setting colides = true you can (for example) have col_id = nil and set it to whatever i is during the collision test.

Code: Select all

function mouseRemove(R)
local col_id = nil  -- change
for i, v in ipairs(rings) do
local dx = mX - v.x
local dy = mY - v.y
local distCalc = dx * dx + dy * dy
if distCalc <= (v.r + R)^2 + ringWidth then
col_id = i  -- change
playerScore = playerScore + rings[i].score
end
end
if col_id then
table.remove(rings, col_id) -- change
end
end


ivan
Party member
Posts: 1549
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Mouse click weirdness

Furthermore, when you want to remove elements DURING iteration, make sure you are going in reverse:

Code: Select all

-- remove ring if radius greater than ringToBig
function ringsRemove()
for i = #rings, 1, -1 do
local v = rings[i]
if v.r + ringWidth > ringToBig then
playerScore = playerScore - v.score
table.remove(rings, i)
end
end
end

Vmpwraith
Prole
Posts: 9
Joined: Thu Jan 15, 2015 12:00 am

### Re: Mouse click weirdness

Awsome thankyou 0x72 and Ivan. Cheers for the Doc's link I hadn't realized I wasn't sending it the "i" and just amused it was getting the correct information. Also cheers Ivan it makes sense to go in reverse.

### Who is online

Users browsing this forum: No registered users and 8 guests