最近在做一个rpg小游戏,研究到粒子系统。粒子系统(particle system)是图形里常用的特效。粒子系统可应用运动学模拟来做到很多不同的效果。粒子系统在游戏和动画中,常常会用来做雨点、火花、烟、爆炸等等不同的视觉效果。
粒子系统模拟大量的粒子,并通常用某些方法把粒子渲染。粒子通常有以下特性:
粒子是独立的,粒子之间互不影响(不碰撞、没有力) 粒子有生命周期,生命结束后会消失 粒子可以理解为空间的一个点,有时候也可以设定半径作为球体和环境碰撞 粒子带有运动状态,也有其他外观状态(例如颜色、影像等) 粒子可以只有线性运动,而不考虑旋转运动(也有例外) 下图是本人实现的一个酷酷的粒子效果(截图效果不太好,实际运行效果好很多)。
当然你可以发挥你的想象力,制作更有意思的粒子效果。记得以前看到国外有的网站用的那种全像素点的验证码,其实思路差不多。实现代码如下:
粒子系统模拟大量的粒子,并通常用某些方法把粒子渲染。粒子通常有以下特性:
粒子是独立的,粒子之间互不影响(不碰撞、没有力) 粒子有生命周期,生命结束后会消失 粒子可以理解为空间的一个点,有时候也可以设定半径作为球体和环境碰撞 粒子带有运动状态,也有其他外观状态(例如颜色、影像等) 粒子可以只有线性运动,而不考虑旋转运动(也有例外) 下图是本人实现的一个酷酷的粒子效果(截图效果不太好,实际运行效果好很多)。

import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class SnowWord extends Application{
private List snow = new LinkedList<>();
double gravity = 0.15D;
@Override
public void start(Stage stage) throws Exception{
WritableImage image = new WritableImage(500, 400);
drawString(image, "东方上人", 60, 200);
final PixelReader reader = image.getPixelReader();
Canvas show = new Canvas(500, 400);
final GraphicsContext context = show.getGraphicsContext2D();
new AnimationTimer(){
@Override
public void handle(long arg0){
context.clearRect(0, 0, 500, 400);
context.setFill(Color.BLACK);
context.fillRect(0, 0, 500, 400);
context.setFill(Color.WHITE);
Iterator it = snow.iterator();
while(it.hasNext()){
Point p = it.next();
p.vy += gravity * p.s;
p.y += p.vy;
if(p.y >= 400){
it.remove();
}else{
/* 指定坐标处是否处在文字上 */
if(reader.getColor((int) p.x, (int) p.y).equals(Color.BLACK)){
p.y -= p.vy;
p.vy = 0;
p.y += 0.2;
}
context.fillOval(p.x, p.y, 2, 2);
}
}
for(int i = 0; i < 10; i++){
snow.add(new Point(Math.random() * 500, 0, Math.random() + 0.5));
}
}
}.start();
Scene scene = new Scene(new Group(show));
stage.setScene(scene);
stage.setTitle("粒子系统 - www.zhouhaocheng.cn");
stage.show();
}
public void drawString(WritableImage image, String text, int x, int y){
BufferedImage buffer = SwingFXUtils.fromFXImage(image, null);
Graphics g = buffer.getGraphics();
g.setColor(java.awt.Color.BLACK);
g.setFont(new Font("Microsoft YaHei", 1, 100));
g.drawString(text, x, y);
SwingFXUtils.toFXImage(buffer, image);
g.dispose();
}
public static void main(String[] args){
launch(args);
}
static class Point{
double x; // x坐标
double y; // y坐标
double s; // 下降加速度
double vy; // y轴方向速度
public Point(double x, double y, double s){
this.x = x;
this.y = y;
this.s = s;
this.vy = 0;
}
public String toString(){
return x + " , " + y + " , " + s + " , " + vy;
}
}
}
当然你可以发挥你的想象力,制作更有意思的粒子效果。记得以前看到国外有的网站用的那种全像素点的验证码,其实思路差不多。实现代码如下:
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;
public class NoisyCaptcha{
// 图片的宽度。
private int width = 120;
// 图片的高度。
private int height = 40;
private String fontName;
private int fontStyle = 1;
private int fontSize;
private static String codes = "abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
public NoisyCaptcha(int width, int height){
this(width, height, "Microsoft YaHei", 1, height - 10);
}
public NoisyCaptcha(int width, int height, String fontName, int fontStyle, int fontSize){
this.width = width;
this.height = height;
this.fontName = fontName;
this.fontStyle = fontStyle;
this.fontSize = fontSize;
}
public BufferedImage genCode(String text){
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
g.setFont(new Font(fontName, fontStyle, fontSize));
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.BLACK);
g.drawString(text, width / 2 - fm.stringWidth(text) / 2, height / 2 + fm.getAscent() / 3);
g.dispose();
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = result.createGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setColor(Color.WHITE);
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
double r = Math.random();
/* 如下0.65和0.95可根据实际显示效果调整 */
if(image.getRGB(i, j) == Color.BLACK.getRGB()){
if(r > 0.65) g.drawOval(i, j, 1, 1);
}else if(r > 0.95){
g.drawOval(i, j, 1, 1);
}
}
}
g.dispose();
return result;
}
public static String generateTextCode(int verifySize){
int codesLen = codes.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for(int i = 0; i < verifySize; i++){
verifyCode.append(codes.charAt(rand.nextInt(codesLen - 1)));
}
return verifyCode.toString();
}
}
生成的验证码图片效果入下: 
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2314
- 用户1336
- 访客11813325
每日一句
Let's seek joy in the simple, quiet moments.
让我们在简单宁静的时刻中寻找快乐。
让我们在简单宁静的时刻中寻找快乐。