Add files via upload

This commit is contained in:
Dangrain 2024-09-27 22:35:30 +02:00 committed by GitHub
parent 2018486abb
commit 3d87aaf5e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 629 additions and 2 deletions

View file

@ -0,0 +1,499 @@
-- Collider v2.0
local collider = {}
collider.colliders = {}
collider.boxIDs = {}
collider.circleIDs = {}
function collider.newBox(x, y, width, height, tag, trigger, debugColor)
local newBox = {}
newBox.x = x
newBox.y = y
newBox.width = width
newBox.height = height or newBox.width
newBox.tag = tag or 'none'
if trigger == nil then
newBox.trigger = false
else
newBox.trigger = trigger
end
newBox.debugColor = debugColor or {1,1,1}
newBox.ID = tostring('B'..#collider.boxIDs+1)
newBox.onTriggerEnter = onTriggerEnter or function(collider) end
newBox.onTriggerExit = onTriggerExit or function(collider) end
newBox.collisions = {}
newBox.lastFrameCollisions = {}
newBox.type = 'box'
newBox.superPoints = {
{
x = newBox.x,
y = newBox.y
},
{
x = newBox.x + newBox.width,
y = newBox.y + newBox.height
},
updatePoint = function(point, x, y)
newBox.superPoints[point].x = x
newBox.superPoints[point].y = y
end
}
function newBox.updatePos(newX, newY, center)
if center == nil then
center = false
end
if center == true then
newBox.x = newX - newBox.width/2
newBox.y = newY - newBox.height/2
else
newBox.x = newX
newBox.y = newY
end
newBox.superPoints.updatePoint(1, newBox.x, newBox.y)
newBox.superPoints.updatePoint(2, newBox.x + newBox.width, newBox.y + newBox.height)
end
function newBox.collidingWith(id)
return newBox.collisions[id] ~= nil
end
function newBox.getID()
return newBox.ID
end
-- NOT WORKING
function newBox.destroy()
for k,v in ipairs(collider.boxIDs) do
if v == newBox.ID then
v = nil
end
end
collider.colliders[newBox.ID] = nil
end
collider.colliders[newBox.ID] = newBox
newBox.IDindex = #collider.boxIDs + 1
collider.boxIDs[newBox.IDindex] = newBox.ID
return newBox
end
function collider.newCircle(x, y, radius, tag, trigger, debugColor)
local newCircle = {}
newCircle.x = x
newCircle.y = y
newCircle.radius = radius or 50
newCircle.tag = tag or 'none'
if trigger == nil then
newCircle.trigger = false
else
newCircle.trigger = trigger
end
newCircle.debugColor = debugColor or {1,1,1}
newCircle.ID = tostring('C'..#collider.circleIDs+1)
newCircle.onTriggerEnter = onTriggerEnter or function(collider) end
newCircle.onTriggerExit = onTriggerExit or function(collider) end
newCircle.collisions = {}
newCircle.lastFrameCollisions = {}
newCircle.type = 'circle'
function newCircle.updatePos(newX, newY)
newCircle.x = newX
newCircle.y = newY
end
function newCircle.collidingWith(id)
return newCircle.collisions[id] ~= nil
end
function newCircle.getID()
return newCircle.ID
end
-- NOT WORKING
function newCircle.destroy()
for k,v in ipairs(collider.circleIDs) do
if v == newCircle.ID then
v = nil
end
end
collider.colliders[newCircle.ID] = nil
end
collider.colliders[newCircle.ID] = newCircle
newCircle.IDindex = #collider.circleIDs + 1
collider.circleIDs[newCircle.IDindex] = newCircle.ID
return newCircle
end
function collider.update()
collider.updateBoxes()
collider.updateCircles()
end
function collider.overlapBox(boxX, boxY, width, height)
local collisions = {}
local superPoints = {
{
x = boxX,
y = boxY
},
{
x = boxX + width,
y = boxY + height
},
}
-- Against every other box
for kk,other in ipairs(collider.boxIDs) do
other = collider.colliders[other]
-- Look for an x plane and y plane intersection in superPoints
local spX = {false, false}
local spY = {false, false}
-- Loop through superPoints
for kkk,sp in ipairs(superPoints) do
if sp.x > other.superPoints[1].x and sp.x < other.superPoints[2].x then
spY[kkk] = true
end
if sp.y > other.superPoints[1].y and sp.y < other.superPoints[2].y then
spX[kkk] = true
end
end
-- Check if superPoints show a collision between my and other
if (spX[1] and spY[1]) or (spX[2] and spY[2]) or (spX[1] and spY[2]) or (spX[2] and spY[1]) then
collisions[other.ID] = other
end
end
-- Against every other circle
for kk,other in ipairs(collider.circleIDs) do
other = collider.colliders[other]
local testX = other.x
local testY = other.y
if (other.x < boxX) then
testX = boxX -- left edge
elseif (other.x > boxX + width) then
testX = boxY + width -- right edge
end
if (other.y < boxY) then
testY = boxY -- top edge
elseif (other.y > boxY + height) then
testY = boxY + height -- bottom edge
end
local distX = other.x - testX;
local distY = other.y - testY;
local distance = (distX * distX) + (distY * distY);
if distance <= other.radius * other.radius then
collisions[other.ID] = other
end
end
return collisions
end
function collider.overlapCircle(x, y, radius)
local collisions = {}
-- Against every other box
for kk,other in ipairs(collider.boxIDs) do
other = collider.colliders[other]
local testX = x
local testY = y
if (x < other.x) then
testX = other.x -- left edge
elseif (x > other.x + other.width) then
testX = other.x + other.width -- right edge
end
if (y < other.y) then
testY = other.y -- top edge
elseif (y > other.y + other.height) then
testY = other.y + other.height -- bottom edge
end
local distX = x - testX;
local distY = y - testY;
local distance = (distX * distX) + (distY * distY);
if distance <= radius * radius then
collisions[other.ID] = other
end
end
-- Against every other circle
for kk,other in ipairs(collider.circleIDs) do
other = collider.colliders[other]
local distX = x - other.x;
local distY = y - other.y;
local distance = (distX*distX) + (distY*distY);
if (distance <= (radius+other.radius) * (radius+other.radius)) then
collisions[other.ID] = other
end
end
return collisions
end
function collider.updateBoxes()
for k,v in ipairs(collider.boxIDs) do
v = collider.colliders[v]
for kk in pairs (v.collisions) do
v.collisions[kk] = nil
end
end
-- Check every box for any collisions
for k,my in ipairs(collider.boxIDs) do
my = collider.colliders[my]
-- Against every other box
for kk,other in ipairs(collider.boxIDs) do
other = collider.colliders[other]
-- Ignore if it is yourself
if kk ~= k then
-- Look for an x plane and y plane intersection in superPoints
local spX = {false, false}
local spY = {false, false}
-- Loop through superPoints
for kkk,sp in ipairs(my.superPoints) do
if sp.x > other.superPoints[1].x and sp.x < other.superPoints[2].x then
spY[kkk] = true
end
if sp.y > other.superPoints[1].y and sp.y < other.superPoints[2].y then
spX[kkk] = true
end
end
-- Check if superPoints show a collision between my and other
if (spX[1] and spY[1]) or (spX[2] and spY[2]) or (spX[1] and spY[2]) or (spX[2] and spY[1]) then
if not my.collisions[other.ID] ~= nil or not other.collisions[my.ID] ~= nil then
my.collisions[other.ID] = other
other.collisions[my.ID] = my
end
end
end
end
-- Against every other circle
for kk,other in ipairs(collider.circleIDs) do
other = collider.colliders[other]
local testX = other.x
local testY = other.y
if (other.x < my.x) then
testX = my.x -- left edge
elseif (other.x > my.x + my.width) then
testX = my.x + my.width -- right edge
end
if (other.y < my.y) then
testY = my.y -- top edge
elseif (other.y > my.y + my.height) then
testY = my.y + my.height -- bottom edge
end
local distX = other.x - testX;
local distY = other.y - testY;
local distance = (distX * distX) + (distY * distY);
if distance <= other.radius * other.radius then
my.collisions[other.ID] = other
other.collisions[my.ID] = my
end
end
end
-- Update collision status
for k,my in ipairs(collider.boxIDs) do
my = collider.colliders[my]
for kk,other in pairs(my.collisions) do
-- Check if its a new collision
if my.lastFrameCollisions[other.ID] == nil then
my.lastFrameCollisions[other.ID] = other
my.onTriggerEnter(collider.colliders[other.ID])
collider.colliders[other.ID].lastFrameCollisions[my.ID] = my
collider.colliders[other.ID].onTriggerEnter(my)
end
end
for kk,other in pairs(my.lastFrameCollisions) do
-- Check if collisions from last frame aren't there anymore
if my.collisions[other.ID] == nil then
my.lastFrameCollisions[other.ID] = nil
my.onTriggerExit(collider.colliders[other.ID])
collider.colliders[other.ID].lastFrameCollisions[my.ID] = nil
collider.colliders[other.ID].onTriggerExit(my)
end
end
end
end
function collider.updateCircles()
for k,v in ipairs(collider.circleIDs) do
v = collider.colliders[v]
for kk in pairs (v.collisions) do
v.collisions[kk] = nil
end
end
-- Check every circle
for k,my in ipairs(collider.circleIDs) do
my = collider.colliders[my]
-- Against every other box
for kk,other in ipairs(collider.boxIDs) do
other = collider.colliders[other]
local testX = my.x
local testY = my.y
if (my.x < other.x) then
testX = other.x -- left edge
elseif (my.x > other.x + other.width) then
testX = other.x + other.width -- right edge
end
if (my.y < other.y) then
testY = other.y -- top edge
elseif (my.y > other.y + other.height) then
testY = other.y + other.height -- bottom edge
end
local distX = my.x - testX;
local distY = my.y - testY;
local distance = (distX * distX) + (distY * distY);
if distance <= my.radius * my.radius then
my.collisions[other.ID] = other
other.collisions[my.ID] = my
end
end
-- Against every other circle
for kk,other in ipairs(collider.circleIDs) do
if k ~= kk then
other = collider.colliders[other]
local distX = my.x - other.x;
local distY = my.y - other.y;
local distance = (distX*distX) + (distY*distY);
if (distance <= (my.radius+other.radius) * (my.radius+other.radius)) then
my.collisions[other.ID] = other
other.collisions[my.ID] = my
end
end
end
end
-- Update collision status
for k,my in ipairs(collider.circleIDs) do
my = collider.colliders[my]
for kk,other in pairs(my.collisions) do
-- Check if its a new collision
if my.lastFrameCollisions[other.ID] == nil then
my.lastFrameCollisions[other.ID] = other
my.onTriggerEnter(collider.colliders[other.ID])
collider.colliders[other.ID].lastFrameCollisions[my.ID] = my
collider.colliders[other.ID].onTriggerEnter(my)
end
end
for kk,other in pairs(my.lastFrameCollisions) do
-- Check if collisions from last frame aren't there anymore
if my.collisions[other.ID] == nil then
my.lastFrameCollisions[other.ID] = nil
my.onTriggerExit(collider.colliders[other.ID])
collider.colliders[other.ID].lastFrameCollisions[my.ID] = nil
collider.colliders[other.ID].onTriggerExit(my)
end
end
end
end
function collider.draw()
for k,id in ipairs(collider.boxIDs) do
local v = collider.colliders[id]
if v ~= nil then
love.graphics.setColor(v.debugColor)
love.graphics.rectangle('line', v.x, v.y, v.width, v.height)
love.graphics.circle('fill', v.x + v.width/2, v.y + v.height/2, 3)
for kk,vv in ipairs(v.superPoints) do
love.graphics.circle('fill', vv.x, vv.y, 3)
end
love.graphics.print(v.ID, v.x + 5, v.y - 15)
love.graphics.print(v.tag, v.x + 5, v.y)
end
end
for k,id in ipairs(collider.circleIDs) do
local v = collider.colliders[id]
if v ~= nil then
love.graphics.setColor(v.debugColor)
love.graphics.circle('line', v.x, v.y, v.radius)
love.graphics.circle('fill', v.x, v.y, 3)
love.graphics.print(v.ID, v.x + 5, v.y - 15)
love.graphics.print(v.tag, v.x + 5, v.y)
end
end
end
return collider

View file

@ -0,0 +1,86 @@
--Transform v0.1
local transform = {}
function transform.new(newX, newY, rotation, scale)
local newT = {}
newT.position = { x = newX, y = newY }
newT.rotation = rotation or 0
newT.scale = scale or 1
function newT.Translate(newx, newy)
if type(newx) ~= 'number' then -- Not a Number
if type(newx) == 'table' and newx.x == nil then -- Table
newy = newx[2]
newx = newx[1]
elseif newx.x ~= nil then --Vector
newy = newx.y
newx = newx.x
end
end
newT.position.x = newT.position.x + newx
newT.position.y = newT.position.y + newy
end
function newT.Set(newx, newy, newrot, newscale)
newT.position.x = newx
newT.position.y = newy
newT.rotation = newrot or newT.rotation
newT.scale = newscale or newT.scale
end
function newT.GetNewPosition(newx, newy)
return newT.position.x + newx, newT.position.y + newy
end
function newT.Request(newx, newy, colliderID)
local c = collider.colliders[colliderID]
local collisions = nil
local collisionsY = nil
if c.type == 'box' then
collisions = collider.overlapBox(newT.position.x + newx, newT.position.y, c.width, c.height)
collisionsY = collider.overlapBox(newT.position.x, newT.position.y + newy, c.width, c.height)
else
collisions = collider.overlapCircle(newT.position.x + newx, newT.position.y, c.radius)
collisionsY = collider.overlapCircle(newT.position.x, newT.position.y + newy, c.radius)
end
local moveMult = {1, 1}
for k,v in pairs(collisions) do
if v.trigger == false and v.ID ~= c.ID then
moveMult[1] = 0
break
end
end
for k,v in pairs(collisionsY) do
if v.trigger == false and v.ID ~= c.ID then
moveMult[2] = 0
break
end
end
for k,v in pairs(collisionsY) do table.insert(collisions, v) end
for k,v in pairs(collisions) do
c.collisions[v.ID] = v
v.collisions[c.ID] = c
end
newT.Translate(newx * moveMult[1], newy * moveMult[2])
end
function newT.get()
return newT.position.x, newT.position.y, newT.rotation, newT.scale
end
return newT
end
return transform

View file

@ -4,7 +4,22 @@ love.graphics.setBackgroundColor(r, g, b)
local timer = 0
local int = math.ceil(timer)
collider = require 'libs/collider'
function love.load()
local dbgcol = {1,1,1}
-- THE RIGHT ONE WILL
-- collision thing
wall = {x = 100, y = 100, width = 50, height = 50}
wall.sprite = love.graphics.newImage('sprites/white.png')
-- If you installed transform.lua
local transform = require 'libs/transform'
anim8 = require 'libs/anim8'
love.graphics.setDefaultFilter("nearest", "nearest")
checker = 0
@ -19,6 +34,9 @@ function love.load()
agent.animations = {}
agent.animations.right = anim8.newAnimation( agent.grid('1-3', 1),0.15)
agent.animations.left = anim8.newAnimation( agent.grid('1-3', 2),0.15)
agent.jumped = love.graphics.newImage('sprites/agent_jump.png')
agent.width = 64
agent.height = 64
agent.anim = agent.animations.right
@ -27,6 +45,10 @@ function love.load()
end
function love.update(dt)
collider.update()
t = 0 -- counter thing
timer = timer + dt
local distance
local isMoving = false
@ -85,23 +107,33 @@ function love.update(dt)
agent.vy = 0
end
if checkCollision(agent, wall) then
t = 0 + 1
end
-- collision checker thingy
end
-- Draw a coloured rectangle.
function love.draw()
-- In versions prior to 11.0, color component values are (0, 102, 102)
love.graphics.print(agent.x, 10, 210)
love.graphics.print(int, 350, 0)
agent.anim:draw(agent.spriteSheet, agent.x, agent.y, nil, 1)
love.graphics.rectangle("fill", wall.x, wall.y, wall.width, wall.height)
love.graphics.print(t)
if isMouseDown then
drawDottedArc(agent.x, agent.y, mouseX, mouseY)
love.graphics.draw(agent.jumped, agent.x, agent.y, nil, 1)
end
collider.draw()
end
function drawDottedArc(x1, y1, x2, y2)
@ -115,3 +147,13 @@ function drawDottedArc(x1, y1, x2, y2)
love.graphics.circle("fill", cx, cy, 2)
end
end
-- thanks google
function checkCollision(obj1, obj2)
return obj1.x < obj2.x + obj2.width and
obj1.x + obj1.width > obj2.x and
obj1.y < obj2.y + obj2.height and
obj1.y + obj1.height > obj2.y
end
-- THE ACTUAL THING!!!