-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobjects.lua
169 lines (152 loc) · 5.41 KB
/
objects.lua
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
local base = require("base")
local objects = setmetatable({}, {__index = base})
local properties = {
water = 2
}
--[[ Callback ]]
function objects:update(dt)
local index, object
for index, object in ipairs(self) do
object:update(dt)
end
end
function objects:draw()
local index, object
for index, object in ipairs(self) do
object:draw()
end
end
--[[ Objects ]]
function objects.baseObject()
local o = {}
o.velocityMod = 1
o.spawned = 0
o.color = {1, 1, 1, 1}
--[[ Callback ]]
function o:update(dt)
self.spawned = self.spawned + dt
if self.velocityMod ~= 1 then self.velocityMod = 1 end
end
function o:draw() end
--[[ Collision ]]
function o:beginContact(a, b, col)
end
function o:endContact(a, b, col)
end
function o:preSolve(a, b, col)
end
function o:postSolve(a, b, col, normalImpulse, tangentImpulse)
end
return o
end
function objects:waterCircle(world, x, y)
local o = setmetatable({}, {__index = objects.baseObject()})
local body = love.physics.newBody(world, x, y, "dynamic")
body:setMass(body:getMass() / 8)
o.shape = love.physics.newCircleShape(5)
o.fixture = love.physics.newFixture(body, o.shape, 1)
o.fixture:setUserData(o)
o.fixture:setMask(properties.water)
o.color = {0, 0.5, 1, 0.8}
o.radiusChangeDirection = 1
o.radiusRange = o.shape:getRadius()
o.radiusChangeStep = o.radiusRange / 2
o.radiusVelocityMod = 0.1
o.radiusMod = 0
function o:update(dt)
local x, y = self.fixture:getBody():getLinearVelocity()
local newRadius = self.radiusMod + self.radiusChangeStep * self.radiusChangeDirection * (dt + math.max(math.abs(x), math.abs(y)) * self.radiusVelocityMod * dt)
while newRadius > self.radiusRange or newRadius < 0 do
if newRadius > self.radiusRange then
newRadius = self.radiusRange - newRadius % self.radiusRange * self.radiusChangeDirection
self.radiusChangeDirection = - self.radiusChangeDirection
end
if newRadius < 0 then
newRadius = math.abs(newRadius)
self.radiusChangeDirection = - self.radiusChangeDirection
end
end
self.radiusMod = newRadius
end
function o:draw()
local world, x, y
world = self.fixture:getBody():getWorld()
x, y = self.fixture:getBody():getWorldPoint(self.shape:getPoint(world))
love.graphics.setColor(unpack(self.color))
love.graphics.circle("fill", x, y, self.shape:getRadius() + self.radiusMod)
love.graphics.setColor(1, 1, 1)
end
function o:preSolve(object, col)
local index, mask
if object.fixture:getBody():getType() == "dynamic" then
for index, mask in ipairs({object.fixture:getMask()}) do
if mask == properties.water then return end
end
-- Non-water dynamic
col:setEnabled(false)
-- Manual force calculation
local f1x, f1y, f2x, f2y
local body
local x, y
local m
local d = self.shape:getRadius() / 4
-- Force applied by self
body = self.fixture:getBody()
x, y = body:getLinearVelocity()
m = body:getMass()
f1x = m * x * x / (2 * d)
f1y = m * y * y / (2 * d)
-- Force applied by object
body = object.fixture:getBody()
x, y = body:getLinearVelocity()
m = body:getMass()
f2x = m * x * x / (2 * d)
f2y = m * y * y / (2 * d)
-- Resulting force
x, y = col:getNormal()
x = x * (f2x + f1x) / love.physics.getMeter() / 3 -- not so sure
y = y * (f2y + f1y) / love.physics.getMeter() / 3 -- not so sure
self.fixture:getBody():applyForce(x, y)
-- Slow object in water
object.velocityMod = 0.75
object.fixture:getBody():applyForce(0, -99)
end
end
table.insert(objects,o)
return o
end
function objects:circle(world)
local o = setmetatable({}, {__index = objects.baseObject()})
local body = love.physics.newBody(world, 500, -500, "dynamic")
o.shape = love.physics.newCircleShape(10)
o.fixture = love.physics.newFixture(body, o.shape, 0)
o.fixture:setUserData(o)
function o:update(dt)
local force
local x, y = self.fixture:getBody():getWorldPoint(self.shape:getPoint())
if love.keyboard.isDown("lctrl") then
force = 25
self.fixture:getBody():setLinearVelocity(0,0)
if love.keyboard.isDown("left") and x > 0 then self.fixture:getBody():setX(self.fixture:getBody():getX()-force) end
if love.keyboard.isDown("right") then self.fixture:getBody():setX(self.fixture:getBody():getX()+force) end
if love.keyboard.isDown("up") then self.fixture:getBody():setY(self.fixture:getBody():getY()-force) end
if love.keyboard.isDown("down") then self.fixture:getBody():setY(self.fixture:getBody():getY()+force) end
else
force = 500 * self.velocityMod
if love.keyboard.isDown("right") then self.fixture:getBody():applyForce(force, 0) end
if love.keyboard.isDown("left") and x > 0 then self.fixture:getBody():applyForce(-force, 0) end
--[[if love.keyboard.isDown("up") then self.fixture:getBody():applyForce(0, -force) end -- Debug
if love.keyboard.isDown("down") then self.fixture:getBody():applyForce(0, force) end]]
end
objects:baseObject().update(self,dt)
end
function o:draw()
local world = self.fixture:getBody():getWorld()
local x, y = self.fixture:getBody():getWorldPoint(self.shape:getPoint(world))
love.graphics.circle("fill", x, y, self.shape:getRadius())
--love.graphics.print(x ..","..y, x, y + 20)
end
table.insert(objects,o)
return o
end
return objects