模拟雨

时间:2012-07-02 14:45:46

标签: java paintcomponent

我正在用java制作游戏,我想创建一个倾盆大雨的模拟。云应该在下雨时向右移动。移动云是没有问题的。这是我正在努力的下雨。

我想要做的是使用计时器绘制一个矩形,这应该看起来像是在云中的随机x值下雨。然后每100毫秒将下降的y值加1。但我不想为每次降雨创建100个不同的矩形,x变量和y变量。

知道我怎么能做到这一点?建议赞赏!


这是一场2D游戏..抱歉。

5 个答案:

答案 0 :(得分:3)

一种方法是考虑剧院的大帐篷。你拍摄了一系列灯泡,通过依次点亮和熄灭它们,你可以模拟线性运动。

同样地,为什么不创造多个不可见的雨滴并且按顺序显示和隐藏它们以模拟向下运动,而不是创建雨滴和动画它们的运动。然后,您将拥有一系列表示雨滴轨道的数组,您只需要循环,然后隐藏当前的数组,递增数组指针并显示该数组指针。

答案 1 :(得分:3)

是否需要编制雨滴?传统上,这可以通过你放置在云下的一些雨精灵和动画来完成,这样看起来就像下雨一样。

答案 2 :(得分:2)

我建议只将值存储为对象的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();
}

答案 3 :(得分:2)

这是我的用于降雨,飞溅,风和重力的2d雨的java(swing)实现

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);
    }
}
}

答案 4 :(得分:0)

您可以使用粒子系统或使用雨滴矢量并每X毫秒为其设置动画。指向粒子系统库的链接:http://code.google.com/p/jops/

vector的示例代码:

import java.util.Vector;
// In your class
Vector raindrops;
void animate()
{
    ListIterator iter = raindrops.listIterator;
    while (iter.hasNext()) {
        ((Raindrop)iter.next()).moveDown();
    }
}