diff --git a/src/DrawParticles.java b/src/DrawParticles.java index b4ba9c3..1c1aefa 100644 --- a/src/DrawParticles.java +++ b/src/DrawParticles.java @@ -11,7 +11,9 @@ import javax.microedition.lcdui.*; */ public class DrawParticles extends Canvas implements Runnable { - private static final int MAX_SNOW = 15; + private static final int MIN_SPEED = 2; + private static final int MAX_SPEED = 50; + private static final int MAX_SNOW = 50; private int w, h; private int speed, wind; @@ -21,13 +23,13 @@ public class DrawParticles extends Canvas implements Runnable { setFullScreenMode(true); w = getWidth(); h = getHeight(); - speed = 1; - wind = 0; + speed = MIN_SPEED; + wind = 250; Snow.setSpeed(speed); Snow.setWind(wind); particles = new Vector(); - for (int i = 0; i < 10; i++) { - particles.addElement(new Snow(w, h-10*i, MAX_SNOW*i+MAX_SNOW/3, i+1)); + for (int i = 0; i < (h/64); i++) { + particles.addElement(new Snow(w, h, MAX_SNOW)); } new Thread(this).start(); } @@ -37,12 +39,17 @@ public class DrawParticles extends Canvas implements Runnable { g.fillRect(0, 0, w, h); // рисуем системы for (int i = 0; i < particles.size(); i++) { - ((ParticleSystem) particles.elementAt(i)).render(g, speed); + ((ParticleSystem) particles.elementAt(i)).render(g); } } public void run() { while(true) { + if (Parameters.autoRotate) { + wind += 5; + if (wind > 360) wind = 0; + } + Snow.setWind(wind); repaint(); try { Thread.sleep(20); @@ -63,22 +70,22 @@ public class DrawParticles extends Canvas implements Runnable { switch (ga) { case UP: speed++; - if (speed > 30) speed = 30; + if (speed > MAX_SPEED) speed = MAX_SPEED; Snow.setSpeed(speed); break; case DOWN: speed--; - if (speed < 1) speed = 1; + if (speed < MIN_SPEED) speed = MIN_SPEED; Snow.setSpeed(speed); break; case RIGHT: wind++; - if (wind > 10) wind = 10; + if (wind > 360) wind = 0; Snow.setWind(wind); break; case LEFT: wind--; - if (wind < -10) wind = -10; + if (wind < 0) wind = 360; Snow.setWind(wind); break; } diff --git a/src/Parameters.java b/src/Parameters.java new file mode 100644 index 0000000..1ed540d --- /dev/null +++ b/src/Parameters.java @@ -0,0 +1,14 @@ +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +/** + * + * @author aNNiMON + */ +public class Parameters { + + /* Автоматическое вращение снежинок в 3D */ + public static boolean autoRotate = true; +} diff --git a/src/ParticleSystem.java b/src/ParticleSystem.java index 4f17bee..8ea0b7c 100644 --- a/src/ParticleSystem.java +++ b/src/ParticleSystem.java @@ -22,7 +22,7 @@ public abstract class ParticleSystem { } /* Отрисовка системы частиц */ - public void render(Graphics g, int speed) { + public void render(Graphics g) { update(); // сначала обновляем частицы g.clipRect(window.x, window.y, window.w, window.h); draw(g); // затем только рисуем diff --git a/src/Snow.java b/src/Snow.java index 9b5ef7f..6e1edb7 100644 --- a/src/Snow.java +++ b/src/Snow.java @@ -10,21 +10,21 @@ import javax.microedition.lcdui.Graphics; * @author aNNiMON */ public class Snow extends ParticleSystem { + + private static final float MIN_Z = 0.5f; + private /*static final*/ int MAX_Z = 15; + /* Скорость падения снега */ private static int speed; - /* Скорость и направление ветра */ - private static int wind; + /* Направление ветра */ + private static float windAngle; /* Начальный угол отрисовки снежинки */ private static float stAngle = 0; - /* Слой снежинок по Z */ - private float zPosition; - - public Snow(int w, int h, int numOfParticles, float zPos) { + public Snow(int w, int h, int numOfParticles) { super(0, 0, w, h, numOfParticles); - if (zPos > 10) zPos = 10; - zPosition = zPos+1; + MAX_Z = w / 15; for (int i = 0; i < particles.length; i++) { particles[i] = addParticle(); } @@ -37,58 +37,88 @@ public class Snow extends ParticleSystem { /* Установка скорости и направления ветра */ public static void setWind(int value) { - wind = value; + windAngle = (float) Math.toRadians(value); } /* Начальные свойства снежинки */ protected Point3D resetParticle() { Point3D snow = new Point3D(); - snow.x = Util.random(window.x, window.w); + snow.z = Util.random(1, MAX_Z); +// if ((int)Util.random(0, 5) == 2) snow.z = Util.random(1, MAX_Z/2); +// else snow.z = Util.random(MAX_Z/2, MAX_Z); + int w_x = (int) (window.x / snow.z); + int w_y = (int) (window.y / snow.z); + int w_w = (int) (window.w * snow.z); + int w_h = (int) (window.h * snow.z); + snow.x = Util.random(w_x, w_w); // создаём снежинки за экраном - snow.y = Util.random(window.y, window.h); - snow.z = zPosition; + snow.y = Util.random(w_y, w_h); + return snow; } protected void update() { for (int i = 0; i < particles.length; i++) { - particles[i].x = applyWind(particles[i].x); // ветер - particles[i].x += Util.random(-1+Util.sign(wind), 1+Util.sign(wind)); // прочие параметры - particles[i].y = particles[i].y + (speed / particles[i].z) + 0.981f; // скорость + притяжение - if (particles[i].y > window.h) { - if (wind > 0) particles[i].x = Util.random(window.x-wind*10, window.w); - else if (wind < 0) particles[i].x = Util.random(window.x, window.w-wind*10); - else particles[i].x = Util.random(window.x, window.w); - particles[i].y = window.y - Util.random(0, 10); - } else if (particles[i].x > window.w) { - if (wind > 0) particles[i].x = -Util.random(0, 10); - } else if (particles[i].x < window.x) { - if (wind < 0) particles[i].x = window.w+Util.random(0, 10); + particles[i].x += 2*Math.cos(windAngle);//applyWind(particles[i].x); // ветер по X + particles[i].z += 0.01f*Math.sin(windAngle);//*Util.random(-1, 1); // ветер по Z + //particles[i].x += Util.random(-1+Util.sign(wind), 1+Util.sign(wind)); // прочие параметры + particles[i].y = particles[i].y + speed + 0.981f; // скорость + притяжение + if (particles[i].z < MIN_Z) { + particles[i].z = MAX_Z; + particles[i].x = Util.random((int) (window.x / particles[i].z), + (int) (window.h * particles[i].z)); + particles[i].y = window.y-Util.random(0, 10); + } else if (particles[i].z > MAX_Z) { + particles[i].x = window.w + Util.random(0, 10); + particles[i].y = Util.random((int) (window.y / particles[i].z), + (int) (window.w * particles[i].z)); + particles[i].z = MIN_Z; + } +// if (particles[i].z < 1) particles[i].z = 1; +// else if (particles[i].z > MAX_Z) particles[i].z = MAX_Z; + int x = (int) (particles[i].x / particles[i].z); + int y = (int) (particles[i].y / particles[i].z); + int w_x = (int) (window.x / particles[i].z); + int w_y = (int) (window.y / particles[i].z); + int w_w = (int) (window.w * particles[i].z); + int wind_x = (int) (2*Math.cos(windAngle)); + if (y > window.h) { + if (wind_x > 0) particles[i].x = Util.random(w_x-wind_x*10, w_w); + else if (wind_x < 0) particles[i].x = Util.random(w_x, w_w-wind_x*10); + else particles[i].x = Util.random(w_x, w_w); + particles[i].y = w_y - Util.random(0, 10); + } else if (particles[i].x > w_w) { + if (wind_x > 0) particles[i].x = w_x-Util.random(0, 10); + } else if (x < w_x) { + //if (wind < 0) + particles[i].x = w_w+Util.random(0, 10); + particles[i].y = Util.random((int) (window.y / particles[i].z), + (int) (window.w * particles[i].z)); } } } protected void draw(Graphics g) { - g.setColor(Util.colorFromBrightness(255 - (int)((zPosition-1) * 12.7f))); for (int i = 0; i < particles.length; i++) { - int x = (int) particles[i].x; - int y = (int) particles[i].y; - if (zPosition > 6) g.drawLine(x, y, x, y); - else { - int radius = (int) (8 - zPosition); - drawSnow(g, x, y, radius); - } + if (particles[i].z < MIN_Z) continue; + g.setColor(Util.colorFromBrightness(255 - (int)(particles[i].z * (128 / MAX_Z)))); + int x = (int) (particles[i].x / particles[i].z); + int y = (int) (particles[i].y / particles[i].z); + int radius = (int) (MAX_Z / particles[i].z); + if (radius < 2) g.drawLine(x, y, x, y); + else drawSnow(g, x, y, radius); } } private float applyWind(float x) { - return (x + wind/5f); + return (x + windAngle/5f); } private void drawSnow(Graphics g, int x, int y, int radius) { - if (wind != 0) { - stAngle = stAngle + Util.sign(wind) * 0.0004f*(speed+Math.abs(wind)); - if (Math.abs(stAngle) > 90) stAngle = Util.sign(wind); + int wind_x = (int) (2*Math.cos(windAngle)); + if (Math.abs(wind_x) > 0.2f) { + stAngle = stAngle + Util.sign(wind_x) * 0.0004f*(speed+Math.abs(wind_x)); + if (Math.abs(stAngle) > 90) stAngle = Util.sign(wind_x); } for (float i = stAngle/2; i <= 180; i += 45) { int cos = (int) (Math.cos(i)*radius);