关于 粒子系统 求教。 小弟想实现火焰燃烧,水中很多由一个点发出气泡的上升等效果,想用粒子系统来处理。由于没有用过,再次想请教DN的大神指点一二。先谢过。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的 game physics。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。http://baike.baidu.com/view/85873.htm粒子系统的应用——雪花飞舞http://www.pconline.com.cn/pcedu/sj/media/3dsmax/0405/367973.html希望对你有帮助 //SnowPic.javaimport java.applet.Applet;import java.awt.*;import java.util.Random;public class SnowPic extends Applet implements Runnable { // 变量声明 Thread mainThread; Image offScreen; Image gAlc[]; Random rand; int stopFlag; int snows; int wind; int threadSleep; int snowSize; int snowX[]; int snowY[]; long stopTime; Dimension dim; MediaTracker mt; // 构造函数 public SnowPic() { stopTime = 0L; } // 得到一个字符串和一个整数类型的参数 int getParameter(String s, int i) { String s1 = getParameter(s); return s1 == null ? i : Integer.parseInt(s1); } // 得到一个字符串和三个整数类型的参数 int getParameter(String s, int i, int j, int k) { String s1 = getParameter(s); if (s1 != null) { if ((i = Integer.parseInt(s1)) > j) return j; if (i < k) return k; else return i; } else { return i; } } // 得到两个字符串的参数 String getParameter(String s, String s1) { String s2 = getParameter(s); return s2 == null ? s1 : s2; } // 初始化小程序 public void init() { rand = new Random(); dim = getSize(); offScreen = createImage(dim.width, dim.height); snows = getParameter("snows", 100, 500, 0); snowSize = getParameter("snowSize", 3, 10, 3); threadSleep = getParameter("threadsleep", 80, 1000, 10); snowX = new int[snows]; snowY = new int[snows]; for (int i = 0; i < snows; i++) { snowX[i] = rand.nextInt() % (dim.width / 2) + dim.width / 2; snowY[i] = rand.nextInt() % (dim.height / 2) + dim.height / 2; } mt = new MediaTracker(this); gAlc = new Image[1]; gAlc[0] = getImage(getDocumentBase(), getParameter("graphic", "test.gif")); mt.addImage(gAlc[0], 0); try { mt.waitForID(0); } catch (InterruptedException interruptedexception) { return; } stopFlag = 0; } // 启动小程序 public void start() { if (mainThread == null) { mainThread = new Thread(this); mainThread.start(); } } // 停止小程序 public void stop() { mainThread = null; } // 运行小程序 public void run() { while (mainThread != null) { try { Thread.sleep(threadSleep); } catch (InterruptedException interruptedexception) { return; } repaint(); } } // 生成雪花 public void drawBackSnow(Graphics g) { g.setColor(Color.white); for (int i = 0; i < snows; i++) { g.fillOval(snowX[i], snowY[i], snowSize, snowSize); snowX[i] += rand.nextInt() % 2 + wind; snowY[i] += (rand.nextInt() % 6 + 5) / 5 + 1; if (snowX[i] >= dim.width) snowX[i] = 0; if (snowX[i] < 0) snowX[i] = dim.width - 1; if (snowY[i] >= dim.height || snowY[i] < 0) { snowX[i] = Math.abs(rand.nextInt() % dim.width); snowY[i] = 0; } } wind = rand.nextInt() % 5 - 2; } // 画屏函数 public void paint(Graphics g) { offScreen.getGraphics().setColor(Color.black); offScreen.getGraphics().fillRect(0, 0, dim.width, dim.height); offScreen.getGraphics().drawImage(gAlc[0], 0, 0, this); drawBackSnow(offScreen.getGraphics()); g.drawImage(offScreen, 0, 0, null); } // 更新屏幕函数 public void update(Graphics g) { paint(g); }}这个符合要求吗 可以自己修改下画雪花,以雪花的总数作为循环条件,通过一个for循环结构,制作雪花,雪花位置的横坐标通过语句snowX[i] += rand.nextInt() % 2 + wind确定,雪花位置的纵坐标通过语句snowY[i] += (rand.nextInt() % 6 + 5) / 5 + 1确定。雪花间的相对速度再调下,让它感觉更真实。 火焰效果://flame.javaimport java.applet.Applet;import java.applet.AppletContext;import java.awt.*;import java.awt.image.MemoryImageSource;import java.awt.image.PixelGrabber;import java.net.MalformedURLException;import java.net.URL;import java.util.Random;import java.util.StringTokenizer;public class Flame extends Applet implements Runnable { // 变量声明 static final int XSIZE = 300; static final int YSIZE = 100; static final int XS = 1; static final int XE = 299; static final int YS = 1; static final int XB = 15; static final int BOTTOM = 29700; static final int MAXPAL = 256; int pal[] = null; static final int SMOOTH = 1; static final int decay = 6; Random rd = null; Image art = null; Thread motor = null; int off[] = null; int count = 0; int burn = 0; static final int YLEN = 50; static final long TW_DLAY = 8000L; static final long TW_FADE = 5000L; static final int TW_LEN = 1000; static final int TW_MAXCOLOR = 30; int tw_words[][] = null; int tw_max = 0; int tw_count = 0; long tw_timer = 0; int tw_color[] = null; boolean tw_isLink = false; String tw_link = null; static final int gXSIZE = 300; static final int gYSIZE = 10; // 响应鼠标事件 public boolean handleEvent(Event event) { if (event.target == this) switch (event.id) { case 501: // Event.MOUSE_DOWN burn = 40; return true; case 503: // Event.MOUSE_MOVE if (!tw_isLink || event.y < 100) showStatus("Click to cool flames."); else showStatus("Link to " + tw_link); return true; case 502: // Event.MOUSE_UP if (!tw_isLink || event.y < 100) return true; URL url; try { url = new URL(tw_link); } catch (MalformedURLException _ex) { return false; } stop(); getAppletContext().showDocument(url); return true; } return super.handleEvent(event); } // 产生随机数 int rand(int n) { return Math.abs(rd.nextInt() % n); } // 得到颜色值 int colorit(int c) { return pal[c & 0xff]; } // 变换颜色 int coloroff(int c) { return (c & 0xff0000) >> 16; } // 行扫描 void processline(int i) { int offset = 300; int poffset = offset - 300; if (i <= 1 || i >= 299) { for (int j = 1; j < 100; j++) { off[i + poffset] = 0xff000000; poffset += 300; } return; } for (int j = 1; j < 100; j++) { int c = coloroff(off[i + offset]); if (c < 6) off[i + poffset] = 0xff000000; else off[(i - (rand(3) - 1)) + poffset] = colorit(c - rand(6)); poffset += 300; offset += 300; } } // 颜色处理 void smoothBottom() { for (int i = 2; i < 298; i++) { int total = 0; for (int j = -1; j <= 1; j++) total += coloroff(off[29700 + i + j]); off[29700 + i] = colorit(total / 3); } } // 随机染色 void splashRandom() { int d = rand(15); int max = 298; for (int i = 0; i < d; i++) { int c = rand(max); int col = coloroff(off[29701 + c]); if ((col &= 0x7) < 0) col = 0; off[29701 + c] = colorit(col); } } // 染色 void splash() { int max = 298; for (int i = 0; i < 25; i++) { int d = rand(4) + 2; int c = rand(max - d); for (int j = 0; j < d; j++) { off[29701 + c] = 0xff000000; c++; } } } // 染色过程 public synchronized void process() { int mid = 150; for (int i = rand(8); i > 0; i--) { int c = rand(268) + 15; for (int j = 0; j < 10; j++) off[29700 + c + j] = colorit(180 + rand(76)); } if (burn > 0) { splash(); burn--; } splashRandom(); smoothBottom(); for (int i = 1; i < mid; i++) processline(i); for (int i = 299; i >= mid; i--) processline(i); } // 调色 void makepal() { for (int i = 0; i < 256; i++) pal[i] = 0xff000000; for (int i = 1; i < 110; i++) pal[i] = 0xff000000 | i << 16 | (i * 3) / 5 << 8 | i / 5; for (int i = 110; i < 256; i++) { int c = pal[i - 1] & 0xff00ffff; if ((c & 0xff00) < 60928) c += 256; if ((c & 0xff00) < 60928) c += 256; if ((c & 0xff) < 255) c++; pal[i] = 0xff000000 | c | i << 16; } } // 设置显示效果 void tw_begin() { for (int i = 0; i < 30; i++) tw_color[i] = pal[170 + i] + 80; tw_isLink = true; tw_link = getParameter("link"); if (tw_link == null) tw_isLink = false; String fts = getParameter("font"); if (fts == null) fts = "TimesRoman"; Image twImg = createImage(300, 50); Graphics twGrp = twImg.getGraphics(); twGrp.setFont(new Font(fts, 1, 40)); FontMetrics fm = twGrp.getFontMetrics(); String words = getParameter("text"); if (words == null) words = "IonChron+presents+Flames+by+IoN CheN"; StringTokenizer st = new StringTokenizer(words, "+"); tw_max = st.countTokens(); tw_words = new int[tw_max][1000]; tw_count = 0; while (st.hasMoreTokens()) { clearOff(); String str = st.nextToken(); twGrp.setColor(Color.black); twGrp.fillRect(0, 0, 300, 50); twGrp.setColor(Color.white); twGrp.drawString(str, (300 - fm.stringWidth(str)) / 2, 40); PixelGrabber pg = new PixelGrabber(twImg, 0, 0, 300, 50, off, 0, 300); boolean grabbed = true; try { pg.grabPixels(); } catch (InterruptedException _ex) { grabbed = false; } if (grabbed) { int i = 1; for (int keep = 0; keep < 15000 && i < 999;) { int cnt; for (cnt = 0; keep < 15000 && (off[keep++] & 0xffffff) == 0; cnt++) ; tw_words[tw_count][i++] = cnt + 1; for (cnt = 1; keep < 15000 && (off[keep++] & 0xffffff) != 0; cnt++) ; tw_words[tw_count][i++] = cnt; } tw_words[tw_count][0] = i - 1; tw_count++; } } tw_max = tw_count; twGrp = null; twImg.flush(); twImg = null; tw_count = tw_max - 1; tw_timer = (System.currentTimeMillis() + 8000L) - 5000L; } // 显示过程 void tw_process() { long ctime = System.currentTimeMillis(); if (ctime <= tw_timer) { if (ctime < tw_timer - 5000L) { int i = 1; int offset = 9000; for (int max = tw_words[tw_count][0]; i < max;) { offset += tw_words[tw_count][i++]; for (int count = tw_words[tw_count][i++]; --count >= 0;) off[offset++] = tw_color[rand(30)]; } return; } } else { if (++tw_count >= tw_max) tw_count = 0; tw_timer = System.currentTimeMillis() + 8000L; } } // 画屏函数 public void paint(Graphics g) { g.setFont(new Font("Helvetica", 0, 9)); g.setColor(new Color(255, 200, 240)); update(g); } // 更新屏幕函数 public void update(Graphics g) { art = createImage(new MemoryImageSource(300, 100, off, 0, 300)); g.drawImage(art, 0, 0, null); art.flush(); } // 初始化小程序 public void init() { setLayout(null); addNotify(); resize(300, 110); setBackground(new Color(0, 20, 40)); } // 开始小程序 public void start() { makepal(); motor = new Thread(this); motor.setPriority(1); motor.start(); } // 停止小程序 public void stop() { motor.stop(); } void clearOff() { for (int i = 0; i < 30000; i++) off[i] = 0xff000000; } void drawBottom() { } // 运行小程序 public void run() { tw_begin(); clearOff(); do { process(); tw_process(); repaint(); try { Thread.sleep(1L); } catch (InterruptedException _ex) { } } while (true); } // 构造函数 public Flame() { pal = new int[256]; rd = new Random(); off = new int[30000]; tw_color = new int[30]; }} 如何获得windows整个桌面内容 50分求解!scjp! 帮助改一下程序 java 调用dll操作powerpoint CLASSPATH的疑问,目录还是JAR文件! 谁知道JAVA编程思想可以在哪下载? 有分 偏门问题,不难。 求个正则~~~ 这个什么问题啊,报错 关于Structs2 valuestack问题 排序问题 httpclient使用中session问题
http://baike.baidu.com/view/85873.htm粒子系统的应用——雪花飞舞
http://www.pconline.com.cn/pcedu/sj/media/3dsmax/0405/367973.html
希望对你有帮助
//SnowPic.java
import java.applet.Applet;
import java.awt.*;
import java.util.Random;public class SnowPic extends Applet implements Runnable {
// 变量声明
Thread mainThread;
Image offScreen;
Image gAlc[];
Random rand;
int stopFlag;
int snows;
int wind;
int threadSleep;
int snowSize;
int snowX[];
int snowY[];
long stopTime;
Dimension dim;
MediaTracker mt; // 构造函数
public SnowPic() {
stopTime = 0L;
} // 得到一个字符串和一个整数类型的参数
int getParameter(String s, int i) {
String s1 = getParameter(s);
return s1 == null ? i : Integer.parseInt(s1);
} // 得到一个字符串和三个整数类型的参数
int getParameter(String s, int i, int j, int k) {
String s1 = getParameter(s);
if (s1 != null) {
if ((i = Integer.parseInt(s1)) > j)
return j;
if (i < k)
return k;
else
return i;
} else {
return i;
}
} // 得到两个字符串的参数
String getParameter(String s, String s1) {
String s2 = getParameter(s);
return s2 == null ? s1 : s2;
} // 初始化小程序
public void init() {
rand = new Random();
dim = getSize();
offScreen = createImage(dim.width, dim.height);
snows = getParameter("snows", 100, 500, 0);
snowSize = getParameter("snowSize", 3, 10, 3);
threadSleep = getParameter("threadsleep", 80, 1000, 10);
snowX = new int[snows];
snowY = new int[snows];
for (int i = 0; i < snows; i++) {
snowX[i] = rand.nextInt() % (dim.width / 2) + dim.width / 2;
snowY[i] = rand.nextInt() % (dim.height / 2) + dim.height / 2;
} mt = new MediaTracker(this);
gAlc = new Image[1];
gAlc[0] = getImage(getDocumentBase(), getParameter("graphic",
"test.gif"));
mt.addImage(gAlc[0], 0);
try {
mt.waitForID(0);
} catch (InterruptedException interruptedexception) {
return;
}
stopFlag = 0;
} // 启动小程序
public void start() {
if (mainThread == null) {
mainThread = new Thread(this);
mainThread.start();
}
} // 停止小程序
public void stop() {
mainThread = null;
} // 运行小程序
public void run() {
while (mainThread != null) {
try {
Thread.sleep(threadSleep);
} catch (InterruptedException interruptedexception) {
return;
}
repaint();
}
} // 生成雪花
public void drawBackSnow(Graphics g) {
g.setColor(Color.white);
for (int i = 0; i < snows; i++) {
g.fillOval(snowX[i], snowY[i], snowSize, snowSize);
snowX[i] += rand.nextInt() % 2 + wind;
snowY[i] += (rand.nextInt() % 6 + 5) / 5 + 1;
if (snowX[i] >= dim.width)
snowX[i] = 0;
if (snowX[i] < 0)
snowX[i] = dim.width - 1;
if (snowY[i] >= dim.height || snowY[i] < 0) {
snowX[i] = Math.abs(rand.nextInt() % dim.width);
snowY[i] = 0;
}
} wind = rand.nextInt() % 5 - 2;
} // 画屏函数
public void paint(Graphics g) {
offScreen.getGraphics().setColor(Color.black);
offScreen.getGraphics().fillRect(0, 0, dim.width, dim.height);
offScreen.getGraphics().drawImage(gAlc[0], 0, 0, this);
drawBackSnow(offScreen.getGraphics());
g.drawImage(offScreen, 0, 0, null);
} // 更新屏幕函数
public void update(Graphics g) {
paint(g);
}
}这个符合要求吗 可以自己修改下画雪花,以雪花的总数作为循环条件,通过一个for循环结构,制作雪花,雪花位置的横坐标通过语句snowX[i] += rand.nextInt() % 2 + wind确定,雪花位置的纵坐标通过语句snowY[i] += (rand.nextInt() % 6 + 5) / 5 + 1确定。
雪花间的相对速度再调下,让它感觉更真实。
//flame.java
import java.applet.Applet;
import java.applet.AppletContext;
import java.awt.*;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import java.util.StringTokenizer;public class Flame extends Applet implements Runnable {
// 变量声明
static final int XSIZE = 300;
static final int YSIZE = 100;
static final int XS = 1;
static final int XE = 299;
static final int YS = 1;
static final int XB = 15;
static final int BOTTOM = 29700;
static final int MAXPAL = 256;
int pal[] = null;
static final int SMOOTH = 1;
static final int decay = 6;
Random rd = null;
Image art = null;
Thread motor = null;
int off[] = null;
int count = 0;
int burn = 0;
static final int YLEN = 50;
static final long TW_DLAY = 8000L;
static final long TW_FADE = 5000L;
static final int TW_LEN = 1000;
static final int TW_MAXCOLOR = 30;
int tw_words[][] = null;
int tw_max = 0;
int tw_count = 0;
long tw_timer = 0;
int tw_color[] = null;
boolean tw_isLink = false;
String tw_link = null;
static final int gXSIZE = 300;
static final int gYSIZE = 10; // 响应鼠标事件
public boolean handleEvent(Event event) {
if (event.target == this)
switch (event.id) {
case 501: // Event.MOUSE_DOWN
burn = 40;
return true; case 503: // Event.MOUSE_MOVE
if (!tw_isLink || event.y < 100)
showStatus("Click to cool flames.");
else
showStatus("Link to " + tw_link);
return true; case 502: // Event.MOUSE_UP
if (!tw_isLink || event.y < 100)
return true;
URL url;
try {
url = new URL(tw_link);
} catch (MalformedURLException _ex) {
return false;
}
stop();
getAppletContext().showDocument(url);
return true; }
return super.handleEvent(event);
} // 产生随机数
int rand(int n) {
return Math.abs(rd.nextInt() % n);
} // 得到颜色值
int colorit(int c) {
return pal[c & 0xff];
} // 变换颜色
int coloroff(int c) {
return (c & 0xff0000) >> 16;
} // 行扫描
void processline(int i) {
int offset = 300;
int poffset = offset - 300;
if (i <= 1 || i >= 299) {
for (int j = 1; j < 100; j++) {
off[i + poffset] = 0xff000000;
poffset += 300;
} return;
}
for (int j = 1; j < 100; j++) {
int c = coloroff(off[i + offset]);
if (c < 6)
off[i + poffset] = 0xff000000;
else
off[(i - (rand(3) - 1)) + poffset] = colorit(c - rand(6));
poffset += 300;
offset += 300;
} } // 颜色处理
void smoothBottom() {
for (int i = 2; i < 298; i++) {
int total = 0;
for (int j = -1; j <= 1; j++)
total += coloroff(off[29700 + i + j]); off[29700 + i] = colorit(total / 3);
} } // 随机染色
void splashRandom() {
int d = rand(15);
int max = 298;
for (int i = 0; i < d; i++) {
int c = rand(max);
int col = coloroff(off[29701 + c]);
if ((col &= 0x7) < 0)
col = 0;
off[29701 + c] = colorit(col);
} } // 染色
void splash() {
int max = 298;
for (int i = 0; i < 25; i++) {
int d = rand(4) + 2;
int c = rand(max - d);
for (int j = 0; j < d; j++) {
off[29701 + c] = 0xff000000;
c++;
} } } // 染色过程
public synchronized void process() {
int mid = 150;
for (int i = rand(8); i > 0; i--) {
int c = rand(268) + 15;
for (int j = 0; j < 10; j++)
off[29700 + c + j] = colorit(180 + rand(76)); } if (burn > 0) {
splash();
burn--;
}
splashRandom();
smoothBottom();
for (int i = 1; i < mid; i++)
processline(i); for (int i = 299; i >= mid; i--)
processline(i); } // 调色
void makepal() {
for (int i = 0; i < 256; i++)
pal[i] = 0xff000000; for (int i = 1; i < 110; i++)
pal[i] = 0xff000000 | i << 16 | (i * 3) / 5 << 8 | i / 5; for (int i = 110; i < 256; i++) {
int c = pal[i - 1] & 0xff00ffff;
if ((c & 0xff00) < 60928)
c += 256;
if ((c & 0xff00) < 60928)
c += 256;
if ((c & 0xff) < 255)
c++;
pal[i] = 0xff000000 | c | i << 16;
} } // 设置显示效果
void tw_begin() {
for (int i = 0; i < 30; i++)
tw_color[i] = pal[170 + i] + 80; tw_isLink = true;
tw_link = getParameter("link");
if (tw_link == null)
tw_isLink = false;
String fts = getParameter("font");
if (fts == null)
fts = "TimesRoman";
Image twImg = createImage(300, 50);
Graphics twGrp = twImg.getGraphics();
twGrp.setFont(new Font(fts, 1, 40));
FontMetrics fm = twGrp.getFontMetrics();
String words = getParameter("text");
if (words == null)
words = "IonChron+presents+Flames+by+IoN CheN";
StringTokenizer st = new StringTokenizer(words, "+");
tw_max = st.countTokens();
tw_words = new int[tw_max][1000];
tw_count = 0;
while (st.hasMoreTokens()) {
clearOff();
String str = st.nextToken();
twGrp.setColor(Color.black);
twGrp.fillRect(0, 0, 300, 50);
twGrp.setColor(Color.white);
twGrp.drawString(str, (300 - fm.stringWidth(str)) / 2, 40);
PixelGrabber pg = new PixelGrabber(twImg, 0, 0, 300, 50, off, 0,
300);
boolean grabbed = true;
try {
pg.grabPixels();
} catch (InterruptedException _ex) {
grabbed = false;
}
if (grabbed) {
int i = 1;
for (int keep = 0; keep < 15000 && i < 999;) {
int cnt;
for (cnt = 0; keep < 15000 && (off[keep++] & 0xffffff) == 0; cnt++)
;
tw_words[tw_count][i++] = cnt + 1;
for (cnt = 1; keep < 15000 && (off[keep++] & 0xffffff) != 0; cnt++)
;
tw_words[tw_count][i++] = cnt;
} tw_words[tw_count][0] = i - 1;
tw_count++;
}
} tw_max = tw_count;
twGrp = null;
twImg.flush();
twImg = null;
tw_count = tw_max - 1;
tw_timer = (System.currentTimeMillis() + 8000L) - 5000L;
} // 显示过程
void tw_process() {
long ctime = System.currentTimeMillis();
if (ctime <= tw_timer) {
if (ctime < tw_timer - 5000L) {
int i = 1;
int offset = 9000;
for (int max = tw_words[tw_count][0]; i < max;) {
offset += tw_words[tw_count][i++];
for (int count = tw_words[tw_count][i++]; --count >= 0;)
off[offset++] = tw_color[rand(30)]; } return;
}
} else {
if (++tw_count >= tw_max)
tw_count = 0;
tw_timer = System.currentTimeMillis() + 8000L;
}
} // 画屏函数
public void paint(Graphics g) {
g.setFont(new Font("Helvetica", 0, 9));
g.setColor(new Color(255, 200, 240));
update(g);
} // 更新屏幕函数
public void update(Graphics g) {
art = createImage(new MemoryImageSource(300, 100, off, 0, 300));
g.drawImage(art, 0, 0, null);
art.flush();
} // 初始化小程序
public void init() {
setLayout(null);
addNotify();
resize(300, 110);
setBackground(new Color(0, 20, 40));
} // 开始小程序
public void start() {
makepal();
motor = new Thread(this);
motor.setPriority(1);
motor.start();
} // 停止小程序
public void stop() {
motor.stop();
} void clearOff() {
for (int i = 0; i < 30000; i++)
off[i] = 0xff000000; } void drawBottom() {
} // 运行小程序
public void run() {
tw_begin();
clearOff();
do {
process();
tw_process();
repaint();
try {
Thread.sleep(1L);
} catch (InterruptedException _ex) {
}
} while (true);
} // 构造函数
public Flame() {
pal = new int[256];
rd = new Random();
off = new int[30000];
tw_color = new int[30];
}
}