N = 50
WindowX = 300.0
WindowY = 100.0
param1 = 1.0
param2 = 0.05
param3 = 1.0
param4 = 0.0
#undef circle
#module
#defcfunc rand
return 1.0 * rnd(32768) / 32768
#deffunc circle int px, int py, int r
circle@hsp px - r, py - r, px + r, py + r, 1
return
#global
randomize
ddim position, N, 2
ddim speed, N, 2
for k, 0, N
position(k, 0) = rand() * WindowX
position(k, 1) = rand() * WindowY
speed(k, 0) = rand() * 0.9 + 0.1
speed(k, 1) = rand() * 0.9 + 0.1
next
ddim distance, N, N
screen 0, WindowX, WindowY
title "boids"
repeat
// 描画
redraw 0
color $FF, $FF, $FF :boxf
color $00, $00, $FF
for k, 0, N
circle position(k, 0), position(k, 1), 2
next
redraw 1
// 距離計算
for i, 0, N - 1
for j, i + 1, N
dx = position(i, 0) - position(j, 0)
dy = position(i, 1) - position(j, 1)
d = sqrt(dx * dx + dy * dy)
distance(i, j) = d
distance(j, i) = d
next
next
// 座標更新
for k, 0, N
dx = mousex - position(k, 0)
dy = mousey - position(k, 1)
d = sqrt(dx * dx + dy * dy)
if(d != 0.0){
speed(k, 0) += dx / d * param4
speed(k, 1) += dy / d * param4
}
// ルール1
vx1 = 0.0 :vy1 = 0.0
for m, 0, N
if(m == k) :_continue
vx1 += position(m, 0)
vy1 += position(m, 1)
next
vx1 /= (N - 1) :vy1 /= (N - 1)
vx1 = (vx1 - position(k, 0)) / 100
vy1 = (vy1 - position(k, 1)) / 100
// ルール2
vx2 = 0.0 :vy2 = 0.0
for m, 0, N
if(m == k) :_continue
dx = position(m, 0) - position(k, 0)
dy = position(m, 1) - position(k, 1)
if(dx * dx + dy * dy >= 100.0) :_continue
vx2 -= dx
vy2 -= dy
next
// ルール3
vx3 = 0.0 :vy3 = 0.0
for m, 0, N
if(m == k) :_continue
vx3 += speed(m, 0)
vy3 += speed(m, 1)
next
vx3 /= (N - 1) :vy3 /= (N - 1)
vx3 = (vx3 - speed(k, 0)) / 8
vy3 = (vy3 - speed(k, 1)) / 8
// 反映
speed(k, 0) += vx1 * param1 + vx2 * param2 + vx3 * param3
speed(k, 1) += vy1 * param1 + vy2 * param2 + vy3 * param3
position(k, 0) += speed(k, 0)
position(k, 1) += speed(k, 1)
next
for k, 0, N
// 反射判定
px = position(k, 0)
py = position(k, 1)
if(px < 0.0) :px = 0.0 :speed(k, 0) = -speed(k, 0)
if(px > WindowX) :px = WindowX :speed(k, 0) = -speed(k, 0)
if(py < 0.0) :py = 0.0 :speed(k, 1) = -speed(k, 1)
if(py > WindowY) :py = WindowY :speed(k, 1) = -speed(k, 1)
position(k, 0) = px
position(k, 1) = py
next
await 50
loop