今天仿照网上代码写了一个贪吃蛇游戏,有六个类:
Node类
package snake; public class Node {//节点类,代表蛇身 private int nodeX; private int nodeY; public int getNodeX(){ return nodeX; } public int getNodeY(){ return nodeY; } public void setNodeX(int nodeX) { this.nodeX = nodeX; } public void setNodeY(int nodeY) { this.nodeY = nodeY; } public Node(int nodeX, int nodeY){ this.nodeX=nodeX; this.nodeY=nodeY; } }
Snake类
package snake; import java.util.LinkedList; import java.util.Random; public class Snake {//蛇 private LinkedList<Node> snakeBody; private Random random; private int direction=0;//方向 private SnakeGameView snakeGameView; public Snake(int snakeHeadX,int snakeHeadY,SnakeGameView snakeGameView){ random=new Random(); snakeBody=new LinkedList<>(); snakeBody.add(new Node(snakeHeadX,snakeHeadY)); this.snakeGameView=snakeGameView; } public int getDirection() { return direction; } public void setDirection(int direction) { this.direction = direction; } public Node getSnakeHead(){ return snakeBody.getFirst();//获取头结点 } public Node getSnakeTail(){ return snakeBody.getLast();//获取尾结点 } public LinkedList<Node> getSnakeBody() { return snakeBody;//身体 } public void snakeMove(){//移动 switch(direction){ case 0: snakeBody.addFirst(new Node(getSnakeHead().getNodeX(),getSnakeHead().getNodeY()-DrawView.VIEW_NUMBER)); break; case 1: snakeBody.addFirst(new Node(getSnakeHead().getNodeX() + DrawView.VIEW_NUMBER,getSnakeHead().getNodeY())); break; case 2: snakeBody.addFirst(new Node(getSnakeHead().getNodeX(),getSnakeHead().getNodeY()+ DrawView.VIEW_NUMBER)); break; case 3: snakeBody.addFirst(new Node(getSnakeHead().getNodeX() - DrawView.VIEW_NUMBER,getSnakeHead().getNodeY())); break; } snakeBody.removeLast(); } public void eatEgg(Node egg){ if(snakeBody.getFirst().getNodeX()==egg.getNodeX()&&snakeBody.getFirst().getNodeY()==egg.getNodeY()){ snakeBody.add(egg); snakeGameView.setEgg(random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER, random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER); SnakeGameView.gameScore = SnakeGameView.gameScore + 5; snakeGameView.getJTextArea().setText(SnakeGameView.gameScore + ""); System.out.println("吃到蛋了"); } } public void snakeRunInterface() {//越界判断 if(this.getSnakeHead().getNodeX() < 0 || this.getSnakeHead().getNodeY() < 0|| this.getSnakeHead().getNodeX() > (DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER)|| this.getSnakeHead().getNodeY() > (DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER)) { SnakeGameView.gameState = false; } } }
SnakeGameView类
package snake; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Random; public class SnakeGameView extends Frame{//游戏界面 private JLabel jl; private DrawView drawView; private Panel panel; private JLabel scoreTitle; private JLabel score; private Panel rule; private JTextArea hint; private Random random; public static boolean gameState = true; public static int gameScore = 0; private Snake snake; private Node egg; private GameRunThread grt; private static Thread thread; public SnakeGameView() { random = new Random(); //初始化Snake snake = new Snake(10 * DrawView.VIEW_NUMBER + random.nextInt(19) * DrawView.VIEW_NUMBER, 10 * DrawView.VIEW_NUMBER + random.nextInt(19) * DrawView.VIEW_NUMBER,this); //初始化Egg egg = new Node(random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER, random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER); //初始化画板 drawView = new DrawView(snake, egg); grt = new GameRunThread(drawView, snake); thread = new Thread(grt); jl = new JLabel("SnakeGame-3.0",JLabel.CENTER); panel = new Panel(); scoreTitle = new JLabel("Score", JLabel.CENTER); score = new JLabel(gameScore + "", JLabel.CENTER); rule = new Panel(); hint = new JTextArea(" 操作方式\n ↑\n ← →\n ↓\n\n【Esc】退出程序\n\n关于\n"); } //设置鸡蛋 public void setEgg(int eggX, int eggY) { this.egg.setNodeX(eggX); this.egg.setNodeY(eggY); } //获得 public JLabel getJTextArea() { return score; } //主方法 public static void main(String[] args) { new SnakeGameView().showView(); thread.start(); } public void showView() { jl.setFont(new Font("宋体", 1, 18));//设置字体,0正常,1粗体 jl.setForeground(Color.white);//设置颜色 jl.setBounds(0, 0, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 70, 40); drawView.setBackground(new Color(51,51,51)); drawView.setBounds(20, 50, DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1); panel.setLayout(null); panel.setBackground(new Color(0,102,102)); panel.setBounds(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 40, 50, 150, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER); scoreTitle.setFont(new Font("宋体", 1, 18));//设置字体,0正常,1粗体 scoreTitle.setForeground(Color.white);//设置颜色 scoreTitle.setBounds(0, 0, 150, 50); score.setFont(new Font("宋体", 1, 20));//设置字体,0正常,1粗体 score.setForeground(Color.white);//设置颜色 score.setBounds(0, 50, 150, 40); rule.setBackground(new Color(0,128,128)); rule.setBounds(0, 90, 150, 1); hint.setFont(new Font("宋体", 0, 16));//设置字体,0正常,1粗体 hint.setBounds(10, 100, 130, 150); hint.setBackground(new Color(0,102,102)); panel.add(scoreTitle); panel.add(score); panel.add(rule); panel.add(hint); this.add(jl); this.setTitle("SnakeGame-3.0"); this.setSize(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 210, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 70); this.setLocation(500, 200); this.setLayout(null); //this.setUndecorated(true); this.setBackground(new Color(0,128,128)); this.add(drawView); this.add(panel); this.addKeyListener(new GameControl(snake)); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0); } }); this.setVisible(true); } }
DrawView类
package snake; import java.awt.*; public class DrawView extends Panel{ //画板的宽度高度 public static final int VIEW_WIDTH = 40; public static final int VIEW_HEIGHT = 40; public static final int VIEW_NUMBER = 15; private Image iBuffer; private Graphics gBuffer; private Snake snake; private Node egg; public DrawView(Snake snake, Node egg) { this.snake = snake; this.egg = egg; } public void paint(Graphics g) { snake.snakeMove(); this.drawGridding(g); this.drawSnake(g); this.drawEgg(g); snake.eatEgg(egg); System.out.println("("+snake.getSnakeHead().getNodeX()+","+snake.getSnakeHead().getNodeY()+")"); } public void update(Graphics g) { if(iBuffer==null) { iBuffer=createImage(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1); gBuffer=iBuffer.getGraphics(); } gBuffer.setColor(getBackground()); gBuffer.fillRect(0,0,DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1); paint(gBuffer); g.drawImage(iBuffer,0,0,this); } //画表格 public void drawGridding(Graphics g) { g.setColor(new Color(128,128,128)); for(int i = 0; i < VIEW_WIDTH; i++) { g.drawLine(0, i * VIEW_NUMBER, VIEW_WIDTH * VIEW_NUMBER, i * VIEW_NUMBER); } for(int i = 0; i < VIEW_HEIGHT; i++) { g.drawLine(i * VIEW_NUMBER, 0, i * VIEW_NUMBER, VIEW_WIDTH * VIEW_NUMBER); } } //画蛇 public void drawSnake(Graphics g) { for(int i = 0; i < snake.getSnakeBody().size(); i ++) { g.setColor(Color.white); if(i == 0) g.setColor(Color.lightGray); g.fillRect(snake.getSnakeBody().get(i).getNodeX(), snake.getSnakeBody().get(i).getNodeY(), VIEW_NUMBER, VIEW_NUMBER); } } //画食物 public void drawEgg(Graphics g) { g.setColor(Color.yellow); g.fillRect(egg.getNodeX(), egg.getNodeY(), VIEW_NUMBER, VIEW_NUMBER); } }
GameRunThread类
package snake; public class GameRunThread implements Runnable{//重画界面 private int runTime=200; private DrawView drawView; private Snake snake; public GameRunThread(DrawView drawView,Snake snake){ this.drawView=drawView; this.snake=snake; } public void run(){ while(true){ snake.snakeRunInterface(); if(SnakeGameView.gameState){ drawView.repaint(); try{ Thread.sleep(runTime); }catch(InterruptedException e){ e.printStackTrace(); } } } } }
GameControl类
package snake; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class GameControl implements KeyListener{//监听 private Snake snake; public GameControl(Snake snake){ this.snake=snake; } public void keyReleased(KeyEvent ke){ switch(ke.getKeyCode()){ case KeyEvent.VK_UP: snake.setDirection(0); break; case KeyEvent.VK_RIGHT: snake.setDirection(1); break; case KeyEvent.VK_DOWN: snake.setDirection(2); break; case KeyEvent.VK_LEFT: snake.setDirection(3); break; case KeyEvent.VK_ENTER: if (SnakeGameView.gameState == true) SnakeGameView.gameState = false; else SnakeGameView.gameState = true; break; case KeyEvent.VK_ESCAPE: System.exit(0); break; } } public void keyPressed(KeyEvent arg0) { } public void keyTyped(KeyEvent arg0) { } }