151 lines
4.2 KiB
Lua
151 lines
4.2 KiB
Lua
local inspect = require("inspect/inspect")
|
|
|
|
local Vector = require("vector")
|
|
|
|
local helpers = require("helpers")
|
|
|
|
function swept_aabb(box1, box2, dt)
|
|
local x_inv_entry, y_inv_entry, x_inv_exit, y_inv_exit
|
|
if box1.dx > 0 then
|
|
x_inv_entry = box2.x - (box1.x + box1.w)
|
|
x_inv_exit = (box2.x + box2.w) - box1.x
|
|
else
|
|
x_inv_entry = (box2.x + box2.w) - box1.x
|
|
x_inv_exit = box2.x - (box1.x + box1.w)
|
|
end
|
|
if (box1.dy > 0) then
|
|
y_inv_entry = box2.y - (box1.y + box1.h)
|
|
y_inv_exit = (box2.y + box2.h) - box1.y
|
|
else
|
|
y_inv_entry = (box2.y + box2.h) - box1.y
|
|
y_inv_exit = box2.y - (box1.y + box1.h)
|
|
end
|
|
|
|
local x_entry_time, y_entry_time, x_exit_time, y_exit_time
|
|
if (box1.dx == 0) then
|
|
x_entry_time = -math.huge
|
|
x_exit_time = math.huge
|
|
else
|
|
x_entry_time = x_inv_entry / box1.dx
|
|
x_exit_time = x_inv_exit / box1.dx
|
|
end
|
|
if (box1.dy == 0) then
|
|
y_entry_time = -math.huge
|
|
y_exit_time = math.huge
|
|
else
|
|
y_entry_time = y_inv_entry / box1.dy
|
|
y_exit_time = y_inv_exit / box1.dy
|
|
end
|
|
local entry_time = math.max(y_entry_time, x_entry_time)
|
|
local exit_time = math.min(y_exit_time, x_exit_time)
|
|
local normalx, normaly
|
|
if (entry_time > exit_time or x_entry_time < 0 and y_entry_time < 0 or x_entry_time > 1 or y_entry_time > 1) then
|
|
normalx = 0
|
|
normaly = 0
|
|
entry_time = 1
|
|
else
|
|
if x_entry_time > y_entry_time then
|
|
if x_inv_entry < 0 then
|
|
normalx = 1
|
|
normaly = 0
|
|
else
|
|
normalx = -1
|
|
normaly = 0
|
|
end
|
|
else
|
|
if y_inv_entry < 0 then
|
|
normalx = 0
|
|
normaly = 1
|
|
else
|
|
normalx = 0
|
|
normaly = -1
|
|
end
|
|
end
|
|
end
|
|
print("SWEPT AABB TIME:", entry_time )
|
|
return {normal={x=normalx, y=normaly}, dt=entry_time}
|
|
end
|
|
|
|
function get_displacement_rect(entity, next_pos)
|
|
local displacement_rect = {
|
|
x=entity.x,
|
|
y=entity.y,
|
|
w=entity.w,
|
|
h=entity.h,
|
|
}
|
|
if entity.dx > 0 then
|
|
displacement_rect.x = entity.x
|
|
displacement_rect.w = next_pos.x + entity.w - entity.x
|
|
elseif entity.dx < 0 then
|
|
displacement_rect.x = next_pos.x
|
|
displacement_rect.w = entity.x + entity.w - next_pos.x
|
|
end
|
|
|
|
if entity.dy > 0 then
|
|
displacement_rect.y = entity.y
|
|
displacement_rect.h = next_pos.y + entity.h - entity.y
|
|
elseif entity.dy < 0 then
|
|
displacement_rect.y = next_pos.y
|
|
displacement_rect.h = entity.y + entity.h - next_pos.y
|
|
end
|
|
return displacement_rect
|
|
end
|
|
|
|
function distance(point_a, point_b)
|
|
return math.sqrt(math.pow(point_a.x - point_b.x, 2) + math.pow(point_a.y - point_b.y, 2))
|
|
end
|
|
function find_closest_tile_in_rectangle(entity, rect, game)
|
|
local closest
|
|
local center = {x=entity.x + entity.w/2, y=entity.y + entity.h/2}
|
|
local min_distance = math.huge
|
|
local top_left_tile = game:pixel_to_tile(rect)
|
|
local bottom_right_tile = game:pixel_to_tile({
|
|
x=rect.x + rect.w,
|
|
y=rect.y + rect.h,
|
|
})
|
|
for tx=top_left_tile.x, bottom_right_tile.x do
|
|
for ty=top_left_tile.y, bottom_right_tile.y do
|
|
local value = game:tile_value({x=tx, y=ty})
|
|
if value ~= 0 then
|
|
local tile_center = {x=game:x_to_pixel(tx) + game.map.tilewidth/2, y=game:y_to_pixel(ty) + game.map.tileheight/2}
|
|
local current_distance = distance(center, tile_center)
|
|
if current_distance < min_distance then
|
|
closest = {x=game:x_to_pixel(tx), y=game:y_to_pixel(ty), w=game.map.tilewidth, h=game.map.tileheight, value=value, tx=tx, ty=ty}
|
|
min_distance = current_distance
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return closest
|
|
end
|
|
|
|
local states = require("states")
|
|
|
|
local Entity = require("entity")
|
|
|
|
local scale_width, scale_height, current_state
|
|
function love.load()
|
|
local screen_width = 320 --self.map.width*self.map.tilewidth
|
|
local screen_height = 200 -- self.map.height*self.map.tileheight
|
|
love.graphics.setDefaultFilter("nearest", "nearest")
|
|
local desktop_width, desktop_height = love.window.getDesktopDimensions()
|
|
scale_width = desktop_width/screen_width
|
|
scale_height = desktop_height/screen_height
|
|
current_state = states.Title:new()
|
|
end
|
|
|
|
function love.update(dt)
|
|
current_state:update(dt)
|
|
if current_state.ended then
|
|
current_state = current_state.next
|
|
end
|
|
end
|
|
|
|
function love.draw()
|
|
love.graphics.setColor(1, 1, 1)
|
|
love.graphics.push()
|
|
love.graphics.scale(scale_width, scale_height)
|
|
current_state:draw()
|
|
love.graphics.pop()
|
|
end
|