object collision
This commit is contained in:
parent
ae3ee8fcb2
commit
5f1a51beac
3 changed files with 167 additions and 67 deletions
6
def.lua
6
def.lua
|
@ -8,6 +8,7 @@ tiles = {
|
|||
count = 1,
|
||||
},
|
||||
cost = 10,
|
||||
collision = true,
|
||||
|
||||
desc = 'An axe clicker. Used to obtain wood.',
|
||||
},
|
||||
|
@ -20,6 +21,7 @@ tiles = {
|
|||
count = 0.25,
|
||||
},
|
||||
cost = 100,
|
||||
collision = true,
|
||||
|
||||
desc = 'A primitive chainsaw. Automatically collects wood.'
|
||||
},
|
||||
|
@ -29,7 +31,8 @@ tiles = {
|
|||
type = 'conveyor',
|
||||
cost = 5,
|
||||
speed = 1,
|
||||
desc = 'Moves a resource from point a to point b'
|
||||
desc = 'Moves a resource from point a to point b',
|
||||
collision = false,
|
||||
},
|
||||
{
|
||||
name = 'basic_seller',
|
||||
|
@ -38,6 +41,7 @@ tiles = {
|
|||
cost = 1500,
|
||||
rate = 1,
|
||||
desc = 'A basic seller. Automatically sells all items coming from the forward tile',
|
||||
collision = false, -- custom collision for sellers
|
||||
}
|
||||
}
|
||||
|
||||
|
|
74
main.lua
74
main.lua
|
@ -1,7 +1,9 @@
|
|||
require 'util'
|
||||
require 'drawutil'
|
||||
require 'def'
|
||||
-- crusty swamp ass language An Awesome Project
|
||||
|
||||
local obj = require 'obj'
|
||||
|
||||
width = 64
|
||||
height = 64
|
||||
|
||||
|
@ -14,7 +16,7 @@ sprites = {}
|
|||
|
||||
money = 0
|
||||
|
||||
local objects = {}
|
||||
objects = {}
|
||||
|
||||
local selectedTile = 1
|
||||
local defaultTileRotation = 0
|
||||
|
@ -58,6 +60,8 @@ end
|
|||
|
||||
local timer = 0
|
||||
function love.update(dt)
|
||||
--dt = dt * 0.1
|
||||
|
||||
for x = 1, width do
|
||||
for y = 1, height do
|
||||
local tileid = getTile(x, y)
|
||||
|
@ -86,69 +90,7 @@ function love.update(dt)
|
|||
timer = timer + dt
|
||||
|
||||
for i,o in ipairs(objects) do
|
||||
o.x = o.x or 0
|
||||
o.y = o.y or 0
|
||||
o.velx = o.velx or 0
|
||||
o.vely = o.vely or 0
|
||||
o.size = o.size or 0.5
|
||||
o.color = o.color or {1, 1, 1}
|
||||
o.despawntimer = o.despawntimer or 0
|
||||
|
||||
local pass = true
|
||||
local object = objectTypes[o.type]
|
||||
|
||||
local onTileId = getTile(math.floor(o.x), math.floor(o.y))
|
||||
if onTileId[1] ~= 0 then
|
||||
local onTile = tiles[onTileId[1]]
|
||||
local a = -(onTileId.rotation or 0) * 90
|
||||
|
||||
if onTile.type == 'conveyor' then
|
||||
o.velx = o.velx - math.sin(math.rad(a)) * onTile.speed
|
||||
o.vely = o.vely - math.cos(math.rad(a)) * onTile.speed
|
||||
elseif onTile.type == 'seller' then
|
||||
local movementAngle = math.deg(math.atan2(o.vely, o.velx)) - 90
|
||||
if onTileId.rotation then
|
||||
local sellerAngle = onTileId.rotation * 90
|
||||
if math.abs(movementAngle - sellerAngle) < 45 then
|
||||
table.remove(objects, i)
|
||||
money = money + object.cost
|
||||
else
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
else
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
for i2,o2 in ipairs(objects) do
|
||||
if i ~= i2 and rectangleTouchingRectangle(o.x - o.size, o.y - o.size, o.size, o.size, o2.x - o2.size, o2.y - o2.size, o2.size, o2.size) then
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
-- this doesnt work
|
||||
]]
|
||||
|
||||
if not pass then
|
||||
o.velx = -o.velx
|
||||
o.vely = -o.vely
|
||||
end
|
||||
|
||||
if math.abs(o.velx) < 0.01 and math.abs(o.vely) < 0.01 then
|
||||
o.despawntimer = o.despawntimer + dt
|
||||
else
|
||||
o.despawntimer = 0
|
||||
end
|
||||
|
||||
if o.despawntimer > 5 then
|
||||
table.remove(objects, i)
|
||||
end
|
||||
|
||||
o.x = o.x + o.velx * dt
|
||||
o.y = o.y + o.vely * dt
|
||||
o.velx = o.velx * 0.8
|
||||
o.vely = o.vely * 0.8
|
||||
obj.updateObject(i, o, dt)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -261,7 +203,7 @@ function love.mousepressed(x, y, button)
|
|||
if tileid[1] ~= 0 then
|
||||
local tile = tiles[tileid[1]]
|
||||
if tile.type == 'clicker' then
|
||||
local a = -tileid.rotation * 90
|
||||
local a = -tileid.rotation * 90 + math.random(-10, 10)/10
|
||||
local x = math.floor(x/tilesize) + 0.5 - math.sin(math.rad(a)) * 0.7
|
||||
local y = math.floor(y/tilesize) + 0.5 - math.cos(math.rad(a)) * 0.7
|
||||
|
||||
|
|
154
obj.lua
Normal file
154
obj.lua
Normal file
|
@ -0,0 +1,154 @@
|
|||
-- handles object collision and updates
|
||||
|
||||
require 'util'
|
||||
|
||||
local self = {}
|
||||
|
||||
local steps = 4 -- the more, the higher quality the collision is, however it becomes laggier
|
||||
local clipAttempts = 10000
|
||||
|
||||
function self.doCollision(i, o, dt)
|
||||
-- check if object is already colliding and try to clip it out
|
||||
|
||||
-- object collision
|
||||
for i2,o2 in ipairs(objects) do
|
||||
local touch = rectangleTouchingRectangle(o.x, o.y, o.size, o.size, o2.x, o2.y, o2.size, o2.size) and i ~= i2
|
||||
if touch then
|
||||
-- clip it out, m64 style
|
||||
for i = 0, clipAttempts do
|
||||
if not rectangleTouchingRectangle(o.x, o.y, o.size, o.size, o2.x, o2.y, o2.size, o2.size) then break end
|
||||
local diffX = (o.x - o2.x) or o.size / 10 -- `or` incase the objects are spawned inside eachother
|
||||
local diffY = (o.y - o2.y) or o.size / 10
|
||||
|
||||
o.x = diffX * 1.1 + o2.x
|
||||
o.y = diffY * 1.1 + o2.y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- tile collision
|
||||
for i = 0, clipAttempts do
|
||||
local pass = true
|
||||
local onTileId = getTile(math.floor(o.x), math.floor(o.y))
|
||||
if onTileId[1] ~= 0 then
|
||||
local onTile = tiles[onTileId[1]]
|
||||
local a = -(onTileId.rotation or 0) * 90
|
||||
|
||||
if onTile.collision then
|
||||
if onTile.type == 'seller' then
|
||||
local movementAngle = math.deg(math.atan2(o.vely, o.velx)) - 90
|
||||
if onTileId.rotation then
|
||||
local sellerAngle = onTileId.rotation * 90
|
||||
if not math.abs(movementAngle - sellerAngle) < 45 then
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
else
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if pass then break end
|
||||
|
||||
local diffX = (o.x % 1 - 0.5) or o.size / 10 -- `or` incase the objects are spawned inside eachother
|
||||
local diffY = (o.y % 1 - 0.5) or o.size / 10
|
||||
|
||||
o.x = diffX * 1.1 + math.floor(o.x) + 0.5
|
||||
o.y = diffY * 1.1 + math.floor(o.y) + 0.5
|
||||
end
|
||||
|
||||
-- move
|
||||
for step = 1, steps do
|
||||
local a = step/steps
|
||||
local x = o.x + o.velx * dt * a
|
||||
local y = o.y + o.vely * dt * a
|
||||
|
||||
local pass = true
|
||||
|
||||
-- tile collision
|
||||
local onTileId = getTile(math.floor(x), math.floor(y))
|
||||
if onTileId[1] ~= 0 then
|
||||
local onTile = tiles[onTileId[1]]
|
||||
local a = -(onTileId.rotation or 0) * 90
|
||||
|
||||
if onTile.collision then
|
||||
if onTile.type == 'seller' then
|
||||
local movementAngle = math.deg(math.atan2(o.vely, o.velx)) - 90
|
||||
if onTileId.rotation then
|
||||
local sellerAngle = onTileId.rotation * 90
|
||||
if not math.abs(movementAngle - sellerAngle) < 45 then
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
else
|
||||
pass = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- object collision
|
||||
for i2,o2 in ipairs(objects) do
|
||||
local touch = rectangleTouchingRectangle(o.x, o.y, o.size, o.size, o2.x, o2.y, o2.size, o2.size) and i ~= i2
|
||||
if touch then pass = false end
|
||||
end
|
||||
|
||||
if pass then
|
||||
o.x = x
|
||||
o.y = y
|
||||
else
|
||||
o.velx = -o.velx * 0.25
|
||||
o.vely = -o.vely * 0.25
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function self.updateObject(i, o, dt)
|
||||
o.x = o.x or 0
|
||||
o.y = o.y or 0
|
||||
o.velx = o.velx or 0
|
||||
o.vely = o.vely or 0
|
||||
o.size = o.size or 0.5
|
||||
o.color = o.color or {1, 1, 1}
|
||||
o.despawntimer = o.despawntimer or 0
|
||||
|
||||
local object = objectTypes[o.type]
|
||||
|
||||
local onTileId = getTile(math.floor(o.x), math.floor(o.y))
|
||||
if onTileId[1] ~= 0 then
|
||||
local onTile = tiles[onTileId[1]]
|
||||
local a = -(onTileId.rotation or 0) * 90
|
||||
|
||||
if onTile.type == 'conveyor' then
|
||||
o.velx = o.velx - math.sin(math.rad(a)) * onTile.speed * dt * 40
|
||||
o.vely = o.vely - math.cos(math.rad(a)) * onTile.speed * dt * 40
|
||||
elseif onTile.type == 'seller' then
|
||||
local movementAngle = math.deg(math.atan2(o.vely, o.velx)) - 90
|
||||
if onTileId.rotation then
|
||||
local sellerAngle = onTileId.rotation * 90
|
||||
if math.abs(movementAngle - sellerAngle) < 45 then
|
||||
table.remove(objects, i)
|
||||
money = money + object.cost
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if math.abs(o.velx) < 0.01 and math.abs(o.vely) < 0.01 then
|
||||
o.despawntimer = o.despawntimer + dt
|
||||
else
|
||||
o.despawntimer = 0
|
||||
end
|
||||
|
||||
if o.despawntimer > 5 then
|
||||
table.remove(objects, i)
|
||||
end
|
||||
|
||||
self.doCollision(i, o, dt)
|
||||
|
||||
o.velx = o.velx * 0.8
|
||||
o.vely = o.vely * 0.8
|
||||
end
|
||||
|
||||
return self
|
Loading…
Reference in a new issue