import processing.video.*;
Capture video;
// 기본 변수 선언
int maxParticles = 300;
float gravity = 1;
float friction = 0.05;
float fade = 2.5;
float flow = 5;
int ballsize = 25;
int oldX = 0;
int oldY = 0;
int mouseSpeedX = 0;
int mouseSpeedY = 0;
float wind = 0;
float windVarSpeed = 0;
float windMax = 5;
float windVarMaxSpeed = 0.5;
float windVarSpeedMaxVar = 0.5;
// ball 배열 선언
ball[] b = new ball[maxParticles];
// class ball 선언
public class ball {
float xSpeed;
float ySpeed;
float x, y; //소수 x,y 변수선언
int size;
float intensity;
boolean active; //불연산 선언- 참/거짓판별
ball(float x, float y, int size) { //ball 함수설정
xSpeed = 0;
ySpeed = 0;
this.x = x; // this.x의 값을 소수점으로 받음.
this.y = y; // this.y의 값을 소수점으로 받음.
this.size = size;
intensity = 255;
active = false; // active 가 거짓일때
}
void reset() {
intensity = 255;
active = true; // active 가 참일때
xSpeed = 0;
ySpeed = 0;
}
}
void setup(){ //setup 관련
size(640,480);
video = new Capture(this, width, height, 30);
noStroke();
smooth();
frameRate(30); // 초당 30프레임, 상단 비디오 캡쳐 속도와 같음.
for (int i = 0; i < maxParticles; i++) {
b[i] = new ball(100, 100, ballsize); // 볼생성 maxParticles(300개 위에서 설정) 만큼
}
}
// 볼 추가사항
void addBall(){
for (int i = 0; i < maxParticles; i++) {
if (!b[i].active) {
b[i].x = mouseX; // 추가되는 볼의 X시작위치
b[i].y = mouseY; // 추가되는 볼의 Y시작위치
b[i].reset();
b[i].ySpeed = -random(flow / 2, flow) + mouseSpeedY / 2;
b[i].xSpeed = random(-flow / 4, flow / 4) + mouseSpeedX / 2 + wind;
b[i].size = (int) random(ballsize - ballsize / 1.5, ballsize);
break;
}
}
}
// num 설정
int num = 80;
float bY[] = new float[num];
float bX[] = new float[num];
void draw(){
// background(102); //백그라운드 컬러 지정
// wind 볼이 떨어질때 움직임 설정
wind += windVarSpeed;
if (wind > windMax)
wind = windMax;
if (wind < -windMax)
wind = -windMax;
windVarSpeed += random(-windVarSpeedMaxVar, windVarSpeedMaxVar);
if (windVarSpeed > windVarMaxSpeed)
windVarSpeed = windVarMaxSpeed;
if (windVarSpeed < -windVarMaxSpeed)
windVarSpeed = -windVarMaxSpeed;
// wind 움직임 끝
if(video.available()){ // 이미지를 이용할 수 있다면...
video.read(); // 비디오를 읽어라
image(video, 0, 0,width, height); // 캡쳐 이미지 출력
int brightestX = 0; // 브라이티스X 초기값 설정
int brightestY = 0; // 브라이티스Y 초기값 설정
float brightestValue = 0; // 브라이티스밸류 초기값 설정
video.loadPixels(); // 비디오파일의 픽셀을 불러와라
int index = 0; // 정수 index 초기값 설정
for(int y = 0; y < video.height; y++){
for(int x = 0; x < video.width; x++){
int pixelValue = video.pixels[index]; // 정수 픽셀벨류값에 비디오의 픽셀첫값(0)을 저장
float pixelBrightness = brightness(pixelValue); // 소수 빅셀브라이트니스값에 브라이트니스값을 적용
if(pixelBrightness > brightestValue){
brightestValue = pixelBrightness;
brightestY = y;
brightestX = x;
// 빛에반응할때 add ball을 실행하라
if (oldX != 0) { // oldX 가 0이 아니면
mouseSpeedX = mouseX - oldX; //mouseSpeedX는 마우스X위치값-oldX
oldX = mouseX; //oldX값은 mouseX값으로 대입
} else {
oldX = mouseX; //oldX값은 mouseX값으로 대입
} if (oldY != 0) {
mouseSpeedY = mouseY - oldY;
oldY = mouseY;
} else {
oldY = mouseY;
}
addBall();
} else {
mouseSpeedX = mouseSpeedY = 0;
oldX = oldY = 0;
// add ball 빛에반응할때 설정 끝
}
index++; // 픽셀 index 값을 증가시켜라
}
}
for(int i=1; i<num; i++) {
bY[i-1] = bY[i];
bX[i-1] = bX[i];
}
bY[num-1] = brightestY;
bX[num-1] = brightestX;
// Draw the shape
//color c; // 컬러값 C
//c = color(255, 255, 255, (int) b[i].intensity);
//fill(c);
fill(255, 153);
// 실제 원 사이즈
for(int i=0; i<num; i++) {
ellipse(bX[i], bY[i], b[i].size, b[i].size);
}
/* 원본
for(int i=0; i<num; i++) {
ellipse(bX[i], bY[i], i/2, i/2);
}
*/
}
}