A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 猫腻 高级黑马   /  2013-3-8 19:50  /  2847 人查看  /  9 人回复  /   3 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 猫腻 于 2013-3-13 12:09 编辑

效果图


示例代码
  1. import java.awt.Graphics;
  2. import java.awt.Image;
  3. import java.awt.event.MouseEvent;
  4. import java.awt.event.MouseMotionListener;
  5. import java.awt.image.MemoryImageSource;
  6. import java.awt.image.PixelGrabber;
  7. import java.io.IOException;
  8. import java.util.Random;


  9. import javax.imageio.ImageIO;
  10. import javax.swing.JFrame;
  11. import javax.swing.JPanel;
  12. import javax.swing.SwingUtilities;


  13. public class WateWave extends JFrame implements Runnable, MouseMotionListener {


  14. boolean m_isRunning = false;


  15. int m_width;
  16. int m_height;
  17. int length;


  18. int[] arrWaveCurrent;// 当前波形
  19. int[] arrWaveNext;// 下一帧的波形


  20. int[] arrClrInfo;// 图片原始颜色信息
  21. int[] arrClrBuff;// 图片新的颜色信息


  22. private Thread runner;
  23. private Random random;
  24. private Image offImage;
  25. private MemoryImageSource source;
  26. private JPanel panel = null;


  27. public WateWave() {
  28. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  29. this.setSize(762, 502);
  30. this.setLocationRelativeTo(null);
  31. addMouseMotionListener(this);
  32. random = new Random();
  33. try {
  34. offImage = ImageIO.read(getClass().getResource("backgroud.png"));// 你自己的图片目录
  35. } catch (IOException e1) {
  36. }


  37. m_width = offImage.getWidth(this);
  38. m_height = offImage.getHeight(this);
  39. length = m_width * m_height;


  40. arrWaveCurrent = new int[length];
  41. arrWaveNext = new int[length];
  42. arrClrInfo = new int[length];
  43. arrClrBuff = new int[length];


  44. PixelGrabber pg = new PixelGrabber(offImage, 0, 0, m_width, m_height,
  45. arrClrInfo, 0, m_width);
  46. try {
  47. pg.grabPixels();
  48. } catch (InterruptedException e) {
  49. }


  50. source = new MemoryImageSource(m_width, m_height, arrClrBuff, 0,
  51. m_width);
  52. source.setAnimated(true);
  53. offImage.getGraphics();
  54. offImage = createImage(source);
  55. panel = new JPanel() {
  56. @Override
  57. protected void paintComponent(Graphics g) {
  58. super.paintComponent(g);
  59. g.drawImage(offImage, 0, 0, this);
  60. }
  61. };
  62. this.setContentPane(panel);
  63. this.setVisible(true);
  64. start();
  65. }


  66. public void start() {
  67. m_isRunning = true;
  68. runner = new Thread(this);
  69. runner.start();
  70. }


  71. public void stop() {
  72. m_isRunning = false;
  73. }


  74. public void destroy() {
  75. stop();
  76. runner.interrupt();
  77. }


  78. public void run() {
  79. while (m_isRunning) {
  80. source.newPixels();
  81. // dot();
  82. rippleRender();


  83. try {
  84. Thread.sleep(30);
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. }


  90. void dot() {
  91. int x = 10 + random.nextInt() % (m_width - 20);
  92. int y = 10 + random.nextInt() % (m_height - 20);
  93. dropStone(x, y, 3, 128);
  94. }


  95. /**
  96. * * 某点下一时刻的波幅算法为:上下左右四点的波幅和的一半减去当前波幅, 即 X0' =(X1 + X2 + y1 + X4)/ 2 - X0
  97. *
  98. * <pre>
  99. * +----x3----+
  100. * + | +
  101. * x1---x0----x2
  102. * + | +
  103. * +----x4----+
  104. *
  105. * <pre>
  106. */


  107. void rippleRender() {


  108. int index = m_width;
  109. int indexPreX = index - 1;
  110. int indexNextX = index + 1;
  111. int indexPreY = index - m_width;
  112. int indexNextY = index + m_width;


  113. for (int y = 1; y < m_height - 1; y++) {
  114. for (int x = 1; x < m_width - 1; x++, index++) {
  115. int x1 = arrWaveCurrent[indexPreX++];
  116. int x2 = arrWaveCurrent[indexNextX++];
  117. int x3 = arrWaveCurrent[indexPreY++];
  118. int x4 = arrWaveCurrent[indexNextY++];
  119. // 波能扩散:上下左右四点的波幅和的一半减去当前波幅
  120. // X0' =(X1 + X2 + X3 + X4)/ 2 - X0
  121. arrWaveNext[index] = ((x1 + x2 + x3 + x4) >> 1)- arrWaveNext[index];
  122. // 波能衰减 1/32
  123. arrWaveNext[index] -= arrWaveNext[index] >> 5;
  124. // 计算出偏移象素和原始象素的内存地址偏移量 :
  125. int xoffset = x1 - x2;
  126. int yoffset = x3 - x4;
  127. int offset = m_width * yoffset + xoffset;
  128. // 判断坐标是否在窗口范围内
  129. if (index + offset > 0 && index + offset < length) {
  130. arrClrBuff[index] = arrClrInfo[index + offset];
  131. } else {
  132. arrClrBuff[index] = arrClrInfo[index];
  133. }
  134. }
  135. }
  136. // 交换波能数据缓冲区
  137. int[] temp = arrWaveCurrent;
  138. arrWaveCurrent = arrWaveNext;
  139. arrWaveNext = temp;
  140. }


  141. /**
  142. * 扔石头
  143. *
  144. * @param x
  145. * @param y
  146. * @param r
  147. * 半径
  148. * @param h
  149. * 波源能量
  150. */
  151. void dropStone(int x, int y, int r, int h) {
  152. // 判断坐标是否在屏幕范围内
  153. if ((x + r) > m_width || (y + r) > m_height || (x - r) < 0
  154. || (y - r) < 0) {
  155. return;
  156. }


  157. int value = r * r;


  158. for (int posx = x - r; posx < x + r; posx++) {
  159. for (int posy = y - r; posy < y + r; posy++) {
  160. if ((posx - x) * (posx - x) + (posy - y) * (posy - y) < value) {
  161. arrWaveCurrent[m_width * posy + posx] = -h;
  162. }
  163. }
  164. }
  165. }


  166. @Override
  167. public void mouseDragged(MouseEvent e) {


  168. }


  169. @Override
  170. public void mouseMoved(MouseEvent e) {
  171. int x = (int) (e.getX());
  172. int y = (int) (e.getY());
  173. dropStone(x, y, 4, 128);
  174. }


  175. public static void main(String[] args) {
  176. SwingUtilities.invokeLater(new Runnable() {
  177. @Override
  178. public void run() {
  179. new WateWave();
  180. }
  181. });
  182. }
  183. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 碉堡了

查看全部评分

9 个回复

倒序浏览
我试了,编译通过了,但是运行就报错了
回复 使用道具 举报
给力啊,支持了
回复 使用道具 举报
黄玉昆 发表于 2013-3-8 20:55
我试了,编译通过了,但是运行就报错了

offImage = ImageIO.read(getClass().getResource("backgroud.jpg"));// 你自己的图片目录
需要自己放一个图片到bin目录下的
回复 使用道具 举报
李培根 发表于 2013-3-8 22:15
offImage = ImageIO.read(getClass().getResource("backgroud.jpg"));// 你自己的图片目录
需要自己放一 ...

还是不行啊,不知道为什么

回复 使用道具 举报
黄玉昆 发表于 2013-3-8 22:52
还是不行啊,不知道为什么

不会啊,我的运行没问题,图片最好控制在100k以内,试了下500k的不行。
回复 使用道具 举报
效果强悍
回复 使用道具 举报
猫腻 高级黑马 2013-3-13 11:04:51
8#
本帖最后由 猫腻 于 2013-3-13 12:07 编辑

运行的时候,目录根据本机的设置好了,不然运行报错,后果自负。
切记修改这段代码,如果是尝试自己玩的话,不然运行会报错的,没做过多的处理,莫怪啊。{:soso_e106:}
  1. try {
  2. offImage = ImageIO.read(getClass().getResource("backgroud.png"));// 你自己的图片目录
  3. } catch (IOException e1) {
  4. }

复制代码
回复 使用道具 举报
呵呵,感觉不错。强顶!支持
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马