-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.lua
More file actions
145 lines (138 loc) · 4.25 KB
/
Copy pathmain.lua
File metadata and controls
145 lines (138 loc) · 4.25 KB
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
-- Main
function love.load()
love.window.setTitle("BOIDS")
love.graphics.setBackgroundColor(0, 0, 0)
width = love.graphics.getWidth()
height = love.graphics.getHeight()
agents = {}
for i = 1, 100 do
local face = love.math.random(0, 360)
local x = love.math.random(0, width)
local y = love.math.random(0, height)
local obj = {x=x, y=y, f=face}
table.insert(agents, obj)
end
end
function love.update(dt)
local a = agents[1]
for i = 1, #agents do
local a1 = agents[i]
align(a1)
separate(a1)
center(a1)
wall(a1)
local dx = math.cos(a1.f * 0.0174533)
local dy = math.sin(a1.f * 0.0174533)
a1.x = a1.x + dx * 5
a1.y = a1.y + dy * 5
end
end
function love.draw()
-- love.graphics.setColor(0.9, 0.9, 0.9)
for i = 1, #agents do
local agent = agents[i]
local t1x = math.cos(agent.f * 0.0174533) * 2
local t1y = math.sin(agent.f * 0.0174533) * 2
local t2x = math.cos((agent.f + 120) * 0.0174533)
local t2y = math.sin((agent.f + 120) * 0.0174533)
local t3x = math.cos((agent.f + 240) * 0.0174533)
local t3y = math.sin((agent.f + 240) * 0.0174533)
local r = 4
love.graphics.polygon("fill",
agent.x + t1x * r, agent.y + t1y * r,
agent.x + t2x * r, agent.y + t2y * r,
agent.x + t3x * r, agent.y + t3y * r)
end
end
function dist(a1, a2)
return math.sqrt(
math.pow(a1.x - a2.x, 2) +
math.pow(a1.y - a2.y, 2))
end
function align(a1)
local dx = math.cos(a1.f * 0.0174533)
local dy = math.sin(a1.f * 0.0174533)
-- Adjust by this % of average velocity
local matchingFactor = 0.1
local visualRange = 75
local avgDX = 0
local avgDY = 0
local numNeighbors = 0
for i = 1, #agents do
local a2 = agents[i]
local dx2 = math.cos(a2.f * 0.0174533)
local dy2 = math.sin(a2.f * 0.0174533)
if dist(a1, agents[i]) < visualRange then
avgDX = avgDX + dx2
avgDY = avgDY + dy2
numNeighbors = numNeighbors + 1
end
end
if numNeighbors > 0 then
avgDX = avgDX / numNeighbors
avgDY = avgDY / numNeighbors
dx = dx + (avgDX - dx) * matchingFactor
dy = dy + (avgDY - dy) * matchingFactor
end
a1.f = math.atan2(dy, dx) / 0.0174533
end
function separate(a1)
local dx = math.cos(a1.f * 0.0174533)
local dy = math.sin(a1.f * 0.0174533)
-- The distance to stay away from other boids
local minDistance = 15
-- Adjust velocity by this %
local avoidFactor = 0.05
local moveX = 0
local moveY = 0
for i = 1, #agents do
if dist(a1, agents[i]) < minDistance then
moveX = moveX + a1.x - agents[i].x
moveY = moveY + a1.y - agents[i].y
end
end
dx = dx + moveX * avoidFactor
dy = dy + moveY * avoidFactor
a1.f = math.atan2(dy, dx) / 0.0174533
end
function center(a1)
-- adjust velocity by this %
local dx = math.cos(a1.f * 0.0174533)
local dy = math.sin(a1.f * 0.0174533)
local centeringFactor = 0.003
local visualRange = 75
local centerX = 0
local centerY = 0
local numNeighbors = 0
for i = 1, #agents do
if dist(a1, agents[i]) < visualRange then
centerX = centerX + agents[i].x
centerY = centerY + agents[i].y
numNeighbors = numNeighbors + 1
end
end
if numNeighbors > 0 then
centerX = centerX / numNeighbors
centerY = centerY / numNeighbors
dx = dx + (centerX - a1.x) * centeringFactor
dy = dy + (centerY - a1.y) * centeringFactor
end
a1.f = math.atan2(dy, dx) / 0.0174533
end
function wall(a1)
local dx = math.cos(a1.f * 0.0174533)
local dy = math.sin(a1.f * 0.0174533)
local margin = 200
local turnFactor = 0.001
if a1.x < margin then
dx = dx + turnFactor * (margin - a1.x)
elseif a1.x > width - margin then
dx = dx - turnFactor * (a1.x + margin - width)
end
if a1.y < margin then
dy = dy + turnFactor * (margin - a1.y)
elseif a1.y > height - margin then
dy = dy - turnFactor * (a1.y + margin - height)
end
a1.f = math.atan2(dy, dx) / 0.0174533
end