#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# [Share] Bot Swarm

Posts: 1,976

Just a little project I made while testing AI that I thought was fun to play around with and decided to share.

``````--# Bot
Bot = class()

function Bot:init()
self.pos = vec2(WIDTH / 4, HEIGHT / 4)
self.target = target
self.size = 50
end

function Bot:draw()
local mot = (self.target - self.pos):normalize() * 200 * DeltaTime
local angle = math.atan2(mot.y, mot.x)
local next = self.pos + mot
local move = true
local i = math.random() * 45 - 22.5
while i <= 180 do
for k, v in ipairs(bots) do
if v ~= self then
if v.pos:dist(next) < (v.size + self.size) / 2 and v.pos:dist(v.target) < self.pos:dist(self.target) then
next = self.pos + vec2(math.cos(angle + math.rad(i)), math.sin(angle + math.rad(i))) * 200 * DeltaTime
end
end
end
for k, v in ipairs(obstacles) do
if math.abs(v.x - self.pos.x) < (v.size + self.size) / 2 and math.abs(v.y - self.pos.y) < (v.size + self.size) / 2 then
next = self.pos + vec2(math.cos(angle + math.rad(i)), math.sin(angle + math.rad(i))) * 200 * DeltaTime
end
end
i = -i
local sign = i / math.abs(i)
if sign ~= 1 and sign ~= -1 then
sign = 1
end
if sign == 1 then
i = i + sign * 22.5
end
end

if move then
self.pos = next
end

noStroke()
fill(0)

ellipse(self.pos.x, self.pos.y, self.size)
end

--# Main
-- Bot Swarm

function setup()
tool = "target"
parameter.watch("tool")
parameter.action("Find Tool", function()
tool = "find"
end)
parameter.action("Target Tool", function()
tool = "target"
end)
parameter.action("Obstacle Tool", function()
tool = "obstacle"
end)
parameter.action("Army Tool", function()
tool = "army"
end)
parameter.boolean("Autospawn", true)
parameter.action("Clear Bots", function()
bots = {}
end)
parameter.action("Clear Obstacles", function()
obstacles = {}
end)
parameter.action("Clear All", function()
bots = {}
obstacles = {}
end)
target = vec2(WIDTH / 1.5, HEIGHT / 1.5)
bots = {}
loop()
obstacles = {}
new = image(WIDTH, HEIGHT)
old = image(WIDTH, HEIGHT)
end

function loop()
if Autospawn then
table.insert(bots, Bot())
end
tween.delay(1, loop)
end

function draw()
rectMode(CENTER)

background(255)

noStroke()

setContext(old, false)
background(0, 0)
sprite(new, old.width / 2, old.height / 2, old.width, old.height)
setContext()
setContext(new, false)
background(0, 0)
for k, v in ipairs(obstacles) do
rect(v.x, v.y, v.size, v.size)
end

for k, v in ipairs(bots) do
v:draw()
end
setContext()
noTint()
sprite(new, WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)
tint(255, 127)
sprite(old, WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)

collectgarbage()
end

function touched(touch)
if tool == "find" then
local closest = 1
local tvec = vec2(touch.x, touch.y)
for k, v in ipairs(bots) do
if v.pos:dist(tvec) < bots[closest].pos:dist(tvec) then
closest = k
end
end
local null = {pos = vec2(0, 0)}
local cbot = bots[closest] or null
if cbot == null then
closest = 0
end
print("Closest is bot #" .. closest)
print("X: " .. cbot.pos.x .. "\nY: " .. cbot.pos.y)
elseif tool == "target" then
target = vec2(touch.x, touch.y)
for k, v in ipairs(bots) do
v.target = target
end
elseif tool == "obstacle" then
if touch.state == BEGAN then
table.insert(obstacles, {x = touch.x, y = touch.y, size = math.random(50, 150)})
end
elseif tool == "army" then
local gridx = 10
local gridy = 10
if touch.state == BEGAN or math.floor(touch.x / WIDTH * gridx + 0.5) ~= math.floor(touch.prevX / WIDTH * gridx + 0.5) or math.floor(touch.y / HEIGHT * gridy + 0.5) ~= math.floor(touch.prevY / HEIGHT * gridy + 0.5) then
table.insert(bots, Bot())
bots[#bots].target = vec2(math.floor(touch.x / WIDTH * gridx + 0.5) / gridx * WIDTH, math.floor(touch.y / HEIGHT * gridy + 0.5) / gridy * HEIGHT)
end
end
end

``````
Tagged:

• Mod
Posts: 8,505

@SkyTheCoder That reminds me of a swarm program I wrote for the 50 line challenge.

``````displayMode(FULLSCREEN)
function setup()
size,ob=25,0
objects1, objects2, objects3, objects4 = {},{},{},{}
for z=1,100 do
a=physics.body(CIRCLE,size)
a.x=math.random(WIDTH)
a.y=math.random(HEIGHT)
a.gravityScale=0
ob=(ob+1)%4
if ob==0 then table.insert(objects1,a)
elseif ob==1 then table.insert(objects2,a)
elseif ob==2 then table.insert(objects3,a)
elseif ob==3 then table.insert(objects4,a) end
end
target1 = vec2(WIDTH/2, HEIGHT-150)
target2 = vec2(WIDTH/2, 150)
target3 = vec2(150,HEIGHT/2)
target4 = vec2(WIDTH-150,HEIGHT/2)
end
function draw()
background(142, 88, 38, 255)   fill(255)
text("tap screen to swap groups.",WIDTH/2,HEIGHT/2)
drawMob(objects1,target1,"Planet Cute:Character Boy")
drawMob(objects2,target2,"Planet Cute:Character Cat Girl")
drawMob(objects3,target3,"Planet Cute:Character Horn Girl")
drawMob(objects4,target4,"Planet Cute:Character Pink Girl")
end
function drawMob(obj,tar,spr)
for i,v in ipairs(obj) do
move = tar - vec2(v.x, v.y)
if move:len() > 10 then move = move:normalize() * 10 end
v.x = v.x + move.x
v.y = v.y + move.y
sprite(spr, v.x, v.y, 20)
end
end
function touched(touch)
if touch.state==BEGAN then
target1,target2=target2,target1
target3,target4=target4,target3
end
end

``````
• Posts: 62

Nice game