# Mob movement

So I’m trying to get some objects to follow where I touch and I have something working, but they all go to the same point and look like one object. I want them to move more like a mob, not overlapping each other. This is what I have so far:

``````
--# Main
-- Targeted Motion

displayMode(FULLSCREEN)
function setup()
objects = {}
table.insert(objects, {WIDTH/2, HEIGHT/2, 10})
table.insert(objects, {WIDTH, HEIGHT, 10})
table.insert(objects, {0, HEIGHT, 10})
table.insert(objects, {WIDTH, 0, 10})
table.insert(objects, {0, 0, 10})

target = vec2(WIDTH/2, HEIGHT/2)
end

function draw()
background(142, 88, 38, 255)

strokeWidth(5)
line(0,0, WIDTH,HEIGHT)
line(0,HEIGHT, WIDTH,0)

for i,v in ipairs(objects) do
move = target - vec2(v, v)
if move:len() > v then
move = move:normalize() * v
end
v = v + move.x
v = v + move.y

sprite("Cargo Bot:Codea Icon", v, v, 50)
end
end

function touched(touch)
target = vec2(touch.x, touch.y)
end
``````

What you need to do is compare the x,y position of all the objects and don’t update their positions if they’re within a set minimum distance of each other.

Maybe this can be of interest?

http://twolivesleft.com/Codea/Talk/discussion/2222/swarm-of-ships#Item_3

Perhaps Google flocking, this is a very simple algorithm for what you want

@JakAttak Not sure what you’re going to use the mob for, but here is a simple version that might work for you.

``````
--# Main
-- Targeted Motion

displayMode(FULLSCREEN)
function setup()
size=20
objects = {}
for z=1,20 do
a=physics.body(CIRCLE,size)
a.x=math.random(WIDTH)
a.y=math.random(HEIGHT)
a.gravityScale=0
table.insert(objects,a)
end
target = vec2(WIDTH/2, HEIGHT/2)
end

function draw()
background(142, 88, 38, 255)
strokeWidth(5)
line(0,0, WIDTH,HEIGHT)
line(0,HEIGHT, WIDTH,0)
for i,v in ipairs(objects) do
move= target - 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("Cargo Bot:Codea Icon", v.x, v.y, 20)
end
end

function touched(touch)
target = vec2(touch.x, touch.y)
end

``````

@dave1707, I’m working on a little game where a horde of people follows you around. Thanks for that! Does simply making them physics bodies stop the, from being able to run into each other?

The physics bodies repell each other. You can adjust the distance they stay from each other by changing the value of size. If you change the value in the for loop from 20 to 100, it looks like they’re attacking whatever is in the center.

Awesome. Thanks!

@dave1707 that’s a great effect. Cheers

@JakAttak Very good idea
http://youtu.be/_mH6pPwdwB0

@JakAttak I modified the code again to show 2 mobs. The 1st mob sits in the center of the screen. The 2nd mob can be moved around depending on where you tap the screen. Kind of interesting watching the mob move around the stationary one.

``````
--# Main
-- Targeted Motion

displayMode(FULLSCREEN)
function setup()
size=30
size1=30
objects = {}
for z=1,30 do
a=physics.body(CIRCLE,size)
a.x=math.random(WIDTH)
a.y=math.random(HEIGHT)
a.gravityScale=0
table.insert(objects,a)
end
objects1 = {}
for z=1,15 do
a=physics.body(CIRCLE,size1)
a.x=math.random(WIDTH)
a.y=math.random(HEIGHT)
a.gravityScale=0
table.insert(objects1,a)
end
target = vec2(WIDTH/2, HEIGHT/2)
target1 = vec2(WIDTH/2, 100)
end

function draw()
background(142, 88, 38, 255)
strokeWidth(5)
line(0,0, WIDTH,HEIGHT)
line(0,HEIGHT, WIDTH,0)
for i,v in ipairs(objects) do
move= target - 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("Planet Cute:Tree Short", v.x, v.y, 20)
end
for i,v in ipairs(objects1) do
move= target1 - 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("Planet Cute:Character Pink Girl", v.x, v.y, 20)
end
end

function touched(touch)
target1 = vec2(touch.x, touch.y)
end

``````

Here’s another example of 4 mobs. Just tap the screen when the mobs are in their area.

``````
--# Main
-- Targeted Motion

displayMode(FULLSCREEN)
function setup()
size=25
ob=0
objects1 = {}
objects2 = {}
objects3 = {}
objects4 = {}
for z=1,120 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)
strokeWidth(5)
line(0,0, WIDTH,HEIGHT)
line(0,HEIGHT, WIDTH,0)
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
xx=target1
target1 = target2
target2=xx
xx=target3
target3=target4
target4=xx
end
end

``````