summaryrefslogtreecommitdiff
path: root/objects
diff options
context:
space:
mode:
Diffstat (limited to 'objects')
-rw-r--r--objects/body.lua87
-rw-r--r--objects/door.lua 20-22-03-209.lua69
2 files changed, 156 insertions, 0 deletions
diff --git a/objects/body.lua b/objects/body.lua
new file mode 100644
index 0000000..f819101
--- /dev/null
+++ b/objects/body.lua
@@ -0,0 +1,87 @@
+local Body = {}
+Body.__index = Body
+
+function Body:new(shape, sizeA, sizeB, zoom)
+ local obj = {
+ shape = shape,
+ r = (shape == "circle" and sizeA or nil),
+ w = (shape == "rectangle" and sizeA or nil),
+ h = (shape == "rectangle" and sizeB or nil),
+ zoom = zoom or 1
+ }
+
+ setmetatable(obj, Body)
+
+ return obj
+end
+
+function Body:collide(other, x1, y1, x2, y2)
+ if self.shape == "circle" and other.shape == "circle" then
+ -- circle to circle
+ local dx = x2 - x1
+ local dy = y2 - y1
+ local distance = math.sqrt(dx * dx + dy * dy)
+ return distance < (self.r + other.r)
+ elseif self.shape == "rectangle" and other.shape == "rectangle" then
+ -- rect to rect
+ return x1 < x2 + other.w and x1 + self.w > x2 and y1 < y2 + other.h and y1 + self.h > y2
+ elseif self.shape == "circle" and other.shape == "rectangle" then
+ -- circle to rect
+ local closestX = math.max(x2, math.min(x1, x2 + other.w))
+ local closestY = math.max(y2, math.min(y1, y2 + other.h))
+ local dx = x1 - closestX
+ local dy = y1 - closestY
+ return (dx * dx + dy * dy) < (self.r * self.r)
+ elseif self.shape == "rectangle" and other.shape == "circle" then
+ return other:collide(self, x2, y2, x1, y1)
+ end
+
+ return false
+end
+
+function Body:isMet(body, selfX, selfY, currentX, currentY, dv, dir)
+ -- x,y should be the predicted next location of this body
+ -- dv = speed * dt * direction
+ local x, y
+ if dir == Direction.LEFT or dir == Direction.RIGHT then
+ x = currentX + dv
+ y = currentY
+ elseif dir == Direction.UP or dir == Direction.DOWN then
+ x = currentX
+ y = currentY + dv
+ end
+
+ return self:collide(body, selfX, selfY, x, y)
+end
+
+function Body:draw(x, y)
+ if self.shape == "circle" then
+ love.graphics.circle("fill", x, y, self.r)
+ elseif self.shape == "rectangle" then
+ love.graphics.rectangle("fill", x, y, self.w, self.h)
+ end
+end
+
+function Body:drawSprite(spriteName, x, y, angle)
+ local sprite = sprite.get(spriteName)
+ local w, h = (self.shape == "circle" and self.r or self.w), (self.shape == "circle" and self.r or self.h)
+
+ love.graphics.draw(sprite, x, y, angle,
+ w / sprite:getWidth(),
+ h / sprite:getHeight()
+ )
+end
+
+function Body:drawQuad(sheet, index, x, y, angle)
+ if self.shape == "circle" then
+ local r = self.r
+ local graphicR = r * self.zoom
+ sprite.drawQuad(sheet, index, x - r, y - r, graphicR, graphicR, angle or 0)
+ else
+ local w, h = self.w, self.h
+ local graphicW, graphicH = w * self.zoom, h * self.zoom
+ sprite.drawQuad(sheet, index, x - w/2, y - h/2, graphicW, graphicH, angle or 0)
+ end
+end
+
+return Body
diff --git a/objects/door.lua 20-22-03-209.lua b/objects/door.lua 20-22-03-209.lua
new file mode 100644
index 0000000..6df6c26
--- /dev/null
+++ b/objects/door.lua 20-22-03-209.lua
@@ -0,0 +1,69 @@
+require "data.directions"
+local physics = require "logic.physics"
+
+local Door = {}
+Door.__index = Door
+
+local function calculateDoorLocation(obj)
+ local roomX, roomY = obj.within:getX(), obj.within:getY()
+ local roomW, roomH = obj.within:getWidth(), obj.within:getHeight()
+ local loc, size, thickness = obj.location, obj.size, obj.thickness
+
+ local positions = {
+ [Direction.LEFT] = { x = roomX, y = (love.graphics.getHeight() - size) / 2, w = thickness, h = size },
+ [Direction.RIGHT] = { x = roomX + roomW, y = (love.graphics.getHeight() - size) / 2, w = thickness, h = size },
+ [Direction.TOP] = { x = (love.graphics.getWidth() - thickness) / 2, y = roomY, w = size, h = thickness },
+ [Direction.BOTTOM] = { x = (love.graphics.getWidth() - thickness) / 2, y = roomY + roomH, w = size, h = thickness }
+ }
+
+ local pos = positions[loc]
+ obj.x, obj.y, obj.w, obj.h = pos.x, pos.y, pos.w, pos.h
+end
+
+function Door:new(location, within, to)
+ local obj = {
+ location = location,
+ size = config.graphics.doorSize,
+ thickness = config.graphics.doorThickness,
+
+ within = within,
+ to = to,
+ }
+
+ setmetatable(obj, Door)
+
+ calculateDoorLocation(obj)
+ G.BodyLifeCycleManager:create(obj, { obj.w, obj.h }, "static")
+
+ return obj
+end
+
+function Door:setTo(room)
+ self.to = room
+end
+
+function Door:onContact(other)
+ local map = require "logic.map"
+ if other.objectType == "player" then
+ print "player in contact with door"
+ if not G.currentRoom.isCleared then return end
+
+ map.switchRoom(self.to)
+
+ -- update player position after entering a new room
+ local doorH, doorW, playerR = self.h, self.w, G.player.physicsShape:getRadius()
+ local roomX, roomY, roomW, roomH = G.currentRoom:getX(), G.currentRoom:getY(), G.currentRoom:getWidth(), G.currentRoom:getHeight()
+
+ local positions = {
+ [Direction.LEFT] = { "x", roomX + roomW - playerR - doorW },
+ [Direction.RIGHT] = { "x", roomX + playerR + doorW },
+ [Direction.TOP] = { "y", roomY + roomH - playerR - doorH },
+ [Direction.BOTTOM] = { "y", roomY + playerR + doorH }
+ }
+
+ local axis, pos = positions[self.location][1], positions[self.location][2]
+ G.BodyLifeCycleManager:setPosition(G.player, axis, pos)
+ end
+end
+
+return Door