commit e75944fbe02a1e54592ff378017a3c6dc632968f Author: Victor Date: Wed Nov 14 23:02:34 2018 +0200 1 diff --git a/src/DrawParticles.java b/src/DrawParticles.java new file mode 100644 index 0000000..b4ba9c3 --- /dev/null +++ b/src/DrawParticles.java @@ -0,0 +1,91 @@ +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +import java.util.Vector; +import javax.microedition.lcdui.*; + +/** + * @author aNNiMON + */ +public class DrawParticles extends Canvas implements Runnable { + + private static final int MAX_SNOW = 15; + + private int w, h; + private int speed, wind; + private Vector particles; + + public DrawParticles() { + setFullScreenMode(true); + w = getWidth(); + h = getHeight(); + speed = 1; + wind = 0; + 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)); + } + new Thread(this).start(); + } + + public void paint(Graphics g) { + g.setColor(0);//xFF2895B9); + g.fillRect(0, 0, w, h); + // рисуем системы + for (int i = 0; i < particles.size(); i++) { + ((ParticleSystem) particles.elementAt(i)).render(g, speed); + } + } + + public void run() { + while(true) { + repaint(); + try { + Thread.sleep(20); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + } + + protected void sizeChanged(int w, int h) { + this.w = getWidth(); + this.h = getHeight(); + super.sizeChanged(w, h); + } + + protected void keyPressed(int key) { + int ga = getGameAction(key); + switch (ga) { + case UP: + speed++; + if (speed > 30) speed = 30; + Snow.setSpeed(speed); + break; + case DOWN: + speed--; + if (speed < 1) speed = 1; + Snow.setSpeed(speed); + break; + case RIGHT: + wind++; + if (wind > 10) wind = 10; + Snow.setWind(wind); + break; + case LEFT: + wind--; + if (wind < -10) wind = -10; + Snow.setWind(wind); + break; + } + } + + protected void keyRepeated(int key) { + keyPressed(key); + } + +} diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..cf1455d --- /dev/null +++ b/src/Main.java @@ -0,0 +1,33 @@ +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +import javax.microedition.lcdui.*; +import javax.microedition.midlet.*; + +/** + * @author aNNiMON + */ +public class Main extends MIDlet { + + public Display dsp; + public static Main midlet; + + public Main() { + midlet = Main.this; + dsp = Display.getDisplay(Main.this); + } + + public void startApp() { + DrawParticles dp = new DrawParticles(); + dsp.setCurrent(dp); + } + + public void pauseApp() { + } + + public void destroyApp(boolean ex) { + notifyDestroyed(); + } +} diff --git a/src/ParticleSystem.java b/src/ParticleSystem.java new file mode 100644 index 0000000..4f17bee --- /dev/null +++ b/src/ParticleSystem.java @@ -0,0 +1,60 @@ + +import javax.microedition.lcdui.Graphics; + +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +/** + * Базовый класс системы частиц + * @author aNNiMON + */ +public abstract class ParticleSystem { + + /* Массив частицы */ + protected Point3D[] particles; + protected Rectangle window; + + public ParticleSystem(int x, int y, int w, int h, int numOfParticles) { + window = new Rectangle(x, y, w, h); + particles = new Point3D[numOfParticles]; + } + + /* Отрисовка системы частиц */ + public void render(Graphics g, int speed) { + update(); // сначала обновляем частицы + g.clipRect(window.x, window.y, window.w, window.h); + draw(g); // затем только рисуем + } + + /* Добавление частицы */ + protected Point3D addParticle() { + return resetParticle(); + } + + /* Сброс свойств частицы */ + protected abstract Point3D resetParticle(); + /* Обновление свойств частиц */ + protected abstract void update(); + /* Отрисовка частиц */ + protected abstract void draw(Graphics g); + + /* Точка в 3D */ + protected class Point3D { + float x, y, z; + int color; + } + + /* Прямоугольник */ + protected class Rectangle { + int x, y, w, h; + + public Rectangle(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + } +} diff --git a/src/Snow.java b/src/Snow.java new file mode 100644 index 0000000..9b5ef7f --- /dev/null +++ b/src/Snow.java @@ -0,0 +1,99 @@ + +import javax.microedition.lcdui.Graphics; + +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +/** + * @author aNNiMON + */ +public class Snow extends ParticleSystem { + + /* Скорость падения снега */ + private static int speed; + /* Скорость и направление ветра */ + private static int wind; + /* Начальный угол отрисовки снежинки */ + private static float stAngle = 0; + + /* Слой снежинок по Z */ + private float zPosition; + + public Snow(int w, int h, int numOfParticles, float zPos) { + super(0, 0, w, h, numOfParticles); + if (zPos > 10) zPos = 10; + zPosition = zPos+1; + for (int i = 0; i < particles.length; i++) { + particles[i] = addParticle(); + } + } + + /* Установка скорости падения снега */ + public static void setSpeed(int value) { + speed = value; + } + + /* Установка скорости и направления ветра */ + public static void setWind(int value) { + wind = value; + } + + /* Начальные свойства снежинки */ + protected Point3D resetParticle() { + Point3D snow = new Point3D(); + snow.x = Util.random(window.x, window.w); + // создаём снежинки за экраном + snow.y = Util.random(window.y, window.h); + snow.z = zPosition; + 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); + } + } + } + + 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); + } + } + } + + private float applyWind(float x) { + return (x + wind/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); + } + for (float i = stAngle/2; i <= 180; i += 45) { + int cos = (int) (Math.cos(i)*radius); + int sin = (int) (Math.sin(i)*radius); + g.drawLine(x-cos, y-sin, x+cos, y+sin); + } + } +} diff --git a/src/Util.java b/src/Util.java new file mode 100644 index 0000000..9ee5b52 --- /dev/null +++ b/src/Util.java @@ -0,0 +1,37 @@ + +import java.util.Random; + +/* + * aNNiMON 2011 + * For more info visit http://annimon.com/ + */ + +/** + * + * @author aNNiMON + */ +public class Util { + + private static final Random rnd = new Random(); + + /** + * Получить цвет ARGB из яркости. Оттенки серого. + * @param value яркость + * @return ARGB цвет + */ + public static int colorFromBrightness(int value) { + return 0xFF000000 | (value << 16) | (value << 8) | (value); + } + + /* Получить случайное float значение в промежутке (from; to) */ + public static float random(int from, int to) { + return rnd.nextInt(to-from)+from+rnd.nextFloat(); + } + + /* Возвращает знак числа */ + public static int sign(int number) { + if (number > 0) return 1; + else if (number < 0) return -1; + else return 0; + } +}