xxxxxxxxxx
// パーティクルクラス
class P{
// 座標
float x;
float xV;
float y;
float yV;
// 擬似回転(2DなのでScaleでがんばる)
float spinX;
float spinXV;
float spinY;
float spinYV;
// 回転
float rot;
float rotV;
P(){
x = random(500);
xV = 0;
y = random(500);
spinX = random(360);
spinY = random(360);
rot = random(360);
init();
}
// 初期化
void init(){
yV = random(1) + 0.5;
spinXV = random(2) + 1;
spinYV = random(2) + 1;
rotV = random(1) + 0.5;
}
// 描画
void act(float dir){
// 各種パラメータ計算
spinX += spinXV;
spinY += spinYV;
rot += rotV;
x += xV;
y += yV;
// 雪の描画
pushMatrix();
translate(x, y);
scale(sin(radians(spinX)), sin(radians(spinY)));
rotate(radians(rot));
rect(0, 0, 10, 10);
popMatrix();
// 停止判定
// ※まず中心からの距離を求める
float tx = x - width / 2;
float ty = y - height / 2;
float d = sqrt(tx * tx + ty * ty);
float a = atan2(ty, tx);
// 中心から半径以上離れた = 球に張り付いたということ
if(d >= width / 2 && ty < 0){
// まだ上半分にいる場合は、横の移動を停止し、落下する。ついでに球の内側に移動させる。
x = cos(a) * (d - 1) + width / 2;
y = sin(a) * (d - 1) + height / 2;
xV = 0;
}else if(d >= width / 2 && ty >= 0){
// 下半分にいる場合は停止
xV = 0;
yV = 0;
rotV = 0;
spinXV = 0;
spinYV = 0;
}else if(yV == 0){
// 停止している場合は復帰
init();
xV = dir * 0.1; // 回転速度を考慮して横移動量を決定
}
}
// 回転処理
void rote(float dir){
// 回転するため極座標系に変換
float tx = x - width / 2;
float ty = y - height / 2;
float dist = sqrt(tx * tx + ty * ty);
float ang = degrees(atan2(ty, tx));
// 回転
ang += dir;
// 新しい位置をセット
x = cos(radians(ang)) * dist + width / 2;
y = sin(radians(ang)) * dist + height / 2;
}
}
ArrayList<P> lists = new ArrayList<P>();
float direction = 0; // 回転量
float rotateAng = 0; // 回転量積算
void setup() {
size(500, 500);
noStroke();
rectMode(CENTER);
for(int i = 0; i < 100; i++){
p = new P();
lists.add(p);
}
}
void draw() {
background(64);
// 球の描画
fill(0);
ellipse(width / 2, height / 2, width, height);
// 回転量計算
direction = pmouseX - mouseX;
rotateAng += direction;
drawTree();
fill(255);
for(P p : lists){
p.act(direction);
p.rote(direction);
}
}
void drawTree(){
pushMatrix();
translate(width / 2, height / 2);
rotate(radians(rotateAng));
fill(64, 64, 0);
rect(0, 160, 20, 180);
fill(0, 128, 0);
triangle(0, 50, -50, 120, 50, 120);
triangle(0, 100, -50, 170, 50, 170);
triangle(0, 150, -50, 220, 50, 220);
popMatrix();
}