贪吃蛇总共有四个类:
1.Yard.java
2.Snake.java
3.Egg.java
4.Dir.java(枚举类 表示方向)
在编程遇到的问题是当蛇吃到蛋时蛋不会马上消失,原因是先画蛇再画蛋,这样导致蛋有线程的延迟时间才能消失,所以在Yard类中一定要先画蛋再画蛇,否则会出现在吃到蛋一瞬间但不会先消失,要到下一秒才会消失,顺序不能调换。
import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; public class Yard extends JFrame { public static final int ROWS = 30; public static final int COLS = 30; public static final int BLOCK_SIZE = 15; public static boolean running = true; Snake s = new Snake(); Egg e = new Egg(); // Image offScreenImage = null; public static void main(String[] args) { // TODO Auto-generated method stub new Yard().launch(); } public static void stop() { running = false; } public void launch() { this.setBounds(400, 100, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.addKeyListener(new KeyMonitor()); new Thread(new PaintThread()).start(); } //添加双缓冲 // @Override // public void update(Graphics g) { // if(offScreenImage == null) { // offScreenImage = this.createImage(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE); // } // Graphics gOff = offScreenImage.getGraphics(); // paint(gOff); // g.drawImage(offScreenImage, 0, 0, null); // } @Override public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.gray); g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE); g.setColor(Color.darkGray); for(int i=1;i<ROWS;i++) { g.drawLine(0, i * BLOCK_SIZE, COLS * BLOCK_SIZE, i * BLOCK_SIZE); } for(int i=1;i<COLS;i++) { g.drawLine(i * BLOCK_SIZE, 0, i * BLOCK_SIZE, ROWS * BLOCK_SIZE); } g.setColor(c); s.eat1(e); // s.eat(e); e.draw(g);//一定要先画蛋再画蛇,否则会出现在吃到蛋一瞬间但不会先消失,要到下一秒才会消失,顺序不能调换 s.draw(g); } public class PaintThread implements Runnable { private boolean pause = false; @Override public void run() { // TODO Auto-generated method stub while(running) { if(pause)continue; else { repaint(); } try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } private class KeyMonitor extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); s.keyPressed(e); } } }
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.KeyEvent; public class Snake { Node head = null; Node tail = null; Node n = new Node(10,10,Dir.D); int size = 0; public Snake() { head = n; tail = n; size = 1; } public void addToTail() { Node node = null; switch(tail.dir) { case L: node = new Node(tail.row,tail.col + 1,tail.dir); break; case R: node = new Node(tail.row,tail.col - 1,tail.dir); break; case U: node = new Node(tail.row + 1,tail.col,tail.dir); break; case D: node = new Node(tail.row - 1,tail.col,tail.dir); break; } tail.next = node; node.prev = tail; tail = node; size ++; } public void addToHead() { Node node = null; switch(head.dir) { case L : node = new Node(head.row, head.col - 1, head.dir); break; case U : node = new Node(head.row - 1, head.col, head.dir); break; case R : node = new Node(head.row, head.col + 1, head.dir); break; case D : node = new Node(head.row + 1, head.col, head.dir); break; } node.next = head; head.prev = node; head = node; size ++; } public void draw(Graphics g) { if(size <= 0)return; move(); for(Node n=head;n!=null;n=n.next) { n.draw(g); } } private void move() { addToHead(); deleteFromTail(); checkDead(); } private void deleteFromTail() { if(size <= 0)return; tail = tail.prev; tail.next = null; } public void eat1(Egg e) { if(e.row == head.row && e.col == head.col) { e.reAppear(); addToTail(); } } public void eat(Egg e) { if(this.getRect().intersects(e.getRect())) { e.reAppear(); this.addToHead(); } } private Rectangle getRect() { return new Rectangle(Yard.BLOCK_SIZE * head.col, Yard.BLOCK_SIZE * head.row, Yard.BLOCK_SIZE, Yard.BLOCK_SIZE); } public void checkDead() { if(head.row < 2 || head.col < 0 || head.row > Yard.ROWS || head.col > Yard.COLS) { Yard.stop(); } for(Node n=head.next;n!=null;n=n.next) { if(head.col == n.col && head.row == n.row) { Yard.stop(); } } } private class Node { Node next = null; Node prev = null; int row; int col; Dir dir; public Node(int row,int col, Dir dir) { this.row = row; this.col = col; this.dir = dir; } void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.black); g.fillRect(col * Yard.BLOCK_SIZE, row * Yard.BLOCK_SIZE, Yard.BLOCK_SIZE, Yard.BLOCK_SIZE); g.setColor(c); } } public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch(key) { case KeyEvent.VK_DOWN: if(head.dir != Dir.U) { head.dir = Dir.D; } break; case KeyEvent.VK_UP: if(head.dir != Dir.D) { head.dir = Dir.U; } break; case KeyEvent.VK_RIGHT: if(head.dir != Dir.L) { head.dir = Dir.R; } break; case KeyEvent.VK_LEFT: if(head.dir != Dir.R) { head.dir = Dir.L; } break; } } // public void keyPressed(KeyEvent e) { // int key = e.getKeyCode(); // switch(key) { // case KeyEvent.VK_KP_DOWN: // if(head.dir != Dir.U) { // head.dir = Dir.D; // } // break; // case KeyEvent.VK_KP_UP: // if(head.dir != Dir.D) { // head.dir = Dir.U; // } // break; // case KeyEvent.VK_KP_RIGHT: // if(head.dir != Dir.L) { // head.dir = Dir.R; // } // break; // case KeyEvent.VK_KP_LEFT: // if(head.dir != Dir.R) { // head.dir = Dir.L; // } // break; // } // } }
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.util.Random; public class Egg { int row; int col; private Random r = new Random(); Color color = Color.red; public Egg() { // row = (int) (Math.random() * (Yard.ROWS - 2)) + 2; // col = (int) (Math.random() * (Yard.COLS - 2)) + 2; row = r.nextInt(Yard.ROWS - 2) + 2; col = r.nextInt(Yard.COLS); } public void reAppear() { row = r.nextInt(Yard.ROWS - 2) + 2; col = r.nextInt(Yard.COLS); } public void draw(Graphics g) { Color c = g.getColor(); g.setColor(color); g.fillOval(col * Yard.BLOCK_SIZE, row * Yard.BLOCK_SIZE, Yard.BLOCK_SIZE, Yard.BLOCK_SIZE); g.setColor(c); if(color == Color.red) color = Color.green; else color = Color.red; } public Rectangle getRect() { return new Rectangle(Yard.BLOCK_SIZE * col, Yard.BLOCK_SIZE * row, Yard.BLOCK_SIZE, Yard.BLOCK_SIZE); } }
public enum Dir { L,R,U,D }