I tried to make a little minigame sort of thing where you throw balls from a cannon and they collide with the walls and between themselves. The problem is that the angle-related code I wrote is probably VERY wrong, so you have now a general-buggy-physics app. Enjoy... I think...
Code: Select all
-- LÖVE Code Doodle #7
-- by HugoBDesigner
-- Completely failed :P
function love.load()
wallsize = 20
spawnx = 400
spawny = 300
shotangle = 0
minspeed = 1000
maxspeed = 1500
minsize = 10
maxsize = 30
minlifetime = 5
maxlifetime = 20
shotimg = love.image.newImageData(shoot.width, shoot.height)
for x = 0, shoot.width-1 do
for y = 0, shoot.height-1 do
local v = x*shoot.width+y+1
local r, g, b, a = unpack(shoot.pixels[v])
shotimg:setPixel(x, y, r, g, b, a)
end
end
shotimg = love.graphics.newImage(shotimg)
balls = {}
toremove = {}
love.graphics.setLineWidth(2)
end
function love.update(dt)
local x, y = love.mouse.getPosition()
shotangle = convertAngle(math.atan2(y-spawny, x-spawnx))
for i, v in ipairs(toremove) do
table.remove(balls, v)
end
toremove = {}
for i, v in ipairs(balls) do
--Collisions with walls (at least these work)
if v.x-v.size < wallsize then
v.speedx = -v.speedx
v.x = wallsize+v.size
elseif v.x+v.size > 800-wallsize then
v.speedx = -v.speedx
v.x = 800-wallsize-v.size
end
if v.y-v.size < wallsize then
v.speedy = -v.speedy
v.y = wallsize+v.size
elseif v.y+v.size > 600-wallsize then
v.speedy = -v.speedy
v.y = 600-wallsize-v.size
end
--Collisions between balls
for j, w in pairs(balls) do
if j ~= i then
if dist(v.x, v.y, w.x, w.y) < v.size+w.size then
local toadd = (dist(v.x, v.y, w.x, w.y) - v.size+w.size)
local spd1 = convertAngle(math.atan2(v.speedy, v.speedy))
local spd2 = convertAngle(math.atan2(w.speedy, w.speedy))
v.speedx = -speedX(v.speed, spd1)
v.speedy = -speedY(v.speed, spd1)
w.speedx = -speedX(w.speed, spd2)
w.speedy = -speedY(w.speed, spd2)
v.x = v.x + speedX(toadd/2, spd1)
v.y = v.y + speedY(toadd/2, spd1)
w.x = w.x + speedX(toadd/2, spd2)
w.y = w.y + speedY(toadd/2, spd2)
end
end
end
--Speed setting
v.x = v.x+ dt*v.speedx
v.y = v.y+ dt*v.speedy
v.lifetime = v.lifetime - dt
if v.lifetime <= 0 then
v.lifetime = 0
table.insert(toremove, i)
end
end
end
function love.draw()
--Walls
love.graphics.setColor(255*.5, 255*.5, 255*.5, 255)
love.graphics.rectangle("fill", 0, 0, wallsize, 600)
love.graphics.rectangle("fill", 800-wallsize, 0, wallsize, 600)
love.graphics.rectangle("fill", wallsize, 0, 800-2*wallsize, wallsize)
love.graphics.rectangle("fill", wallsize, 600-wallsize, 800-2*wallsize, wallsize)
--Balls
for i, v in pairs(balls) do
local alpha = 255
if v.lifetime <= 1 then
alpha = 255*v.lifetime
end
love.graphics.setColor(v.color[1], v.color[2], v.color[3], alpha)
love.graphics.circle("fill", v.x, v.y, v.size, 32)
love.graphics.setColor(v.color[1]*.5, v.color[2]*.5, v.color[3]*.5, alpha)
love.graphics.circle("line", v.x, v.y, v.size, 32)
end
--Shooter
love.graphics.setColor(255, 255, 255, 255)
love.graphics.draw(shotimg, spawnx, spawny, shotangle, 1, 1, shotimg:getWidth()/2, shotimg:getHeight()/2)
end
function love.mousepressed(x, y, button)
if button == "l" then
spawnball()
end
end
function love.keypressed(key, unicode)
if key == "escape" then
love.event.quit()
end
end
function convertAngle(a) --Probably wrong
local a = a
a = math.pi-a
return math.offset(math.abs(a)+math.pi/2, 0, math.pi*2, math.pi*2)
end
function math.offset(n, mn, mx, f)
local n = n
local f = f or mx
if math.abs(mn-mx) > f then f = mx end
while n >= mx do
n = n - f
end
while n < mn do
n = n + f
end
return n
end
function speedX(angle, speed)
return -math.sin(angle)*speed
end
function speedY(angle, speed)
return math.cos(angle)*speed
end
function randomColor()
return {math.random(155, 255), math.random(155, 255), math.random(155, 255)}
end
function spawnball()
local b = {}
b.x = spawnx
b.y = spawny
b.speed = math.random(minspeed, maxspeed)
b.speedx = speedX(b.speed, shotangle)
b.speedy = speedY(b.speed, shotangle)
b.lifetime = math.random(minlifetime, maxlifetime)
b.size = math.random(minsize, maxsize)
b.color = randomColor()
table.insert(balls, b)
end
function dist(x1, y1, x2, y2, ab)
local ab = ab or true
local w, h = x1-x2, y1-y2
if ab then
w = math.abs(w)
h = math.abs(h)
end
return math.sqrt(w^2+h^2)
end
at the end (it's the code to load the image. It's too big, thus I uploaded it separately, but runs fine with the code)...