Mothback/code/entity.lua

288 lines
8.0 KiB
Lua

Entity = {class = "Entity"}
LoadedObjects.Entities = {}
function Entity:New(x,y)
o = {}
o.pos = {x = x, y = y}
o.vel = {x = 0, y = 0}
o.direction = 0
o.boxCollision = {
from = {x = x, y = y},
to = {x = x, y = y},
}
o.target_offset = {x = 0, y = 0}
o.sprite_offset = {x = 0, y = 0}
o.sprite_scale = {x = 1, y = 1}
o.sprite_rotation = math.rad(0)
o.sprite_tint = {1,1,1}
o.sprite_alpha = 1
o.sprite_flip = { x = 1, y = 1}
o.illuminated = false
setmetatable(o, self)
self.__index = self
return o
end
function Entity:CheckNearest(type,maxdistance)
local return_entity = nil
local shortest = -1
for _, entity in pairs(LoadedObjects.Entities) do
if not type or entity.type == type then
local distance_x = entity.pos.x - self.pos.x
local distance_y = entity.pos.y - self.pos.y
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if not maxdistance or distance < maxdistance then
if shortest == -1 or distance < shortest then
shortest = distance
return_entity = entity
end
end
end
end
return return_entity
end
function Entity:Smart()
end
function Entity:Move()
self.pos.x = self.pos.x + self.vel.x
self.pos.y = self.pos.y + self.vel.y
end
function Entity:CollisionMove()
local r = false
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
self.pos.x = self.pos.x + self.vel.x
else
self.vel.x = 0
r = true
end
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
self.pos.y = self.pos.y + self.vel.y
else
self.vel.y = 0
r = true
end
return r
end
function Entity:MoveX()
local r = false
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
self.pos.x = self.pos.x + self.vel.x
else
self.vel.x = 0
r = true
end
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
self.pos.y = self.pos.y + self.vel.y
else
self.vel.y = 0
r = true
end
return r
end
function Entity:LightAdjust(x,y)
if self.light ~= nil then
local x = x or 0
local y = y or 0
self.light.pos.x = self.pos.x
self.light.pos.y = self.pos.y
end
end
function Entity:Kill()
if self.light ~= nil then
KillLight(self.light)
end
if self.id ~= nil then
for _, e in pairs(LoadedObjects.Entities) do
if e.id > self.id then
e.id = e.id - 1
end
end
table.remove(LoadedObjects.Entities,self.id)
end
self = nil
end
function Entity:CheckVisionLine(entity,range)
local target_x = entity.pos.x + entity.target_offset.x
local target_y = entity.pos.y + entity.target_offset.y
local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y
local angle = GetAngleFromVector(distance_x,distance_y)
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
local is_colliding = true
if distance < range then
is_colliding = false
for i=1, distance, game.scale do
if isThereObjectAt(
self.pos.x+math.cos(angle)*i,
self.pos.y+math.sin(angle)*i,
LoadedObjects.Collisions
) then
is_colliding = true
end
end
end
return not is_colliding
end
function Entity:Draw(animation)
local c1, c2, c3, a = love.graphics.getColor()
love.graphics.setColor(self.sprite_tint[1],self.sprite_tint[2],self.sprite_tint[3],self.sprite_alpha)
animation:Draw(
self.pos.x - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x,
self.pos.y - Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y,
self.sprite_rotation,
self.sprite_scale.x * self.sprite_flip.x,
self.sprite_scale.y * self.sprite_flip.y
)
love.graphics.setColor(c1,c2,c3,a)
end
function Entity:centerOffset(animation,x,y)
local x = x or 0
local y = y or 0
self.sprite_offset.x = animation.imgs[1]:getWidth()/2 + x
self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y
end
function Entity:getBoundingBox(animation,top,left,bottom,right)
local left = left or 0
local right = right or 0
local top = top or 0
local bottom = bottom or 0
self.boxCollision.from.x = -animation.imgs[1]:getWidth()/2 + left
self.boxCollision.to.x = animation.imgs[1]:getWidth()/2 + right
self.boxCollision.from.y = -animation.imgs[1]:getHeight()/2 + top
self.boxCollision.to.y = animation.imgs[1]:getHeight()/2 + bottom
end
-- returns true if theres a collision at that point. also marks collisioned tile as collision true
function Entity:isCollidingAt(x,y,object)
for _, collision in pairs(object) do
if collision.disable then
-- Dont calculate if disabled
elseif x + self.boxCollision.from.x < collision.to.x
and x + self.boxCollision.to.x > collision.from.x
and y + self.boxCollision.from.y < collision.to.y
and y + self.boxCollision.to.y > collision.from.y
then
collision.isColliding = true
return true
end
end
return false
end
function Entity:isCollidingWith(entity)
return self.pos.x + self.boxCollision.from.x < entity.pos.x + entity.boxCollision.to.x
and entity.pos.x + entity.boxCollision.from.x < self.pos.x + self.boxCollision.to.x
and self.pos.y + self.boxCollision.from.y < entity.pos.y + entity.boxCollision.to.y
and entity.pos.y + entity.boxCollision.from.y < self.pos.y + self.boxCollision.to.y
end
function Entity:isCollidingAtAll(x,y)
local result = false
if not result then
result = self:isCollidingAt(x,y,LoadedObjects.Platforms)
end
if not result then
result = self:isCollidingAt(x,y,LoadedObjects.Platforms)
end
if not result then
result = self:isCollidingAt(x,y,LoadedObjects.Platforms)
end
return result
end
function Entity:CheckVisionLineDebug(entity,range)
local c1, c2, c3, a = love.graphics.getColor()
local target_x = entity.pos.x + entity.target_offset.x
local target_y = entity.pos.y + entity.target_offset.y
local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y
local angle = GetAngleFromVector(distance_x,distance_y)
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if distance < range then
for i=1, distance, game.scale do
if isThereObjectAt(
self.pos.x+math.cos(angle)*i,
self.pos.y+math.sin(angle)*i,
LoadedObjects.Collisions
) then
love.graphics.setColor(1,0,0)
else
love.graphics.setColor(0,1,0)
end
love.graphics.line(
self.pos.x+math.cos(angle)*i-1 - Camera.pos.x,
self.pos.y+math.sin(angle)*i-1 - Camera.pos.y,
self.pos.x+math.cos(angle)*i - Camera.pos.x,
self.pos.y+math.sin(angle)*i - Camera.pos.y
)
end
end
love.graphics.setColor(c1,c2,c3,a)
end
function Entity:Debug()
-- draw center GREEN
love.graphics.setColor(0,1,0)
love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1)
-- draw collision box PURPLE
love.graphics.setColor(1,0,1)
love.graphics.rectangle(
"line",
-Camera.pos.x + self.pos.x + self.boxCollision.from.x,
-Camera.pos.y + self.pos.y + self.boxCollision.from.y,
-Camera.pos.x + self.pos.x + self.boxCollision.to.x -(-Camera.pos.x + self.pos.x + self.boxCollision.from.x),
-Camera.pos.y + self.pos.y + self.boxCollision.to.y -(-Camera.pos.y + self.pos.y + self.boxCollision.from.y)
)
if self.target ~= nil then
love.graphics.line(
-Camera.pos.x + self.pos.x,
-Camera.pos.y + self.pos.y,
-Camera.pos.x + self.target.x,
-Camera.pos.y + self.target.y
)
end
end
function Entity:HandleAnimation()
end
function Entity:DrawBackground()
end
require "code/entities/kupo"
require "code/entities/arrow"
require "code/entities/decoration"
require "code/entities/player"
require "code/entities/fairy"
require "code/entities/cursed_book"
require "code/entities/hook_anchor"
require "code/entities/particle"