Mod: Coding Challenge #88: Snowfall
Processingで書きながらところどころ自己流で書いた.いわゆるスプライト画像と言われるような,複数の画像がタイル状に配置された1枚の画像を読み込んで適宜使用するようなやり方をやっている.メリークリスマス.
コード
// img src : https://alca.tv/static/f32.png ArrayList<Snowflake> snow = new ArrayList<Snowflake>(); int num = 1000; PVector gravity; ArrayList<PImage> textures = new ArrayList<PImage>(); float zOff = 0; void setup() { size(960, 540); colorMode(HSB, 360, 100, 100); PImage img = loadImage("f32.png"); for (int y = 0; y < img.height; y += 32) { for (int x = 0; x < img.width; x += 32) { textures.add(img.get(x, y, 32, 32)); } } gravity = new PVector(0, 0.006); for (int i = 0; i < num; i++) { snow.add(new Snowflake()); } } void draw() { background(0, 0, 0); //snow.add(new Snowflake()); for (Snowflake sf : snow) { float xOff = sf.pos.x / width; float yOff = sf.pos.y / height; float wAngle = noise(xOff, yOff, zOff) * TWO_PI; PVector wind = PVector.fromAngle(wAngle); wind.mult(0.002); sf.applyForce(gravity); sf.applyForce(wind); sf.update(); sf.render(); } for (int i = snow.size()-1; i > 0; i--) { Snowflake sf = snow.get(i); if (sf.isOffScreen()) { sf.randomize(); sf.pos.y = random(-100, -10); } } zOff += 0.01; } class Snowflake { PVector pos; PVector vel; PVector acc; float r; PImage img; float angle; float dir; float freq; Snowflake() { randomize(); } void randomize() { r = getRandomSize(); float x = random(-r, width+r); float y = random(-height, height); pos = new PVector(x, y); vel = new PVector(); acc = new PVector(); angle = random(TWO_PI); dir = (random(1) > 0.5) ? -1: 1; int n = (int)random(textures.size()); img = textures.get(n); freq = random(0.01,0.1); } void applyForce(PVector force) { PVector f = force.copy(); f.mult(r); acc.add(f); } void update() { vel.add(acc); vel.limit(r * 0.2); if (vel.mag() < 1) { vel.normalize(); } pos.add(vel); acc.mult(0); if (pos.x < -r) { pos.x += width+r; } else if (pos.x > width + r) { pos.x -= width+r; } } void render() { //stroke(0, 0, 100); //strokeWeight(r); //point(pos.x, pos.y); pushMatrix(); translate(pos.x, pos.y); rotate(angle+freq*frameCount); imageMode(CENTER); image(img, 0, 0, r, r); popMatrix(); } boolean isOffScreen() { return (pos.y > height + r); } float getRandomSize() { /* method 3. */ float r = pow(random(1), 5); return constrain(r * 36, 2, 36); /* method 2. */ //float r = randomGaussian() * 2; //return constrain(abs(r*r), 2, 36); /* method 1. */ //while (true) { // float r1 = random(1); // float r2 = random(1); // if (r2 > r1) { // return r1 * 36; // } //} } }