Created
April 9, 2013 06:06
-
-
Save p5info/5343320 to your computer and use it in GitHub Desktop.
@fladdict さんの 「JSでアメーバのシミュレーション作ってみた」 http://fladdict.net/blog/2013/04/js-ameba.html のjavascriptソースコードをProcessing及びProcessing.jsで動くように修正してみた。動くように修正しただけなので、リファクタリングもかけてないですし、中のコメントも残したまんまです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int numberOfNodes = 200; | |
Node[] nodes = new Node[numberOfNodes]; | |
int pressedCount = 0; | |
float pressedX; | |
float pressedY; | |
//var calcTable; | |
float lineAlpha = 0; | |
void setup() { | |
size(displayWidth, displayHeight); //Processing 2.x以降はdisplayWidth | |
//size(screenWidth, screenHeight); //if Processing 1.5.1まではscreenWidth | |
background(0, 0, 0); | |
//For FullScreen | |
//@//HTMLのためのコードなので無視 | |
//@ window.onresize = function() | |
//@ { | |
//@ size(window.innerWidth,window.innerHeight); | |
//@ }; | |
setup2(); | |
} | |
void setup2() { | |
for (int i=0; i<numberOfNodes; i++) { | |
Node nd = new Node(); | |
nd.x = random(1f) * width; | |
nd.y = random(1f) * height; | |
nd.nodes = nodes; | |
nd.nodeType = int(random(1f)*2); | |
nodes[i]= nd; | |
}; | |
//@高速化テーブル [NodeXId][NodeYId][dx,dy,dist]; | |
//@あとで採用して最適化すること | |
//@ calcTable = []; | |
//@ for(var yy=0; i<numberOfNodes; yy++){ | |
//@ var ar = []; | |
//@ for(var xx=0; j<numberOfNodes; xx++){ | |
//@ ar.push([0,0,0]); | |
//@ } | |
//@ calcTable.push(ar); | |
//@ } | |
} | |
void draw() { | |
colorMode(RGB, 255); | |
fill(0); | |
noStroke(); | |
rect(0, 0, width, height); | |
int n = nodes.length; | |
if (pressedCount>0) { | |
pressedCount--; | |
for (int i=0; i<n; i++) { | |
Node nd = nodes[i]; | |
nd.maxVelocity=3; | |
nd.friction = 0.99; | |
nd.updateVelocity(); | |
nd.updatePosition(); | |
} | |
}else { | |
lineAlpha = lineAlpha + (1-lineAlpha)*0.01; | |
for (int i=0; i<n; i++) { | |
Node nd = nodes[i]; | |
nd.maxVelocity=1; | |
nd.friction = 0.9; | |
nd.resetForce(); | |
nd.update(); | |
} | |
} | |
for (int i=0; i<n; i++) | |
{ | |
for (int j=i; j<n; j++) | |
{ | |
Node nd0 = nodes[i]; | |
Node nd1 = nodes[j]; | |
if (nd0!=nd1) { | |
float dx = nd1.x - nd0.x; | |
float dy = nd1.y - nd0.y; | |
float dist = sqrt(dx*dx+dy*dy); | |
if (dist<150 && dist!=0 && nd0.nodeType==nd1.nodeType) { | |
//255で0、 100で1 | |
// (255-dist); | |
float strokeCol = (150-dist)*1.5; | |
stroke(strokeCol * lineAlpha); | |
line(nd0.x, nd0.y, nd1.x, nd1.y); | |
} | |
} | |
} | |
} | |
for (int i=0; i<n; i++) { | |
Node nd = nodes[i]; | |
nd.draw(); | |
}; | |
} | |
void mousePressed() | |
{ | |
pressedCount = 120; | |
pressedX = mouseX; | |
pressedY = mouseY; | |
lineAlpha = 0; | |
int n = nodes.length; | |
for (int i=0; i<n; i++) { | |
Node nd = nodes[i]; | |
float fx = nd.x - mouseX; | |
float fy = nd.y - mouseY; | |
float dist = sqrt(fy*fy+fx*fx); | |
float rad = atan2(fy, fx); | |
if (dist>1) { | |
nd.fx += cos(rad)/dist*800; | |
nd.fy += sin(rad)/dist*800; | |
nd.updateVelocity(); | |
nd.updatePosition(); | |
} | |
}; | |
} | |
class Node { | |
float x =0; | |
float y = 0; | |
float vx = 0; | |
float vy = 0; | |
int maxVelocity = 2; | |
float fx = 0; | |
float fy = 0; | |
int nodeType; | |
float rotation = 0; | |
Node[] nodes; | |
float friction = 0.9; | |
void init() { | |
} | |
void update() { | |
this.updateBoid(); | |
this.updateVelocity(); | |
this.updatePosition(); | |
} | |
void resetForce() | |
{ | |
this.fx = 0; | |
this.fy = 0; | |
} | |
void updateBoid() | |
{ | |
//ここでBoid計算 | |
int n = this.nodes.length; | |
//Calc Position | |
int deathCount = 0; | |
float fx = 0; | |
float fy = 0; | |
//仲間に近づく / 離れる | |
for (int i=0; i<n; i++) { | |
Node nd = this.nodes[i]; | |
if (nd==this) | |
continue; | |
float dx = nd.x - this.x; | |
float dy = nd.y - this.y; | |
float dist = sqrt(dx*dx+dy*dy); | |
if (dist<50 && dist>1) { | |
deathCount++; | |
fx -= dx / dist / dist / dist * 40; | |
fy -= dy / dist / dist / dist * 40; | |
} | |
else if (dist<200 && this.nodeType==nd.nodeType) { | |
fx += dx / dist / dist / dist * 30; | |
fy += dy / dist / dist / dist * 30; | |
} | |
} | |
//仲間と同じ方向に移動する | |
for (int i=0; i<n; i++) { | |
Node nd = this.nodes[i]; | |
if (nd==this) | |
continue; | |
float dx = nd.x - this.x; | |
float dy = nd.y - this.y; | |
float dist = sqrt(dx*dx+dy*dy); | |
if (dist>1) { | |
float vx = nd.vx; | |
float vy = nd.vy; | |
float rad = atan2(vy, vx); | |
fx += cos(rad) /dist/dist; | |
fy += sin(rad) /dist/dist; | |
} | |
} | |
//マウスから逃げる | |
float mfx = mouseX - this.x; | |
float mfy = mouseY - this.y; | |
float mdist = sqrt(mfx*mfx+mfy*mfy); | |
float mrad = atan2(mfy, mfx); | |
//console.log(mdist); | |
if (mdist>0) { | |
fx -= cos(mrad)/mdist/mdist*300; | |
fy -= sin(mrad)/mdist/mdist*300; | |
} | |
/* | |
if(deathCount>20){ | |
this.x = random()*width; | |
this.y = random()*height; | |
}*/ | |
//Normalize Speed | |
//@//変数distが参照可能なスコープから見当たらない。 | |
//@ float d = dist(fx, fy); | |
//@ if (d>1) { | |
//@ fx = fx / dist; | |
//@ fy = fy / dist; | |
//@ } | |
this.fx += (random(1f)-0.5)*0.2; | |
this.fy += (random(1f)-0.5)*0.2; | |
this.fx += fx * 3; | |
this.fy += fy * 3; | |
} | |
void updateVelocity() | |
{ | |
this.vx = this.vx * this.friction + this.fx; | |
this.vy = this.vy * this.friction + this.fy; | |
//@//dist(x1,y1,x2,y2)なので動かない。 | |
//@//this.vx / v * this.maxVelocity;が代入などが行われない無効なコード | |
//@ float v = dist(this.vx, this.vy); | |
//@ if (v>this.maxVelocity) { | |
//@ this.vx / v * this.maxVelocity; | |
//@ this.vy / v * this.maxVelocity; | |
//@ } | |
} | |
void updatePosition() | |
{ | |
this.x += this.vx; | |
this.y += this.vy; | |
if (this.x<0) { | |
this.x =0; | |
this.vx = abs(this.vx); | |
this.fx = 0; | |
} | |
if (this.x>width) { | |
this.x=width; | |
this.vx = -abs(this.vx); | |
this.fx = 0; | |
} | |
if (this.y<0) { | |
this.y=0; | |
this.vy = abs(this.vy); | |
this.fy = 0; | |
} | |
if (this.y>height) { | |
this.y=height; | |
this.vy = -abs(this.vy); | |
this.fy = 0; | |
} | |
} | |
void draw() | |
{ | |
stroke(150); | |
ellipse(this.x, this.y, 10, 10); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment