2012-07-02 29 views
10

Tôi đang tạo một trò chơi bằng java và tôi muốn tạo mô phỏng một đám mây đổ mưa. Đám mây được cho là di chuyển sang phải trong khi trời mưa. Di chuyển đám mây là không có vấn đề. Đó là mưa mà tôi đang đấu tranh với.Mô phỏng mưa

Những gì tôi đã nghĩ đến khi làm là với một bộ đếm thời gian để vẽ một hình chữ nhật, có nghĩa vụ phải giống như mưa rơi ở một giá trị x ngẫu nhiên bên trong đám mây. Và sau đó thêm 1 vào giá trị y của mỗi 100 mili giây. Nhưng tôi không muốn tạo ra 100 hình chữ nhật, biến x và biến y khác nhau cho từng giọt mưa.

Bất kỳ ý tưởng nào về cách tôi có thể thực hiện việc này? Đề xuất được đánh giá cao!


Đây là trò chơi 2ngày .. Rất tiếc.

+0

Dưới đây là một liên kết mà có thể trợ giúp: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3704&lngWId=2. Nó được viết bằng Java 1.2 vì vậy tôi không chắc đó có phải là giải pháp tốt nhất hay không, nhưng nó vẫn có thể cung cấp cho bạn cái nhìn sâu sắc. – Josh

+0

trông interresting, cảm ơn! sẽ xem xét –

+0

Đảm bảo: Đây có phải là trò chơi 2D không? Ngang là đường chân trời, chiều dọc là chiều cao và không có chiều sâu? –

Trả lời

2

Tôi khuyên bạn chỉ nên lưu trữ các giá trị dưới dạng ArrayList của đối tượng.

class Raindrop { 
    private int x; 
    private int y; 

    public void fall() { 
     y--; 
    } 
} 

Sau đó tạo một ArrayList với loại chung.

ArrayList<Raindrop> drops = new ArrayList<Raindrop>(); 

Để thực hiện từng giọt rơi,

for (int i=0; i<drops.length(); i++) { 
    drops.get(i).fall(); 
} 
+0

chưa bao giờ sử dụng danh sách mảng trước đây. Sẽ đọc một chút về nó. Cảm ơn! –

+0

Vì vậy, tôi đang đấu tranh để hiểu điều này.Tôi nên đặt tuyên bố cho đâu? –

+0

Sự hiểu biết của tôi là lớp Vector không được chấp nhận, vì vậy ArrayList đang thay thế nó. – danmcardle

3

Một cách tiếp cận sẽ là xem xét vùng chọn trên nhà hát. Bạn lấy một loạt các bóng đèn, và bằng cách chiếu sáng và dập tắt chúng theo thứ tự, bạn có thể mô phỏng chuyển động tuyến tính. Trong cùng một cách, thay vì tạo ra các hạt mưa và làm động tác chuyển động của chúng, tại sao không tạo ra nhiều hạt mưa vô hình và hiển thị và ẩn chúng theo trình tự để mô phỏng chuyển động đi xuống. Sau đó, bạn sẽ có một loạt các mảng đại diện cho một rãnh theo dõi mưa và bạn chỉ cần chu kỳ thông qua, ẩn hiện tại, tăng con trỏ mảng và hiển thị con trỏ đó.

+0

Có thể là một giải pháp hợp lệ. Cảm ơn. –

0

Bạn có thể sử dụng hệ thống hạt hoặc sử dụng vector của hạt mưa và tạo ảnh động cho mỗi X mili giây. Một liên kết đến một thư viện hệ thống hạt: http://code.google.com/p/jops/

dụ mã cho vector:

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

Có một yêu cầu rằng những giọt mưa được lập trình? Theo truyền thống, điều này sẽ được thực hiện với một vài sprites mưa mà bạn đặt dưới đám mây và animate để nó trông giống như mưa đang rơi.

2

Đây là java của tôi (swing) thực hiện mưa 2d với giọt, giật gân, gió và lực hấp dẫn

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