1 packageSnake;2
3 import java.awt.event.*;4 import javax.swing.*;5 importjavax.swing.Timer;6 importjavax.swing.border.EmptyBorder;7 import javax.swing.table.*;8 import java.awt.*;9 import java.util.*;10 import java.math.*;11
12 public class UI extends JFrame implementsKeyListener{13 staticTimer timer;14 static Font enFont1 = new Font("Times New Roman",Font.BOLD,15);15 static Font enFont2 = new Font("Times New Roman",Font.BOLD,20);16 static Queue Q = new LinkedList();17 static JTextField mmp[][] = new JTextField[30][30];18 staticJPanel drawPanel,scorePanel;19 staticJLabel scoreText,scoreNum,readMe;20 staticJButton newGame,Help,Pause;21 staticSnake snake;22 static String HelpMessage = ""
23 + "Game Rules :\r\n"
24 + "Use the direction keys to control the snake on your keyboard.\r\n"
25 + "Use the space key to pause/continue the game.\r\n"
26 + "The snake can grows longer by eatting food.\r\n"
27 + "Snake head can not touch the edges of the map.\r\n"
28 + "Snake head can not touch his body.\r\n"
29 + "\r\n"
30 + "Happy game, happy life!\r\n\r\n"
31 + "Copyright © J_Coder 2019. All rights reserved.";32 static int diff = 300;33 publicUI(){34 snake = newSnake();35 snake.newSnake();36 //timer 被不断 new 会导致计时器间隔越来越小
37 timer = new Timer(diff, newTimerListener());38 //set drawPanel
39 drawPanel = newJPanel();40 drawPanel.setLayout(null);41 drawPanel.setBounds(10,5,440,440);42 drawPanel.setBackground(Color.DARK_GRAY);43 drawPanel.setFocusable(false);44 this.add(drawPanel);45 for(int i = 0;i <= 21;i ++){46 for(int j = 0;j <= 21;j ++){47 mmp[i][j] = newJTextField();48 mmp[i][j].setEditable(false);49 mmp[i][j].setBounds(20*j,20*i,20,20);50 mmp[i][j].setBorder(new EmptyBorder(0,0,0,0));51 if(i == 0 || j == 0 || i == 21 || j == 21) {52 mmp[i][j].setBackground(new Color(0,155,155));53 }54 elsemmp[i][j].setBackground(Color.WHITE);55 mmp[i][j].setFocusable(false);56 drawPanel.add(mmp[i][j]);57 }58 }59 //set scorePanel
60 scorePanel = newJPanel();61 scorePanel.setLayout(null);62 scorePanel.setBounds(460,5,160,440);63 scorePanel.setBackground(Color.LIGHT_GRAY);64 scorePanel.setFocusable(false);65 this.add(scorePanel);66 readMe = newJLabel();67 readMe.setBounds(0,0,160,150);68 readMe.setOpaque(true);69 readMe.setBackground(Color.white);70 readMe.setFont(enFont1);71 readMe.setText(readMe.getText() + "Description
Press ↓ to move up.
");72 readMe.setText(readMe.getText() + "Press ↑ to move down.
");73 readMe.setText(readMe.getText() + "Press ← to move left.
");74 readMe.setText(readMe.getText() + "Press → to move right.
");75 readMe.setText(readMe.getText() + "Press SPACE to pause or continue the game.");76 readMe.setFocusable(false);77 scorePanel.add(readMe);78 scoreText = new JLabel("SCORE",JLabel.CENTER);79 scoreText.setFont(enFont2);80 scoreText.setBounds(15,170,130,30);81 scoreText.setOpaque(true);82 scoreText.setBackground(Color.white);83 scoreText.setFocusable(false);84 scorePanel.add(scoreText);85 scoreNum = new JLabel("0",JLabel.CENTER);86 scoreNum.setFont(enFont2);87 scoreNum.setBounds(15,210,130,30);88 scoreNum.setOpaque(true);89 scoreNum.setBackground(Color.white);90 scoreNum.setFocusable(false);91 scorePanel.add(scoreNum);92 newGame = new JButton("New Game");93 newGame.setFont(enFont2);94 newGame.setBounds(15,260,130,40);95 newGame.addActionListener(newActionListener(){96 public voidactionPerformed(ActionEvent e){97 snake.newSnake();98 draw();99 timer.start();100 scoreNum.setText("0");101 Pause.setText("Pause");102 }103 });104 newGame.setFocusable(false);105 scorePanel.add(newGame);106 Pause = new JButton("Pause");107 Pause.setFont(enFont2);108 Pause.setBounds(15,310,130,40);109 Pause.addActionListener(newActionListener(){110 public voidactionPerformed(ActionEvent e){111 if(timer == null) return;112 if(Pause.getText().charAt(0) == 'P') {PauseGame();}113 else{ContinueGame();}114 }115 });116 Pause.setFocusable(false);117 scorePanel.add(Pause);118 Help = new JButton("Help");119 Help.setFont(enFont2);120 Help.setBounds(15,360,130,40);121 Help.addActionListener(newActionListener(){122 public voidactionPerformed(ActionEvent e){123 if(timer != null) PauseGame();124 JOptionPane.showMessageDialog(null, HelpMessage, "Help", JOptionPane.INFORMATION_MESSAGE);125 }126 });127 Help.setFocusable(false);128 scorePanel.add(Help);129 //set frame
130 this.setTitle("Snake");131 this.setLayout(null);132 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);133 this.setSize(640, 480);134 Dimension winSize =Toolkit.getDefaultToolkit().getScreenSize();135 this.setLocation((winSize.width - this.getWidth()) / 2,(winSize.height - this.getHeight()) / 2);136 this.setResizable(false);137 this.setVisible(true);138 addKeyListener(this);139 this.setFocusable(true);140 }141
142 voiddraw() {143 for(int i = 1;i <= 20;i ++){144 for(int j = 1;j <= 20;j ++){145 mmp[i][j].setBackground(Color.white);146 if(snake.mmp[i][j] ==snake.L) {147 mmp[i][j].setBackground(new Color(200,50,50));148 }149 else if(snake.mmp[i][j] != 0 && snake.mmp[i][j] != 1000) {150 mmp[i][j].setBackground(new Color(50,50,200));151 }152 else if(snake.mmp[i][j] == 1000){153 mmp[i][j].setBackground(new Color(50,200,50));154 }155 }156 }157 }158
159 static voidPauseGame(){160 timer.stop();161 Pause.setText("Continue");162 }163 static voidContinueGame(){164 timer.start();165 Pause.setText("Pause");166 }167
168 public voidgameOver(){169 timer.stop();170 int nowScore =Integer.valueOf(scoreNum.getText());171 String Title = "GameOver";172 String loseMessage = "Your score is " + scoreNum.getText() + " .\r\n";173 if(nowScore <= 300){loseMessage += "Your evaluation : Too weak !";}174 else if(nowScore <= 800){loseMessage += "Your evaluation : Just so so !";}175 else if(nowScore <= 1300){loseMessage += "Your evaluation : Good job !";}176 else if(nowScore <= 2000){loseMessage += "Your evaluation : Incredible !";}177 else if(nowScore < 3500){loseMessage += "Your evaluation : Holy crap !";}178 else{179 Title = "Congratulations";180 loseMessage = "You are already finish this stage !\r\nThank you for your playing !";181 }182 JOptionPane.showMessageDialog(null, loseMessage, Title, JOptionPane.INFORMATION_MESSAGE);183 }184
185 class TimerListener implementsActionListener {186 public voidactionPerformed(ActionEvent e) {187 //for(int i = 0;i <= 21;i ++) {188 //for(int j = 0;j <= 21;j ++) {189 //System.out.printf("%2d",snake.mmp[i][j]);190 //}System.out.println();191 //}
192 if(Q.size() > 0) snake.dir =Q.poll();193 Q.clear();194 int tmp =snake.moveForward();195 draw();196 if(tmp == -1){gameOver();}197 else scoreNum.setText(String.valueOf(Integer.valueOf(scoreNum.getText()) +tmp));198 if(Integer.valueOf(scoreNum.getText()) >= 3500){199 gameOver();200 }201 }202 }203 //使用 setFocusable() 将 JFrame 设置为 true204 //其他组件设置为 false 可以避免点击其他按钮等操作将焦点转移至其他控件
205 public voidkeyPressed(KeyEvent e) {206 if(e.getKeyCode() ==KeyEvent.VK_SPACE) {207 if(timer != null) {208 if(Pause.getText().charAt(0) == 'P') {PauseGame();}209 else{ContinueGame();}210 }211 return;212 }213 if(Pause.getText().charAt(0) == 'C') {return;}214 if(e.getKeyCode() ==KeyEvent.VK_UP) {215 if(snake.dir != 2) Q.offer(1);216 //if(snake.dir != 2) {snake.dir = 1;}217 //System.out.println("up");
218 return;219 }220 if(e.getKeyCode() ==KeyEvent.VK_DOWN) {221 if(snake.dir != 1) Q.offer(2);222 //if(snake.dir != 1) {snake.dir = 2;}223 //System.out.println("down");
224 return;225 }226 if(e.getKeyCode() ==KeyEvent.VK_LEFT) {227 if(snake.dir != 4) Q.offer(3);228 //if(snake.dir != 4) {snake.dir = 3;}229 //System.out.println("left");
230 return;231 }232 if(e.getKeyCode() ==KeyEvent.VK_RIGHT) {233 if(snake.dir != 3) Q.offer(4);234 //if(snake.dir != 3) {snake.dir = 4;}235 //System.out.println("right");
236 return;237 }238 }239 public voidkeyReleased(KeyEvent e) {}240 public voidkeyTyped(KeyEvent e) {}241 }