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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© jauliun 中级黑马   /  2015-12-30 23:21  /  641 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.Vector;

import javax.swing.JFrame;

/**
* 打字游戏
* @author
*
*/
public class WordGame extends Window implements KeyListener, Runnable {
        //保存屏幕的宽和高
        int width, height;
        //内存位图对象
        BufferedImage buf;
        //创建图形对象用来绘制窗体
        Graphics gc;
        //游戏是否继续
        boolean play = true;
        //创建一个集合来保存当前屏幕上的字母
        Vector<WordFactory> keys = new  Vector<WordFactory>();
        //线程中循环执行的次数
        int count;
        //当前窗体的字体
        Font fontSize = new Font("楷体", 0, 60);       
        //程序的入口点
        public static void main(String[] args){
                //创建一个窗体对象
                JFrame help = new JFrame("打字练习");
                //显示窗体
                help.setVisible(true);
                //设置窗体的关闭为默认关闭
                help.setDefaultCloseOperation(3);
                //给当前窗体添加一个键盘按键监听器
                help.addKeyListener(new WordGame(help));
        }
        /*
         * 当前类的Constructor中初始化窗体对象       
         */
   private WordGame(Frame f) {
                super(f);
                //此对象封装了当前窗体的宽度和高度
                Dimension s = getToolkit().getScreenSize();
                width = (int) s.getWidth();
                height = (int) s.getHeight();
                //设置当前窗体的大小
                this.setBounds(0, 0, width, height);
                //创建一个和当前窗体一样大小的位图
                this.buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                //通过位图创建一个图形
                gc = buf.getGraphics();
                //显示窗体
                this.setVisible(true);
                //当前始终保持在最前端
                this.setAlwaysOnTop(true);
                //开启线程用来创建字母
                new Thread(this).start();
        }
       
        public void keyTyped(KeyEvent e) {
        }
       
    /*
     * 键盘按下事件(线程同步)
     */
        public synchronized void keyPressed(KeyEvent e) {
                //判断用户是否按下了Esc键
                if (e.getKeyCode() == 27) {
                        //游戏结束
                        play = false;
                        //释放当前窗口
                        this.dispose();
                        //系统退出
                        System.exit(0);
                }
                //获取用户按下的键
                char inputWord = e.getKeyChar();
                //如果键的范围在'a'-'z'之间,就消除屏幕上的字母
                if (inputWord >= 'a' && inputWord <= 'z') {
                        String l = "" + inputWord;
                        //遍历集合
                        for (int i = 0; i < keys.size(); i++) {
                                //判断用户输入的字母在集合中是否存在
                                if (l.equals(((WordFactory) keys.elementAt(i)).word)) {
                                        //从集合中删除用户输入的字母
                                        keys.removeElementAt(i);
                                       
                                        return;
                                }
                        }
                       
                }
        }

        public void keyReleased(KeyEvent e) {
        }
    /**
     * 窗体的刷新方法,用来控制字母的下落
     */
        @Override
        public void update(Graphics g) {
        //重新绘制屏幕的背景
                gc.setColor(Color.BLACK);
                //重绘大小
                gc.fillRect(0, 0, width, height);
                //重绘字体               
                gc.setFont(fontSize);
                //定义一个字母对象
                WordFactory o;
                //遍历当前集合中的所有对象
                for (int i = 0; i < keys.size(); i++) {
                        //取出对象
                        o =  keys.elementAt(i);
                        //并判断当前字母的纵坐标是否小于当前窗体的高度
                        if (o.y > height - 10) {
                                //从集合中删除该字母
                                keys.removeElementAt(i);
                        }
                        //重绘该字母的颜色
                        gc.setColor(o.color);
                        //重绘该字母的值和横坐标以及纵坐标加上6个像素
                        gc.drawString(o.word, o.x, o.y += 6);                       
                }
                //重新以位图渲染当前图形
                g.drawImage(buf, 0, 0, null);
        }
        //重写Runnable接口的run方法,用来添加新的字母
        public void run() {
                while (play) {
                        try {                               
                                count++;
                                //每800毫秒添加一个新的字母
                                if (count % 10 == 0) {
                                        //向当前集合中添加一个新的字母
                                        keys.add(WordFactory.getinstance(width));
                                }
                                //当前运行的线程睡眠80毫秒
                                Thread.sleep(80);
                                //重新绘制当前组件
                                repaint();
                        } catch (InterruptedException ex) {
                                ex.printStackTrace();
                        }
                }
        }
       
}
/**
* 字母工厂
* @author 林志霄
*
*/
class WordFactory {
        //字母出现的横坐标和纵坐标
        int x, y;
        //字母的随机颜色
        Color color;
        //字母的值
        String word;
    //创建一个随机数对象
        static java.util.Random r = new java.util.Random();
    //根据屏幕的宽度创建字母新的字母
        public static WordFactory getinstance(int maxX) {
                //创建一个新的字母
                WordFactory a = new WordFactory();
                //一个有26个字母,生成1-26之间的
                int b = r.nextInt(26);
                //将刚才生成的整数加上'a'的ASCII码生成一个随机的字母,范围在'a'-'z'之间
                a.word = "" + (char) (b + 'a');
                //随机生成一个字母的位置,当前屏幕宽度减掉30个像素
                a.x = r.nextInt(maxX-30);
                //使用随机数,生成随机的颜色分量,创建一个颜色对象
                a.color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
                return a;
        }
       
}

1 个回复

倒序浏览
看不懂...
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马