I've been coding in Lua for a couple of days now with Löve.
I've written a little tower defence test case but my code to find targets in range doesn't seem to work. It seems to think everything is in range... I cant figure out what I've done wrong here.... And then it seems to randomly kill targets rather than killing the closest one... Something wrong with my distance formula?
Code: Select all
function love.load()
squares = {}
towers = {}
speed = 50
sqcount = 0
ball = love.graphics.newImage("ball.png")
rotation = 0
target = {}
target.x = 400
target.y = 400
effects = {} -- This will hold projectiles, beams and particles
end
function love.mousepressed(x,y,button)
if button == "l" then
sqcount = sqcount + 1
square = {}
square.x = x
square.y = y
square.mx = 0
square.my = 0
square.mm = 1
table.insert(squares, square)
elseif button == "r" then
tower = {}
tower.x = x
tower.y = y
tower.r = 50 -- Range
tower.fr = 1 -- time between shots in seconds
tower.lf = 0 -- Elapsed time since last fired
table.insert(towers, tower)
elseif button == "m" then
target.x = x
target.y = y
end
currentmx = target.x
currentmy = target.y
for i,v in ipairs(squares) do
if v.x < currentmx and v.y > currentmy then
mode2 = math.sqrt((currentmx-v.x)^2+(v.y-currentmy)^2)
if mode2 > 20 then
ratio2 = 1 / mode2
v.mx = ratio2 * (currentmx-v.x) * speed
v.my = ratio2 * (v.y-currentmy) * speed
v.mm = 2
end
elseif v.x > currentmx and v.y > currentmy then
mode3 = math.sqrt((v.x-currentmx)^2+(v.y-currentmy)^2)
if mode3 > 20 then
ratio3 = 1 / mode3
v.mx = ratio3 * (v.x-currentmx) * speed
v.my = ratio3 * (v.y-currentmy) * speed
v.mm = 3
end
elseif v.x > currentmx and v.y < currentmy then
mode4 = math.sqrt((v.x-currentmx)^2+(currentmy-v.y)^2)
if mode4 > 20 then
ratio4 = 1 / mode4
v.mx = ratio4 * (v.x-currentmx) * speed
v.my = ratio4 * (currentmy-v.y) * speed
v.mm = 4
end
elseif v.x < currentmx and v.y < currentmy then
mode5 = math.sqrt((currentmx-v.x)^2+(currentmy-v.y)^2)
if mode5 > 20 then
ratio5 = 1 / mode5
v.mx = ratio5 * (currentmx-v.x) * speed
v.my = ratio5 * (currentmy-v.y) * speed
v.mm = 5
end
else
v.mm = 1
end
end
end
function love.update(dt)
for i,v in ipairs(towers) do
v.lf = v.lf + dt -- Set or add to last fired time
if v.lf > v.fr then
creepsinrange = {}
tox = v.x
toy = v.y
for is,vs in ipairs(squares) do
distance = math.sqrt((fdiff(tox, vs.x))^2+(fdiff(vs.y, toy))^2)
if distance > v.r then
inrange = 1
end
if distance <= v.r then
inrange = 0
end
if inrange == 0 then
creepinrange = {}
creepinrange.id = ii
creepinrange.dist = distance
table.insert(creepsinrange, creepinrange)
end
end
-- Closest code
table.remove(squares, fclosest(creepsinrange))
v.lf = 0
closest = nil
closestdist = nil
creepsinrange = nil
end
end
rotation = rotation + 10 * dt
for i,v in ipairs(squares) do
if v.mm == 2 then
v.x = v.x + v.mx * dt
v.y = v.y - v.my * dt
elseif v.mm == 3 then
v.x = v.x - v.mx * dt
v.y = v.y - v.my * dt
elseif v.mm == 4 then
v.x = v.x - v.mx * dt
v.y = v.y + v.my * dt
elseif v.mm == 5 then
v.x = v.x + v.mx * dt
v.y = v.y + v.my * dt
end
end
end
function love.draw()
for i,v in ipairs(squares) do -- Draws creeps
love.graphics.draw(ball, v.x, v.y, rotation, 1, 1, 8, 8)
end
for i,v in ipairs(towers) do -- Draws towers
love.graphics.rectangle("fill", v.x, v.y, 5, 5)
love.graphics.circle("line", v.x, v.y, v.r, 50)
end
love.graphics.setColor(255,255,255,255)
fps = love.timer.getFPS()
love.graphics.print("FPS: " .. fps, 10, 10)
love.graphics.print("Square Count: " .. sqcount, 10, 30)
end
function fdiff(numbera, numberb)
local xdiff
if numbera > numberb then
xdiff = numbera - numberb
return xdiff
elseif numbera < numberb then
xdiff = numberb - numbera
return xdiff
else
return 0
end
end
function fclosest(stable)
for ikey,ival in ipairs(stable) do
if cl == nil then
cl = ival.id
cldist = ival.dist
elseif ival.dist < closestdist then
cldist = ival.dist
cl = ival.id
end
end
return cl
end
Left click places creeps, middle click creates a direction for the creeps to head in. right click creates towers.