黑马程序员技术交流社区

标题: Java 实现黑客帝国中的数字雨 [打印本页]

作者: jacobsnow    时间: 2016-4-21 21:59
标题: Java 实现黑客帝国中的数字雨
Java 实现黑客帝国中的数字雨




      自从看过黑客帝国的后,一直对里面的一个镜头念念不忘。那就是镜头里反复出现的数字雨特效。

是这样的



我一直在想这是怎么做了的。自从学了Java后,我一直在琢磨,能不能有Java来实现。作为到今天为止只学了8天菜鸟,我自然是写不出来的。寻寻觅觅,终于在网上找到了大神写的(原帖:
http://www.cnblogs.com/x110/p/4239585.html
)。代码如下:(命名为
Rain.java,点击运行即可

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.MemoryImageSource;
import java.util.Random;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Rain extends JDialog implements ActionListener {

    private Random random = new Random();
    private Dimension screenSize;
    private JPanel graphicsPanel;
    //行高,列宽
    private final static int gap = 20;
    //存放雨点顶部的位置信息(marginTop)
    private int[] posArr;
    //行数
    private int lines;
    //列数
    private int columns;

    public Rain() {
        initComponents();
    }

    private void initComponents() {
        setLayout(new BorderLayout());
        graphicsPanel = new GraphicsPanel();
        add(graphicsPanel, BorderLayout.CENTER);
        //设置光标不可见
        Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
        Image image = defaultToolkit.createImage(new MemoryImageSource(0, 0, null, 0, 0));
        Cursor invisibleCursor = defaultToolkit.createCustomCursor(image, new Point(0, 0), "cursor");
        setCursor(invisibleCursor);
        //ESC键退出
        KeyPressListener keyPressListener = new KeyPressListener();
        this.addKeyListener(keyPressListener);
        //this.setAlwaysOnTop(true);
        //去标题栏
        this.setUndecorated(true);
        //全屏
        this.getGraphicsConfiguration().getDevice().setFullScreenWindow(this);
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setVisible(true);

        screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        lines = screenSize.height / gap;
        columns = screenSize.width / gap;

        posArr = new int[columns + 1];
        random = new Random();
        for (int i = 0; i < posArr.length; i++) {
            posArr = random.nextInt(lines);
        }

        //每秒10帧
        new Timer(100, this).start();
    }

    /**
     * @return 随机字符
     */
    private char getChr() {
        return (char) (random.nextInt(94) + 33);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        graphicsPanel.repaint();
    }

    private class GraphicsPanel extends JPanel {
        @Override
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setFont(getFont().deriveFont(Font.BOLD));
            g2d.setColor(Color.BLACK);
            g2d.fillRect(0, 0, screenSize.width, screenSize.height);
            //当前列
            int currentColumn = 0;
            for (int x = 0; x < screenSize.width; x += gap) {
                int endPos = posArr[currentColumn];
                g2d.setColor(Color.CYAN);
                g2d.drawString(String.valueOf(getChr()), x, endPos * gap);
                int cg = 0;
                for (int j = endPos - 15; j < endPos; j++) {
                    //颜色渐变
                    cg += 20;
                    if (cg > 255) {
                        cg = 255;
                    }
                    g2d.setColor(new Color(0, cg, 0));
                    g2d.drawString(String.valueOf(getChr()), x, j * gap);
                }
                //每放完一帧,当前列上雨点的位置随机下移1~5行
                posArr[currentColumn] += random.nextInt(5);
                //当雨点位置超过屏幕高度时,重新产生一个随机位置
                if (posArr[currentColumn] * gap > getHeight()) {
                    posArr[currentColumn] = random.nextInt(lines);
                }
                currentColumn++;
            }
        }
    }

    private class KeyPressListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                System.exit(0);
            }
        }
    }

    public static void main(String[] args) {
        new Rain();
    }
}


(有好多还是看不懂。看来成为大神的路,还有很远。

最后一句,愿大家忠于理想,面对现实!好好努力……

就这样吧,

鞠躬,下台……)







黑客帝国.png (45.16 KB, 下载次数: 43)

黑客帝国.png

作者: kingmask    时间: 2016-4-21 23:44
好牛逼,顶起来
作者: hmjavaqinchi    时间: 2016-4-22 01:05
haoniubidedongxia
作者: 长衫造纸农_    时间: 2016-4-22 08:28
好牛逼的东西阿。
作者: 编号89757    时间: 2016-4-22 12:27
第63行   posArr少了个[i]   是posArr[i],就可以运行了
作者: Q灬先生    时间: 2016-4-22 13:12
好nb可是现在看不懂!
作者: jacobsnow    时间: 2016-4-22 23:35
  1. import java.awt.*;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import java.awt.event.KeyAdapter;
  5. import java.awt.event.KeyEvent;
  6. import java.awt.image.MemoryImageSource;
  7. import java.util.Random;
  8. import javax.swing.JDialog;
  9. import javax.swing.JPanel;
  10. import javax.swing.Timer;

  11. public class Rain extends JDialog implements ActionListener {

  12.     private Random random = new Random();
  13.     private Dimension screenSize;
  14.     private JPanel graphicsPanel;
  15.     //行高,列宽
  16.     private final static int gap = 20;
  17.     //存放雨点顶部的位置信息(marginTop)
  18.     private int[] posArr;
  19.     //行数
  20.     private int lines;
  21.     //列数
  22.     private int columns;

  23.     public Rain() {
  24.         initComponents();
  25.     }

  26.     private void initComponents() {
  27.         setLayout(new BorderLayout());
  28.         graphicsPanel = new GraphicsPanel();
  29.         add(graphicsPanel, BorderLayout.CENTER);
  30.         //设置光标不可见
  31.         Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
  32.         Image image = defaultToolkit.createImage(new MemoryImageSource(0, 0, null, 0, 0));
  33.         Cursor invisibleCursor = defaultToolkit.createCustomCursor(image, new Point(0, 0), "cursor");
  34.         setCursor(invisibleCursor);
  35.         //ESC键退出
  36.         KeyPressListener keyPressListener = new KeyPressListener();
  37.         this.addKeyListener(keyPressListener);
  38.         //this.setAlwaysOnTop(true);
  39.         //去标题栏
  40.         this.setUndecorated(true);
  41.         //全屏
  42.         this.getGraphicsConfiguration().getDevice().setFullScreenWindow(this);
  43.         this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
  44.         setVisible(true);

  45.         screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  46.         lines = screenSize.height / gap;
  47.         columns = screenSize.width / gap;

  48.         posArr = new int[columns + 1];
  49.         random = new Random();
  50.         for (int i = 0; i < posArr.length; i++) {
  51.             posArr[i] = random.nextInt(lines);
  52.         }

  53.         //每秒100帧
  54.         new Timer(100, this).start();
  55.     }

  56.     /**
  57.      * @return 随机字符
  58.      */
  59.     private char getChr() {
  60.         return (char) (random.nextInt(94) + 33);
  61.     }

  62.     @Override
  63.     public void actionPerformed(ActionEvent e) {
  64.         graphicsPanel.repaint();
  65.     }

  66.     private class GraphicsPanel extends JPanel {
  67.         @Override
  68.         public void paint(Graphics g) {
  69.             Graphics2D g2d = (Graphics2D) g;
  70.             g2d.setFont(getFont().deriveFont(Font.BOLD));
  71.             g2d.setColor(Color.BLACK);
  72.             g2d.fillRect(0, 0, screenSize.width, screenSize.height);
  73.             //当前列
  74.             int currentColumn = 0;
  75.             for (int x = 0; x < screenSize.width; x += gap) {
  76.                 int endPos = posArr[currentColumn];
  77.                 g2d.setColor(Color.CYAN);
  78.                 g2d.drawString(String.valueOf(getChr()), x, endPos * gap);
  79.                 int cg = 0;
  80.                 for (int j = endPos - 15; j < endPos; j++) {
  81.                     //颜色渐变
  82.                     cg += 20;
  83.                     if (cg > 255) {
  84.                         cg = 255;
  85.                     }
  86.                     g2d.setColor(new Color(0, cg, 0));
  87.                     g2d.drawString(String.valueOf(getChr()), x, j * gap);
  88.                 }
  89.                 //每放完一帧,当前列上雨点的位置随机下移1~5行
  90.                 posArr[currentColumn] += random.nextInt(5);
  91.                 //当雨点位置超过屏幕高度时,重新产生一个随机位置
  92.                 if (posArr[currentColumn] * gap > getHeight()) {
  93.                     posArr[currentColumn] = random.nextInt(lines);
  94.                 }
  95.                 currentColumn++;
  96.             }
  97.         }
  98.     }

  99.     private class KeyPressListener extends KeyAdapter {
  100.         @Override
  101.         public void keyPressed(KeyEvent e) {
  102.             if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
  103.                 System.exit(0);
  104.             }
  105.         }
  106.     }

  107.     public static void main(String[] args) {
  108.         new Rain();
  109.     }
  110. }
复制代码

作者: Wanibal    时间: 2016-4-24 10:38
友情回复,实力顶帖
作者: wkong    时间: 2016-4-24 11:20
碉堡了。。
作者: lalala1a    时间: 2016-4-24 17:48
好高端,看不懂
作者: monZhang    时间: 2016-4-24 18:20
好像没什么卵用




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2