Моделирование дождя
Я делаю игру в java, и я хочу создать симуляцию облака, заливающего дождь. Предполагается, что облако будет двигаться вправо, пока идет дождь. Перемещение облака не проблема. Это дождь, с которым я борюсь.
То, что я собирался сделать, было с помощью таймера рисовать прямоугольник, который должен был выглядеть как падающий дождь при случайном значении x внутри облака. А затем добавьте 1 к значению y падения каждые 100 миллисекунд. Но я не хочу создавать 100 разных прямоугольников, x переменных и y переменных для каждого дождя.
Любая идея, как я могу это сделать? Предложения оценены!
Это игра 2d.. Извините.
Ответы
Ответ 1
Я бы рекомендовал просто хранить значения как ArrayList объектов.
class Raindrop {
private int x;
private int y;
public void fall() {
y--;
}
}
Затем создайте ArrayList с общим типом.
ArrayList<Raindrop> drops = new ArrayList<Raindrop>();
Чтобы сделать каждое падение падения,
for (int i=0; i<drops.length(); i++) {
drops.get(i).fall();
}
Ответ 2
Один из подходов - рассмотреть шатер в театре. Вы берете серию лампочек и, освещая их и туша их последовательно, можете имитировать линейное движение.
Точно так же, вместо того, чтобы создавать капли дождя и оживлять их движение, почему бы не создать несколько невидимых капель дождя и показать их и спрятать их последовательно, чтобы имитировать движение вниз. Затем у вас будет серия массивов, представляющих дорожку капли дождя, и вам просто нужно будет прокручивать ее, скрывая текущую, увеличивая указатель на массив и отображая ее.
Ответ 3
Требуется ли запрограммировать дождь? Традиционно это делается с помощью нескольких дождевых спрайтов, которые вы размещаете под облаком и живите так, чтобы казалось, что дождь падает.
Ответ 4
Вот моя реализация java (swing) 2d дождя с каплями, всплеском, ветром и гравитацией
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main( String [] args ) {
JFrame frame = new JFrame();
frame.setSize(800, 300);
final RPanel rPanel=new RPanel();
frame.add(rPanel);
frame.setVisible( true );
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
rPanel.stop();
System.exit(0);
}
});
}
}
class RPanel extends JPanel {
//*********SETTINGS****************************
private float mWind = 2.05f;
private float mGravity = 9.8f;
private double mRainChance = 0.99; // from 0 to 1
private int mRepaintTimeMS = 16;
private float mRainWidth=1;
private double mDdropInitialVelocity = 20;
private double mDropDiam = 2;
private Color mColor=new Color(0, 0, 255);
//*********************************************
private ArrayList<Rain> rainV;
private ArrayList<Drop> dropV;
private UpdateThread mUpdateThread;
public RPanel() {
rainV = new ArrayList<>();
dropV = new ArrayList<>();
mUpdateThread=new UpdateThread();
mUpdateThread.start();
}
public void stop() {
mUpdateThread.stopped=true;
}
public int getHeight() {
return this.getSize().height;
}
public int getWidth() {
return this.getSize().width;
}
private class UpdateThread extends Thread {
public volatile boolean stopped=false;
@Override
public void run() {
while (!stopped) {
RPanel.this.repaint();
try {
Thread.sleep(mRepaintTimeMS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(mRainWidth));
g2.setColor(mColor);
//DRAW DROPS
Iterator<Drop> iterator2 = dropV.iterator();
while (iterator2.hasNext()) {
Drop drop = iterator2.next();
drop.update();
drop.draw(g2);
if (drop.y >= getHeight()) {
iterator2.remove();
}
}
//DRAW RAIN
Iterator<Rain> iterator = rainV.iterator();
while (iterator.hasNext()) {
Rain rain = iterator.next();
rain.update();
rain.draw(g2);
if (rain.y >= getHeight()) {
//create new drops (2-8)
long dropCount = 1 + Math.round(Math.random() * 4);
for (int i = 0; i < dropCount; i++) {
dropV.add(new Drop(rain.x, getHeight()));
}
iterator.remove();
}
}
//CREATE NEW RAIN
if (Math.random() < mRainChance) {
rainV.add(new Rain());
}
}
//*****************************************
class Rain {
float x;
float y;
float prevX;
float prevY;
public Rain() {
Random r = new Random();
x = r.nextInt(getWidth());
y = 0;
}
public void update() {
prevX = x;
prevY = y;
x += mWind;
y += mGravity;
}
public void draw(Graphics2D g2) {
Line2D line = new Line2D.Double(x, y, prevX, prevY);
g2.draw(line);
}
}
//*****************************************
private class Drop {
double x0;
double y0;
double v0; //initial velocity
double t; //time
double angle;
double x;
double y;
public Drop(double x0, double y0) {
super();
this.x0 = x0;
this.y0 = y0;
v0 = mDdropInitialVelocity;
angle = Math.toRadians(Math.round(Math.random() * 180)); //from 0 - 180 degrees
}
private void update() {
// double g=10;
t += mRepaintTimeMS / 100f;
x = x0 + v0 * t * Math.cos(angle);
y = y0 - (v0 * t * Math.sin(angle) - mGravity * t * t / 2);
}
public void draw(Graphics2D g2) {
Ellipse2D.Double circle = new Ellipse2D.Double(x, y, mDropDiam, mDropDiam);
g2.fill(circle);
}
}
}
Ответ 5
Вы можете использовать систему частиц или использовать вектор капель дождя и анимировать их каждые X миллисекунд. Ссылка на библиотеку систем частиц: http://code.google.com/p/jops/
пример кода для вектора:
import java.util.Vector;
// In your class
Vector raindrops;
void animate()
{
ListIterator iter = raindrops.listIterator;
while (iter.hasNext()) {
((Raindrop)iter.next()).moveDown();
}
}