summaryrefslogtreecommitdiff
path: root/Bolvis.lua
blob: 7f7f0e97b60a22a6cc1c0e42f78054bb3967ca7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
local game = require 'game'
local physics = require 'physics'
local Camera = require 'Camera'

local Bolvis = physics.Object:extend()
Bolvis.sprite = love.graphics.newImage("bolvis.png", {dpiscale = 5})
Bolvis.z = 50

local Hand = game.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)
	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()
	self.body:setAngle(0)
	physics.Object.update(self)
end

function Hand:new(bolvis)
	game.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(1, 0.8, 0.9)
	love.graphics.setLineWidth(15)
	love.graphics.line(x1, y1, x2, y2)
	love.graphics.setColor(1, 1, 1)
	game.Object.draw(self)
end

return Bolvis