JavaFX实现水波效果

上传人:ba****u6 文档编号:174119768 上传时间:2022-12-14 格式:DOCX 页数:12 大小:66.23KB
返回 下载 相关 举报
JavaFX实现水波效果_第1页
第1页 / 共12页
JavaFX实现水波效果_第2页
第2页 / 共12页
JavaFX实现水波效果_第3页
第3页 / 共12页
点击查看更多>>
资源描述
JavaFX实现水波效果public class JfxRipper extends Application private final double MAX_WIDTH = 400.0;private final double MAX_HEIGHT = 400.0;private static AnimationTimer timer;private static AnimationTimer rainTimer;private FileChooser fc;private double scaleRate;stonePower;private int maxRainSize, maxRainPower, stoneSize,private int imgWidth, imgHeight;int arrWaveCurrent;/ 当前帧各点波动能量数据int arrWaveNext;/ 下一帧各点波动能量数据private Image img;private WritableImage imgRipper;private ImageView imgView;Overridepublic void init() throws Exception fc = new FileChooser();/添加文件类型过滤 fc.getExtensionFilters().add(new FileChooser.Ex tension Filt er(图片文件, *.jpg;*.png;*.jpeg;*.bmp);img = newImage(getClass().getClassLoader().getResourceAsStream(images/红花.jpg);imgWidth = (int) img.getWidth();imgHeight = (int) img.getHeight();/波纹效果计算需要遍历图片每个像素,图片尺寸过大会导致运行速度极慢,故 按比例缩小if (imgWidth MAX_WIDTH | imgHeight MAX_HEIGHT) double sx = MAX_WIDTH / imgWidth;double sy = MAX_HEIGHT / imgHeight;scaleRate = sx sy ? sy : sx;img = scaleImg(img, imgWidth, imgHeight, scaleRate);imgWidth = (int) (scaleRate * (double) imgWidth);imgHeight = (int) (scaleRate * (double) imgHeight);maxRainSize = 4;maxRainPower = 60;stoneSize = 5;stonePower = 128; else /雨点和石子大小根据图片尺寸的大小稍作调整maxRainSize = 3;maxRainPower = 50;stoneSize = 4;stonePower = 108; imgRipper = new WritableImage(imgWidth, imgHeight); arrWaveCurrent = new intimgWidth * imgHeight; arrWaveNext = new intimgWidth * imgHeight;imgView = new ImageView(); imgView.setOnMousePressed(new EventHandler() Overridepublic void handle(Event event) MouseEvent e = (MouseEvent) event;dropStone(int) e.getX(), (int) e.getY(), stoneSize, stonePower); );timer = new AnimationTimer() Overridepublic void handle(long now) genRipper();imgView.setImage(imgRipper);rainTimer = new AnimationTimer() Overridepublic void handle(long now) rain();imgView.setImage(imgRipper);/* 模拟下雨,随机抛出不同大小和位置的石子*/protected void rain() int x = (int) (Math.random() * imgWidth);int y = (int) (Math.random() * imgHeight);int rainSize = (int) (Math.random() * maxRainSize);int power = (int) (Math.random() * maxRainPower) + maxRainPower; dropStone(x, y, rainSize, power);Overridepublic void start(Stage primaryStage) throws Exception Group root = new Group();VBox vb = new VBox(10); root.getChildren().add(vb);imgView.setImage(img);Scene scene = new Scene(root); primaryStage.setScene(scene);HBox hb = new HBox(10);Button rainCo nt rol = new Button(停止下雨); rainControl.setOnAction(ActionEvent event) - if (开始下雨.equals(rainCo nt rol.ge tTex t() rainTimer.start();rainCon trol.se tTex t(停止下雨); else rainTimer.stop();rainCo nt rol.se tTex t(开始下雨););Button changePic = new Butt on(“ 更换图片); changePic.setOnAction(ActionEvent event) - File f = fc.showOpenDialog(primaryStage); if (null != f) /将默认目录设置为上次访问过的目录fc.setInitialDirectory(f.getParentFile(); /Image imgTmp = null;try img = new Image(new FileInputStream(f);/Desktop.getDesktop().open(f); catch (Exception e) e.printStackTrace();if (img != null) imgWidth = (int) img.getWidth();imgHeight = (int) img.getHeight();if (imgWidth MAX_WIDTH | imgHeight MAX_HEIGHT) double sx = MAX_WIDTH / imgWidth;double sy = MAX_HEIGHT / imgHeight;scaleRate = sx sy ? sy : sx;img = scaleImg(img, imgWidth, imgHeight, scaleRate); imgWidth = (int) (scaleRate * (double) imgWidth); imgHeight = (int) (scaleRate * (double) imgHeight); maxRainSize = 4;maxRainPower = 60; stoneSize = 5;stonePower = 128; else maxRainSize = 3;maxRainPower = 50; stoneSize = 4;stonePower = 108;imgRipper = new WritableImage(imgWidth, imgHeight); arrWaveCurrent = new intimgWidth * imgHeight; arrWaveNext = new intimgWidth * imgHeight; imgView.setFitHeight(imgHeight); imgView.setFitWidth(imgWidth); primaryStage.setWidth(imgWidth); imgView.setImage(img);primaryStage.setHeight(imgHeight + 40););Button exit 二 new Button(退出);exit.setOnAction(ActionEvent event) - primaryStage.close(););hb.getChildren().addAll(rainControl, changePic, exit); vb.getChildren().addAll(imgView, hb); primaryStage.setWidth(imgWidth); hb.setAlignment(Pos.CENTER); scene.setFill(Color.BLUEVIOLET); primaryStage.initStyle(StageStyle.TRANSPARENT); timer.start();rainTimer.start();primaryStage.show();/*水波算法,原作者Imagic*/public void genRipper() PixelReader readImg = img.getPixelReader();PixelWriter writeRipper = imgRipper.getPixelWriter(); int index = imgWidth;int indexPreX = index - 1;int indexNextX = index + 1;int indexPreY = index - imgWidth;int indexNextY = index + imgWidth;for (int y = 1; y imgHeight - 1; y+) for (int x = 1; x 1) - arrWaveNextindex; /波能衰减 1/32arrWaveNextindex -= arrWaveNextindex 5; /计算出偏移象素和原始象素的内存地址偏移量 : int xoffset = x2 - x1;int yoffset = x4 - x3;int offset = imgWidth * yoffset + xoffset;int posY = index / imgWidth;int posX = index - posY * imgWidth;int newY = (index + offset) / imgWidth;int newX = (index + offset) - newY * imgWidth;/ 判断坐标是否在窗口范围内if (index + offset 0 & index + offset imgWidth * imgHeight) writeRipper.setColor(posX, posY, readImg.getColor(newX, newY); else writeRipper.setColor(posX, posY, readImg.getColor(posX, posY);/ 交换波能数据缓冲区int temp = arrWaveCurrent;arrWaveCurrent = arrWaveNext;arrWaveNext = temp;/* 模拟向水中投石子* param x:石子位置X坐标* param y:石子位置y坐标* param sto neSize:石子半径* param power:波能大小*/private void dropStone(int x, int y, int stoneSize, int power) int minPosX = x - stoneSize, maxPosX = x + stoneSize;int minPosY = y - stoneSize, maxPosY = y + stoneSize;minPosX = minPosX 0 ? 0 : minPosX;minPosY = minPosY imgWidth ? imgWidth : maxPosX;maxPosY = maxPosY imgHeight ? imgHeight : maxPosY;int value = stoneSize * stoneSize;for (int posx = minPosX; posx maxPosX; posx+) for (int posy = minPosY; posy maxPosY; posy+) if (posx - x) * (posx - x) + (posy - y) * (posy - y) value) arrWaveCurrentposy * imgWidth + posx = -power;/* 按比例缩小图片引,*缩小图片算法:xO = x / sx, y0 = y / sy。xO,yO分别为原图水平和垂直索* sx,sy分别为水平和垂直缩小比例* param src:原始图片* param imgW:原始图片宽度* param imgH:原始图片长度* param ra te:缩小后的图片不原图片尺寸的比例* return 缩小后的图片*/ private Image scaleImg(Image src, int imgW, int imgH, double rate) int width = (int) (double) imgW * rate);int height = (int) (double) imgH * rate);WritableImage imgScaled = new WritableImage(width, height);PixelReader readSrc = src.getPixelReader();PixelWriter writeDest = imgScaled.getPixelWriter();for (int x = 0; x width; x+) for (int y = 0; y height; y+) writeDest.setColor(x, y,readSrc.getColor(int) (x / rate), (int) (y / rate);return imgScaled;public static void main(String args) launch(args); 里面用到了行序优先一维数组存储二维数组时两个数组索引之间的算术关系公 式。设一维数组索引为index,二维数组行索引为x,列索引为y,均从0开始,每行 存储元素个数为width,则:y = int (index / width),int 为取整函数,如 int (1.1)和 int (1.9)都等于 1 x= index - y * widthindex = width * y + x截图:号上卜口
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!