最近在做一个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 Listsnow = 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)
站点信息
- 文章2305
- 用户1336
- 访客11456237
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员