Java实现打字游戏
樱薾 人气:0本文着重为大家仔细讲解了Java实现打字游戏,文中代码实例讲解的非常细致,希望能够帮助到您,欢迎大家阅读和收藏
新建一个项目,然后在src里面建一个MyGame.java文件,
把代码粘到刚才新建的MyGame.java,
然后把两张图放到src下,就行了
一、代码
import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.*; public class MyGame { static UIFrame uiFrame;//主界面 static playGame playgame;//正式游戏开始界面 public static void main(String[] args) { uiFrame = new UIFrame("打字游戏"); playgame = new playGame(); } /*游戏主界面*/ static class UIFrame extends JFrame { int width = 500; int height = 700; Font X = new Font("方正舒体", Font.PLAIN, 30); JLabel playjb = new JLabel("开始游戏"); JLabel rulejb = new JLabel("规则"); JLabel exitjb = new JLabel("退出游戏"); JFrame f1 = new JFrame("规则"); /*主界面设置*/ public UIFrame(String text) { super(text); this.setLayout(null); this.setSize(width, height); this.setLocationRelativeTo(null); this.setResizable(false); this.getLayeredPane().setLayout(null); JPanel imgPanel = (JPanel) this.getContentPane(); imgPanel.setOpaque(false); imgPanel.setBounds(0, 0, width, height); imgPanel.setLayout(null); ImageIcon icon = new ImageIcon("src/bg.jpg"); JLabel label = new JLabel(icon); label.setBounds(0, 0, this.getWidth(), this.getHeight()); icon.setImage(icon.getImage().getScaledInstance(label.getWidth(), label.getHeight(), Image.SCALE_DEFAULT)); this.getLayeredPane().add(label, Integer.valueOf(Integer.MIN_VALUE)); Title title = new Title();//新建一个标题对象 this.add(title);//往窗口中加入标题面板 Thread t = new Thread(title);//将标题面板加入一个线程 t.start();//启动线程,实现标题面板下落 buildButton(); add_JB_Listener(); setruleJF(); this.setVisible(true); } /*设置按钮规格*/ public void buildButton() { playjb.setForeground(Color.red); rulejb.setForeground(Color.red); exitjb.setForeground(Color.red); playjb.setFont(X); rulejb.setFont(X); exitjb.setFont(X); playjb.setBounds(width / 3, height * 2 / 6, width / 3, 50); rulejb.setBounds(width / 3, height * 3 / 6, width / 3, 50); exitjb.setBounds(width / 3, height * 4 / 6, width / 3, 50); playjb.setHorizontalAlignment(JLabel.CENTER); rulejb.setHorizontalAlignment(JLabel.CENTER); exitjb.setHorizontalAlignment(JLabel.CENTER); this.add(playjb); this.add(rulejb); this.add(exitjb); } /*设置规则窗口*/ public void setruleJF(){ JLabel text1 = new JLabel("<html><body>"+"基本规则:点击开始游戏后可以选择生命值,确认后游戏正式开始游戏开始后会自动下落四个三位"+"<br>"+" "+"数,在输入框中输入其中之一会自动消除这个三位数," + "得分增加,并产生新数字,当数字"+"<br>"+" "+"掉落到屏幕底部时生命值减一,生命值为0游戏结束。(PS:在输入框中输入空格游戏暂"+"<br>"+" "+"停,输入任意数字则继续)" +"<br>"+"<br>"+ "难度介绍:游戏难度会随着得分的增加而自动增加,也可使用滑块自己调整数字下落难度等级。"+"<br>"+"<br>"+ "闪烁模式:游戏开始后可以点击开始闪烁按钮来开始闪烁模式,此时数字会隔一段时间消失再出现。"+"<br>"+"<br>"+"好好享受吧!"+"</body></html>"); text1.setVerticalAlignment(JLabel.NORTH);//使其文本位于JLabel顶部 text1.setFont(new Font("宋体", Font.PLAIN, 20)); f1.add(text1);//f1为显示规则的窗口 f1.setResizable(false); f1.setSize(2 * width - 100, height / 2); f1.setLocationRelativeTo(null); } /*按钮添加监听器*/ public void add_JB_Listener() { playjb.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { setVisible(false); Chooselife chooselife = new Chooselife(); } @Override public void mouseEntered(MouseEvent e) { playjb.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.LIGHT_GRAY)); } @Override public void mouseExited(MouseEvent e) { playjb.setBorder(null); } }); rulejb.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { f1.setVisible(true); } public void mouseEntered(MouseEvent e) { rulejb.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.LIGHT_GRAY)); } @Override public void mouseExited(MouseEvent e) { rulejb.setBorder(null); } }); exitjb.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { System.exit(0); } public void mouseEntered(MouseEvent e) { exitjb.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.LIGHT_GRAY)); } @Override public void mouseExited(MouseEvent e) { exitjb.setBorder(null); } }); } } /*选择生命界面*/ static class Chooselife extends JFrame { static Boolean gamePlayflag = false;//第一次开始游戏则为false,否则为true, Chooselife() { setTitle("选择生命值"); setAlwaysOnTop(true);//置于顶部 setLayout(null); setSize(300, 100); setLocationRelativeTo(null); setResizable(false); setBotton();//设按钮 setVisible(true); } /*设置按钮*/ void setBotton() { ButtonGroup lives = new ButtonGroup();//新建按钮组实现互斥 JRadioButton one = new JRadioButton("1", true);//按钮默认选择1 JRadioButton two = new JRadioButton("2", false); JRadioButton three = new JRadioButton("3", false); lives.add(one);//按钮添加进按钮组 lives.add(two); lives.add(three); JPanel chooselifejp = new JPanel(); chooselifejp.setBounds(0, 0, getWidth(), getHeight() - 60); chooselifejp.add(one);//按钮添加进JPanel chooselifejp.add(two); chooselifejp.add(three); add(chooselifejp);//JPanel添加到JFrame JButton play = new JButton("开始"); play.setBounds(getWidth() / 3 + 10, chooselifejp.getHeight(), 70, 25); add(play); /*给开始按钮添加监听器,设置选中的生命值*/ play.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (one.isSelected()) { playgame.life = 1;//开始游戏后将生命值设成1 } else if (two.isSelected()) { playgame.life = 2; } else { playgame.life = 3; } /*后面实现重玩再讲*/ playgame.templife =playgame.life;//为实现重玩功能而新建的临时变量templife,用来保存当前的生命值。 if (!gamePlayflag) {//第一次游戏 playgame.begin();//调用begin函数来新设置一些变量和线程、控件规格 gamePlayflag = true; } else { playgame.injp.replay_func();//选择完生命值之后,使用第一次游戏使用的那些变量、线程、控件, // 然后用重玩的函数功能重置一些变量即可实现开始新一轮游戏的效果 playgame.PlayJF.setVisible(true);//显示正式游戏界面 } dispose(); } }); } } static class playGame { static int life=1; static int templife=1; static int width = 500; static int height = 700; static int N = 4;//数字列数 static int x[] = new int[N]; static int y[] = new int[N]; static String[] num = new String[N]; JFrame PlayJF = new JFrame("打字游戏"); Image lifeicon = Toolkit.getDefaultToolkit().getImage("src/life.jpg"); static int difficult_level = 1;//下落难度 static int mindifficult_level = 1;//最小下落难度 static int shanshuo_level = 1;//闪烁难度 Boolean terminateflag = false; Boolean beginflag = false; Boolean shanshuoflag = false; Boolean zantingshanshuoflag = false;//闪烁且暂停 Boolean Gameoverflag = false; JTextField in = new JTextField(3); JLabel showtext = new JLabel(); int score; int count = 3; int allcount; int correctcount; int lianjicount; Boolean lianjiflag = false; MyPanel mp; messageJP injp; /*第一次开始游戏调用*/ public void begin() { getrandnum(); PlayJF.setSize(width, height); mp = new MyPanel(); injp = new messageJP(); PlayJF.setResizable(false); PlayJF.setLocationRelativeTo(null); PlayJF.getLayeredPane().setLayout(null); JPanel imgPanel = (JPanel) PlayJF.getContentPane(); imgPanel.setOpaque(false); imgPanel.setBounds(0, 0, width, height); imgPanel.setLayout(null); ImageIcon icon = new ImageIcon("src/bg.jpg"); JLabel label = new JLabel(icon); label.setBounds(0, 0, PlayJF.getWidth(), PlayJF.getHeight()); icon.setImage(icon.getImage().getScaledInstance(label.getWidth(), label.getHeight(), Image.SCALE_DEFAULT)); PlayJF.getLayeredPane().add(label, Integer.valueOf(Integer.MIN_VALUE)); PlayJF.getContentPane().add(mp); PlayJF.getContentPane().add(injp, Integer.valueOf(Integer.MAX_VALUE)); Thread t = new Thread(mp); t.start(); PlayJF.setVisible(true); in.requestFocus(); } /*产生四个随机三位数*/ public static void getrandnum() { int i, j; for (i = 0; i < N; i++) {//生成数字的字符形式,设置初始横纵坐标 num[i] = Integer.toString((int) (Math.random() * 900 + 100));//生成100到999之间随机数 x[i] = (int) (0.1 * width + i * 0.20 * width); y[i] = 50; } for (i = 0; i < N; i++) { for (j = i + 1; j < N; j++) { while (num[j].charAt(0) == num[i].charAt(0)) {//若数字与前面的数字首位相同,则重新生成该数字 num[j] = Integer.toString((int) (Math.random() * 900 + 100)); } } } } /*数字下落面板*/ class MyPanel extends JPanel implements Runnable { int width = PlayJF.getWidth(); int height = 500; long time;//记录时间,用于闪烁功能的实现 public MyPanel() { setOpaque(false); setBounds(0, 0, width, height); setBackground(Color.BLACK); } public void paint(Graphics g) { super.paint(g); if (Gameoverflag) {//游戏结束 g.setColor(Color.RED); g.setFont(new Font("宋体", Font.BOLD, 35)); g.drawString("游戏结束!", width / 3, height / 2); g.drawString("您的分数为"+score,width / 3-15,height/2+35); gameoverwork(); } else { if (!beginflag) {//倒计时 g.setColor(Color.RED); g.setFont(new Font("宋体", Font.PLAIN, 50)); if (count == 0) { g.drawString("Go!", width / 2, height / 2); in.setEditable(true); } else { in.requestFocus(); g.drawString(String.valueOf(count), width / 2, height / 2); } } else {//数字开始掉落 g.setFont(new Font("宋体", Font.PLAIN, 20)); g.setColor(Color.WHITE); for (int i = 0; i < N; i++) { if (shanshuoflag) {//进入闪烁模式 if (zantingshanshuoflag == false) {//闪烁模式且不在暂停状态 if (time % 3000 < 500 * shanshuo_level == false) {//闪烁:若时间满足条件,则绘出数字,否则不绘出数字 g.drawString(num[i], x[i], y[i]); } } else {//闪烁模式且暂停,直接显示数字 g.drawString(num[i], x[i], y[i]); } } else {//不是闪烁则正常绘出数字 g.drawString(num[i], x[i], y[i]); } } if (terminateflag) {//画出暂停字样 g.setColor(Color.BLUE); g.setFont(new Font("宋体", Font.BOLD, 30)); g.drawString("暂停中...", width / 4, height / 2); g.setFont(new Font("宋体", Font.BOLD, 20)); g.drawString("输入任意数字继续...", width / 4, height / 2 + 30); if (shanshuoflag) { zantingshanshuoflag = true;//如果是暂停而且是闪烁状态, } } else {//不暂停,每次数字纵坐标加一,掉落到底部生命值减一,重置所有数字纵坐标。 for (int i = 0; i < N; i++) { y[i] = y[i] + 1; if (y[i] > getHeight()&&templife>0) { templife--; for(int j=0;j<N;j++){ y[j]=50; } } } if(templife==0){//游戏结束 Gameoverflag=true; } } g.setColor(Color.WHITE); g.setFont(new Font("宋体", Font.PLAIN, 20)); g.drawString("得分:" + score, 2, 20); g.drawString("生命值:", 270, 20); for (int i = 0; i < templife; i++) { g.drawImage(lifeicon, 350 + i * 21, 1, 20, 20, this);//在指定位置根据生命值绘出爱心桃 } } } } /*清空输入框和无法输入*/ public void gameoverwork(){ in.setText(""); in.setEditable(false); } @Override public void run() { long startTime = System.currentTimeMillis();//记录游戏开始时间 while (true) { /*倒计时*/ if (!beginflag) { in.setEditable(false); repaint(); try { Thread.sleep(1000); count--; if (count == -1) { beginflag = true; } } catch (InterruptedException e) { e.printStackTrace(); } } else {//绘出数字 repaint(); try { Thread.sleep(40 - difficult_level * 5); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); time = endTime - startTime;//记录从开始到执行这次重绘函数后总共经历的时间 } } } } /*功能面板类*/ class messageJP extends JPanel { JSlider difficultJS = new JSlider(1, 5, 1);//游戏难度滑块 JLabel difficultJL = new JLabel();//显示“当前游戏难度为多少”的字样 JSlider shanshuo_levelJS = new JSlider(1, 3, 1);//闪烁难度的滑块 JLabel shanshuo_levelJL = new JLabel();//显示“闪烁难度等级”的字样 JLabel termiJL = new JLabel();//显示“输入空格暂停”字样 JButton replay = new JButton("重玩"); JButton gotomain = new JButton("返回主界面"); JButton shanshuoJB = new JButton("开启闪烁"); String input; messageJP() { setLayout(null); setBounds(0, mp.getHeight(), PlayJF.getWidth(), PlayJF.getHeight() - mp.getHeight()); set_difficultJS(); set_replay(); set_gotomain(); set_shanshuoJB(); set_in(); set_termiJL(); set_showtext(); } /*设置输入框的一些功能*/ void set_in() { in.setCaretPosition(in.getText().length()); in.setBounds(width / 4, getHeight() - 70, width / 3, 30); in.setFont(new Font("宋体", Font.PLAIN, 15)); in.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent e) { System.out.println("KeyTyped:"+in.getText()); } public void keyPressed(KeyEvent e) { super.keyPressed(e); System.out.println("KeyPressed:"+in.getText()); if (e.getKeyChar() == KeyEvent.VK_SPACE) {//判断输入是否为空格 if (terminateflag) { terminateflag = false; } else { terminateflag = true; } } } public void keyReleased(KeyEvent e) { System.out.println("KeyReleased:"+in.getText()); String s = in.getText().replaceAll(" ", ""); in.setText(s); if(terminateflag==true&&e.getKeyChar()!=KeyEvent.VK_SPACE){ terminateflag = false; } if (in.getText().length() >= 3) { allcount++; input = in.getText(); in.setText(""); lianjiflag = false; for (int i = 0; i < N; i++) { if (input.equals(num[i])) { y[i] = 50; score += 10 * difficult_level; correctcount++; lianjiflag = true; if (mindifficult_level < 5 && score > 200) { mindifficult_level = score / 100; difficultJS.setMinimum(mindifficult_level);//设置滑块的最小难度 if (difficult_level < mindifficult_level) { difficult_level = mindifficult_level;//如果当前难度比最小难度低,调整最小难度 } difficultJS.setValue(difficult_level); } difficultJL.setText("下落等级:" + difficult_level); num[i] = Integer.toString((int) (Math.random() * 900 + 100)); while (true) { for (int j = 0; j < N; j++) { if (num[i].charAt(0) == num[j].charAt(0) && i != j) { num[i] = Integer.toString((int) (Math.random() * 900 + 100)); j = -1; } } break; } } } if (lianjiflag) { lianjicount++; } else { lianjicount = 0; } } showtext.setText("<html>输入总次数:" + allcount + "<br/>正确次数:" + correctcount + "<br/>当前连击数:" + lianjicount + " <br/></html>"); } }); add(in); } /*输入空格暂停字样*/ void set_termiJL() { termiJL.setText("输入空格暂停"); termiJL.setFont(new Font("宋体", Font.PLAIN, 15)); termiJL.setForeground(Color.RED); termiJL.setBounds(width / 4, getHeight() - 95, width / 3, 30); add(termiJL); } /*难度等级滑块*/ void set_difficultJS() { difficultJS.setBounds(10, getHeight() - 110, 80, 40); difficultJS.setMajorTickSpacing(1); difficultJS.setSnapToTicks(true); difficultJS.setPaintTicks(true); difficultJS.setPaintLabels(true); difficultJS.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { difficult_level = difficultJS.getValue(); difficultJL.setText("下落等级:" + difficult_level); } }); difficultJL.setBounds(10, getHeight() - 85, 100, 50); difficultJL.setFont(new Font("方正姚体", Font.PLAIN, 15)); difficultJL.setText("下落等级:" + difficult_level); add(difficultJL); add(difficultJS, Integer.valueOf(Integer.MIN_VALUE)); } /*重玩按钮的功能*/ void set_replay() { replay.setBounds(width * 3 / 4 + 10, 0, 100, 50); add(replay); replay.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { replay_func(); } }); } /*返回主界面功能*/ void set_gotomain() { gotomain.setBounds(width * 3 / 4 + 10, 55, 100, 50); add(gotomain); gotomain.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { PlayJF.setVisible(false); uiFrame.setVisible(true); } }); } /*闪烁按钮及其功能*/ void set_shanshuoJB() { shanshuoJB.setBounds(width * 3 / 4 + 10, 110, 100, 50); shanshuo_levelJS.setBounds(10, 5, 80, 40); shanshuo_levelJS.setSnapToTicks(true); shanshuo_levelJS.setPaintTicks(true); shanshuo_levelJS.setPaintLabels(true); shanshuo_levelJS.setMajorTickSpacing(1); shanshuo_levelJL.setFont(new Font("方正姚体", Font.PLAIN, 15)); shanshuo_levelJL.setText("闪烁等级:" + shanshuo_level); shanshuo_levelJL.setBounds(10, 30, 80, 70); shanshuo_levelJS.setVisible(false); shanshuo_levelJL.setVisible(false); add(shanshuoJB); add(shanshuo_levelJS); add(shanshuo_levelJL); shanshuoJB.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (shanshuoflag) {//当前模式是闪烁模式 shanshuoflag = false; shanshuo_levelJS.setVisible(false);//隐藏闪烁难度调节滑块 shanshuo_levelJL.setVisible(false); shanshuoJB.setText("开启闪烁"); shanshuo_level = 1; shanshuo_levelJS.setValue(1); } else { shanshuoflag = true; shanshuo_levelJS.setVisible(true); shanshuo_levelJL.setVisible(true); shanshuoJB.setText("关闭闪烁"); } } }); shanshuo_levelJS.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { shanshuo_level = shanshuo_levelJS.getValue(); shanshuo_levelJL.setText("闪烁等级:" + shanshuo_level); } }); } /*显示一些统计信息*/ void set_showtext() { showtext.setFont(new Font("方正姚体", Font.PLAIN, 15)); showtext.setBounds(width / 4, 10, getWidth() / 3, getHeight() / 2); showtext.setText("<html>输入总次数:" + allcount + "<br/>正确次数:" + correctcount + "<br/>当前连击数:" + lianjicount + " <br/></html>"); showtext.setBorder(BorderFactory.createLineBorder(Color.GRAY)); add(showtext); } /*实现重玩功能的函数*/ void replay_func() {//就是重置一些变量 in.setEditable(true); difficult_level = 1; difficultJS.setMinimum(1); difficultJS.setMaximum(5); difficultJS.setValue(1); templife=life; shanshuo_level = 1; shanshuo_levelJS.setValue(1); shanshuo_levelJS.setVisible(false); shanshuo_levelJL.setVisible(false); terminateflag=false; getrandnum(); score = 0; count = 3; lianjicount = 0; allcount = 0; correctcount = 0; in.setText(""); showtext.setText("<html>输入总次数:" + allcount + "<br/>正确次数:" + correctcount + "<br/>当前连击数:" + lianjicount + " <br/></html>"); lianjiflag = false; shanshuoflag = false; shanshuoJB.setText("开启闪烁"); beginflag = false; Gameoverflag = false; in.requestFocus(); } } } } /*在一个面板上实现标题自动下落*/ class Title extends JPanel implements Runnable { int width = 500; int height = 250; int N = 4; int[] x = new int[N];//存储标题中的每个字的横坐标 int[] y = new int[N];//存储标题中的每个字的纵坐标 String[] strs = new String[]{"打", "字", "游", "戏"}; Title() { setBounds(0, 0, width, height);//设置面板大小 setOpaque(false);//透明 setplace();//设置标题每个字初始的横纵坐标 } void setplace() { for (int i = 0; i < N; i++) { x[i] = (int) (width * 0.15 + i * 0.2 * width); y[i] = 10; } } @Override public void paint(Graphics g) { super.paint(g); g.setColor(Color.RED);//设置画笔颜色为红 g.setFont(new Font("方正姚体", Font.PLAIN, 50));//设置画笔字体 for (int i = 0; i < N; i++) { g.drawString(strs[i], x[i], y[i]);//在指定位置画出标题的字 y[i]++;//标题的字纵坐标下移一像素 if (y[i] > height - 50) {//如果到达height-50,则保持在那个位置 y[i] = height - 50; } } } @Override public void run() { while (true) { try { Thread.sleep(10);//实现每10毫秒重绘一次 } catch (InterruptedException e) { e.printStackTrace(); } repaint();//调用重绘函数 } } }
二、图片
bg.jpg
life.jpg
加载全部内容