local game = require 'game' local physics = require 'physics' local Camera = require 'Camera' local Bolvis = physics.Object:extend() Bolvis.sprite_center = love.graphics.newImage("bolvis.png", {dpiscale = 5}) Bolvis.sprite_left = love.graphics.newImage("bolvis-left.png", {dpiscale = 5}) Bolvis.sprite_right = love.graphics.newImage("bolvis-right.png", {dpiscale = 5}) Bolvis.sprite_blink = love.graphics.newImage("bolvis-blink.png", {dpiscale = 5}) Bolvis.z = 50 local Hand = physics.Object:extend() Hand.sprite_open = love.graphics.newImage("hand-open.png", {dpiscale = 3.5}) Hand.sprite_closed = love.graphics.newImage("hand-closed.png", {dpiscale = 3.5}) Hand.max_speed = 10 Hand.z = 49 function Bolvis:new(pos, rotation) self.sprite = self.sprite_center self.blink = 10 physics.Object.new(self, pos, rotation, nil, 'dynamic') self.shape = love.physics.newRectangleShape(90, 90) self.fixture = love.physics.newFixture(self.body, self.shape) self.fixture:setRestitution(0.2) self.fixture:setDensity(20) self.hand = Hand(self) self.camera = Camera() self.camera:follow(self) end function Bolvis:update(dt) self.body:setAngle(0) physics.Object.update(self, dt) self.blink = self.blink - (dt * 30) if self.blink <= 0 then if self.sprite == self.sprite_blink then self.sprite = self.sprite_center self.blink = math.random(30, 256) else self.sprite = self.sprite_blink self.blink = 4 end end if self.sprite ~= self.sprite_blink then if self.hand.grab_joint then local offsx = self.hand:present_offset() if offsx > 150 then self.sprite = self.sprite_right elseif offsx < -150 then self.sprite = self.sprite_left else self.sprite = self.sprite_center end elseif self.sprite ~= self.sprite_center then if math.random(1, 4) == 1 then self.sprite = self.sprite_blink self.blink = 4 else self.sprite = self.sprite_center end end end end function Hand:new(bolvis) physics.Object.new(self) self.offset = {100, -100} self.bolvis = bolvis self.sprite = self.sprite_open end function Hand:angle() local x, y = unpack(self.pos) local bx, by = unpack(self.bolvis.pos) local ox, oy = x - bx, y - by local a = math.atan(oy / math.abs(ox)) + math.pi / 2 if ox < 0 then a = -a end return a end local function clamp(n, max, min) return math.max(math.min(n, max), min) end function Hand:update() self.rot = self:angle() if not self.grab_joint then self.pos[1] = self.bolvis.pos[1] + self.offset[1] self.pos[2] = self.bolvis.pos[2] + self.offset[2] else self.pos = {self.grabbed.body:getWorldPoint(unpack(self.grab_pos))} end end function Hand:present_offset() local x, y = unpack(self.pos) local bx, by = unpack(self.bolvis.pos) return x - bx, y - by end function Hand:mousemoved(_, _, dx, dy) dx = clamp(dx, self.max_speed, -self.max_speed) dy = clamp(dy, self.max_speed, -self.max_speed) self.offset[1] = clamp(self.offset[1] + dx, 1920 / 2, -1920 / 2) self.offset[2] = clamp(self.offset[2] + dy, 1080 / 2, -1080 / 2) if self.grab_joint then local x, y = unpack(self.offset) self.grab_joint:setLinearOffset(x + self.grab_pos[1], y + self.grab_pos[2]) end end function Hand:mousepressed(_, _, button) if button == 1 then self.sprite = self.sprite_closed local grabbed for o in pairs(game.all_objects) do if o.fixture then if o.fixture:testPoint(unpack(self.pos)) then if o ~= self.bolvis then self.grabbed = o break end end end end if self.grabbed then local x1, y1 = unpack(self.bolvis.pos) local x2, y2 = unpack(self.bolvis.pos) self.grab_joint = love.physics.newMotorJoint( self.bolvis.body, self.grabbed.body, 0.5, true) self.grab_joint:setMaxForce(500) self.grab_pos = {self.grabbed.body:getLocalPoint(unpack(self.pos))} end end end function Hand:mousereleased(_, _, button) if button == 1 then self.sprite = self.sprite_open if self.grab_joint then self.grabbed = nil self.grab_joint:destroy() self.grab_joint = nil end self.offset = {self:present_offset()} end end function Hand:draw() local x1, y1 = unpack(self.bolvis.pos) local x2, y2 = unpack(self.pos) love.graphics.setColor(0.73, 0.76, 0.91) love.graphics.setLineWidth(15) love.graphics.line(x1, y1, x2, y2) love.graphics.setColor(1, 1, 1) game.Object.draw(self) end return Bolvis