本文共 7646 字,大约阅读时间需要 25 分钟。
package snake;/** * * @author hjn * */public class Constant {/** * 蛇方移动方向:左边 */public static final int LEFT = 0;/** * 蛇方移动方向:右边 */public static final int RIGHT = 1;/** * 蛇方移动方向:上边 */public static final int UP = 3;/** * 蛇方移动方向:下边 */public static final int DOWN = 4;/** * 界面列数 */public static final int COLS = 30;/** * 界面行数 */public static final int ROWS = 30;/** * 每个格子边长 */public static final int BODER_SIZE = 15;}Node.java代码如下:
package snake;/** * 格子 * * @author hjn * */public class Node {/** * 所在行数 */private int row;/** * 所在列数 */private int col;public Node() {};public Node(int row, int col) {this.row = row;this.col = col;};/** * 蛇将要移动一格时头部格子将所到格子 * * @param dir * 蛇前进方向 * @param node * 蛇头所在的格子 */public Node(int dir, Node node) {if (dir == Constant.LEFT) {this.col = node.getCol() - 1;this.row = node.getRow();} else if (dir == Constant.RIGHT) {this.col = node.getCol() + 1;this.row = node.getRow();} else if (dir == Constant.UP) {this.row = node.getRow() - 1;this.col = node.getCol();} else {this.row = node.getRow() + 1;this.col = node.getCol();}}/** * 重写equals方法 */public boolean equals(Object obj) {if (obj instanceof Node) {Node node = (Node) obj;if (this.col == node.col && this.row == node.row) {return true;} else {return false;}} else {return false;}}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public String toString() {return "col:" + this.col + " row:" + this.row;}}
package snake;import java.awt.Color;import java.awt.Graphics;import java.util.Random;/** * 蛋,蛇的食物 * * @author Nan * */public class Egg extends Node {/** * 蛋的颜色 */Color color;/** * 随机函数 */public static Random random = new Random();/** * 构造函数 蛋出现在固定位置 * * @param row * 所在第几行数 * @param col * 所在第几列数 */public Egg(int row, int col) {super(row, col);this.color = Color.green;}/** * 构造函数 蛋随机出现 * */public Egg() {super();int col = random.nextInt(Constant.COLS - 4) + 2;int row = random.nextInt(Constant.ROWS - 4) + 2;this.setCol(col);this.setRow(row);}/** * 画蛋 * @param g 画笔 */void draw(Graphics g) {if (this.color == Color.green) {this.color = Color.red;} else {this.color = Color.green;}g.setColor(this.color);int boderSize = Constant.BODER_SIZE;g.fillOval(this.getCol() * boderSize, this.getRow() * boderSize,boderSize, boderSize);}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}}Snake.java代码如下:
package snake;import java.awt.Color;import java.awt.Graphics;import java.awt.event.KeyEvent;import java.util.ArrayList;import java.util.List;/** * 蛇 * * @author hjn * */public class Snake {/** * 前进的方向 */int dir;/** * 蛇的身体,由一个格子Node集合组成 */ListnodeList = new ArrayList ();/** * 是否越界 */boolean isOverstep = false;/** * 构造方法默认开始方向向左 ,蛇身有3个格子 ,位置在20行,15列 */public Snake() {this.dir = Constant.LEFT;for (int i = 0; i < 3; i++) {Node node = new Node(20, 15 + i);this.nodeList.add(node);}}/** * 蛇前进 */void forward() {addNode();nodeList.remove(nodeList.size() - 1);}/** * 蛇前进的时候头部增加格子,私有方法 */private void addNode() {Node node = nodeList.get(0);node = new Node(dir, node);nodeList.add(0, node);}/** * 是否吃到蛋,蛇身是否有格子跟蛋重叠,所以重写了Node的equals方法 * * @param egg蛋 * @return boolean */boolean eatEgg(Egg egg) {if (nodeList.contains(egg)) {addNode();return true;} else {return false;}}/** * 画自己 * * @param g画笔 */void draw(Graphics g) {g.setColor(Color.black);for (int i = 0; i < this.nodeList.size(); i++) {Node node = this.nodeList.get(i);if (node.getCol() > (Constant.COLS - 2) || node.getCol() < 2|| node.getRow() > (Constant.ROWS - 2) || node.getRow() < 2) {this.isOverstep = true;}g.fillRect(node.getCol() * Constant.BODER_SIZE, node.getRow()* Constant.BODER_SIZE, Constant.BODER_SIZE,Constant.BODER_SIZE);}forward();}/** * 键盘事件,来确定前进方向,有左右上下4个方向 * * @param e键盘监听事件 */void keyPress(KeyEvent e) {int key = e.getKeyCode();switch (key) {case KeyEvent.VK_LEFT:if (this.dir != Constant.LEFT)this.dir = Constant.LEFT;break;case KeyEvent.VK_RIGHT:if (this.dir != Constant.RIGHT)this.dir = Constant.RIGHT;break;case KeyEvent.VK_UP:if (this.dir != Constant.UP)this.dir = Constant.UP;break;case KeyEvent.VK_DOWN:if (this.dir != Constant.DOWN)this.dir = Constant.DOWN;break;default:break;}}public int getDir() {return dir;}public void setDir(int dir) {this.dir = dir;}public List getNodeList() {return nodeList;}public void setNodeList(List nodeList) {this.nodeList = nodeList;}public boolean isOverstep() {return isOverstep;}public void setOverstep(boolean isOverstep) {this.isOverstep = isOverstep;}}
package snake;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;/** * 贪吃蛇展示页面 * * @author hjn * */public class MainFrame extends Frame {/** * 版本 */private static final long serialVersionUID = -5227266702753583633L;/** * 背景颜色 */Color color = Color.gray;/** * 蛋 */static Egg egg = new Egg();/** * 蛇 */Snake snake = new Snake();/** * 游戏是否失败 */boolean gameOver = false;/** * 给画笔起一个线程 */PaintThread paintThread = new PaintThread();/** * 构造方法 */public MainFrame() {init();}/** * 界面初始化 */void init() {this.setBounds(200, 200, Constant.COLS * Constant.BODER_SIZE,Constant.ROWS * Constant.BODER_SIZE);this.setResizable(true);this.repaint();/** * 窗口关闭监听事件 */this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});/** * 添加键盘监听事件 */this.addKeyListener(new KeyMomiter());/** * 画笔线程启动 */new Thread(paintThread).start();}/** * 画笔画界面 */public void paint(Graphics g) {Color c = g.getColor();g.setColor(Color.GRAY);g.fillRect(0, 0, Constant.COLS * Constant.BODER_SIZE, Constant.ROWS* Constant.BODER_SIZE);g.setColor(Color.DARK_GRAY);for (int i = 0; i < Constant.ROWS; i++) {g.drawLine(0, i * Constant.BODER_SIZE, Constant.COLS* Constant.BODER_SIZE, i * Constant.BODER_SIZE);}for (int i = 0; i < Constant.COLS; i++) {g.drawLine(i * Constant.BODER_SIZE, 0, i * Constant.BODER_SIZE,Constant.ROWS * Constant.BODER_SIZE);}g.setColor(Color.yellow);g.setFont(new Font("宋体", Font.BOLD, 20));g.drawString("score:" + getScore(), 10, 60);if (gameOver) {g.setColor(Color.red);g.drawString("GAME OVER", 100, 60);this.paintThread.pause = true;}g.setColor(c);if (snake.eatEgg(egg)) {egg = new Egg();}snake.draw(g);egg.draw(g);}/** * 获取分数 * * @return int 分数 */int getScore() {return snake.getNodeList().size();}/** * 画笔的线程 * * @author hjn */class PaintThread implements Runnable {private boolean isRun = true;private boolean pause = false;@Overridepublic void run() {while (isRun) {if (pause) {continue;} else {if (snake.isOverstep == true) {gameOver = true;}repaint();}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}/** * 暂停 */public void pause() {this.pause = true;}/** * 重新开始 */public void restart() {this.pause = true;snake = new Snake();}/** * 游戏结束 */public void gameOver() {isRun = false;}}/** * 停止 */void stop() {gameOver = true;}/** * 键盘监听器 * * @author hjn * */class KeyMomiter extends KeyAdapter {@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);int key = e.getKeyCode();if (key == KeyEvent.VK_F2) {paintThread.restart();} else {snake.keyPress(e);}}}/** * 启动程序入口 * * @param args */@SuppressWarnings("deprecation")public static void main(String[] args) {MainFrame mainFrame = new MainFrame();mainFrame.show();}}