先画好网格 游戏范围
public class Grid { //定义网格 public static int rows; //列数 public static int cols; //行数 public static int size; //格子大小 /** * 构造一个网格 * * @param rows 行数 * @param cols 列数 */ public Grid(int rows, int cols, int size) {
this.rows = rows;
this.cols = cols;
this.size = size;
}
}
再定义节点 根据节点来描述食物和蛇位置
public class Node { //定义节点 private int col; //col 列数 private int row; //row 行数 /** * 构造函数(初始化一个节点) * @param row * @param col */ public Node(int row,int col){
this.col = col;
this.row = row;
}
/** * 拷贝构造函数 (用一个已经存在的对象复制出另一个对象) * @param node 待复制的节点 */ public Node(Node node) {
this.row = node.getRow();
this.col = node.getCol();
}
/** * 判断节点是否相等 * @param p * @return true-相等 false-不相等 */ public boolean isSame(Node p){
// return (p.col ==this.col && p.row ==this.row);
}
public int getCol() {
return col;
}
public int getRow() {
return row;
}
public void setCol(int col) {
this.col = col;
}
public void setRow(int row) {
this.row = row;
}
}
定义蛇这个类
import java.util.LinkedList;public class Snake { //蛇移动的方向 **public static final byte LEFT = 1; public static final byte RIGHT = -1; public static final byte UP = 2; public static final byte DOWN = -2; public byte direction = RIGHT; //默认初始移动方向 *public byte beforeDirection = RIGHT; private boolean isGrow = false; //默认不成长 public byte getDirection() { return direction; } public void setDirection(byte direction) { this.direction = direction; } private LinkedList snakeBody = new LinkedList<>(); //来一条蛇 / ** 初始化一条蛇 (位于左上角长度为4向右移动的蛇) / public Snake(){ for (int n = 1; n <=4 ; n++) { Node node = new Node(0,4-n); snakeBody.add(node); } direction = RIGHT; } / ** 蛇的移动 */ *public void move(){ / 思路:加头去尾 ** / //加头:(1)复制当前的头 (2)根据方向跳整横坐标或纵坐标 // (3)插入到头部 **Node head = snakeBody.getFirst(); //找到蛇头 **Node newHead = new Node(head); switch (direction){ case LEFT: //键盘改方向使蛇移动 *newHead.setCol(newHead.getCol()-1); break; case RIGHT: newHead.setCol(newHead.getCol()+1); break; case UP: newHead.setRow(newHead.getRow()-1); break; case DOWN: newHead.setRow(newHead.getRow()+1); break; } snakeBody.addFirst(newHead); //移动的时候判断是否需要去尾(是否生长) if (!isGrow){ snakeBody.removeLast(); }else { isGrow = false; } } / ** 蛇的生长 / public void grow(){ isGrow = true; } / ** 判断蛇是否吃到自己 *** @return */ public boolean eatSelf(){ / ** 将蛇身的每个节点和舌头进行比较, ** 只要有一个重合的则说明迟到了自己 */ **Node head = snakeBody.getFirst(); //拿到蛇头 *for (int i =1;i<snakeBody.size();i++){ //遍历循环和身体相比较 if (snakeBody.get(i).isSame(head)){ return true; } } return false; } / ** 判断蛇是否撞到墙 *** @return ***/ **public boolean isCollide(){ if (getSnakeBody().getFirst().getCol()==Grid.cols||getSnakeBody().getFirst().getRow()==Grid.rows ||getSnakeBody().getFirst().getCol()<0||getSnakeBody().getFirst().getRow()<0){ return true; } return false; } public LinkedList getSnakeBody(){ return snakeBody; }}
定义食物这个类
import java.util.LinkedList;
public class Food { //定义随机食物的点 private Node node;
public Node getNode() {
return node;
}
private static int x,y;
// 写一个构造函数 public Food(Grid grid,Snake snake){
// 思路:(1)随机生成食物的位置(横纵坐标) (2) 判断食物有没有与蛇重叠 //(3)重复以上过程直到确定一个没有重叠的位置 while(true){
//随机生成一个横纵坐标 x = (int)(Math.random()*Grid.cols);
y = (int)(Math.random()*Grid.rows);
Node food = new Node(x,y);
//判断是否与蛇身重叠 LinkedList<Node> body = snake.getSnakeBody();
boolean overlap = false; //蛇身与食物是否重叠的标记 for(Node node:body){ //遍历蛇的身体 if(food.equals(node)){
overlap = true;
break;
}
}
//如果没有重叠,则确定了位置,结束 if(!overlap){
this.node = food;
break; }
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
定义游戏这个类 来操作游戏里的蛇
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
public class Game {
private Frame frame; //定义一个弹框 private Canvas canvas; //定义一个画布 private Graphics graphics; // 定义一个画笔 private Snake snake; //三个属性 成员 private Grid grid;
private Food food;
public Game(int rows, int cols, int size) {
snake = new Snake(); //小程序.蛇 grid = new Grid(rows, cols, size); //网格 food = new Food(grid,snake); //食物 frame = new Frame( "小程序/贪吃蛇" ); //窗口名 frame.setSize(500, 500); //窗口大小 canvas = new Canvas(); //来一个新画布 frame.add(canvas); //把画布放在窗口里 frame.setVisible(true); //true-可见 false - 不可见 drawGrid(); //画出网格线 drawFood(); //画食物 drawSnake(); //画蛇 if (snake.eatSelf() || snake.isCollide()){ //如果蛇吃到自己或者碰到了墙游戏结束 int res=JOptionPane.showConfirmDialog(null, "是否继续游戏" , "游戏结束" , JOptionPane.YES_NO_OPTION);
if(res==JOptionPane.YES_OPTION){ //点击“是”后执行这个代码块 }else{
System.exit(1); //点击“否”后执行这个代码块 return;
}
}
if (isEatFood()){ //如果吃到了食物 蛇就生长 ,食物重新初始化 snake.grow();
food = new Food(grid,snake);
}
snake.move();
// 键盘事件 用来控制蛇的方向 canvas.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
handleKeyPress(e.getKeyCode());
}
});
}
/** * 画出网格线 游戏布局 */ public void drawGrid() {
graphics = canvas.getGraphics();
graphics.setColor(Color.white);
graphics.fillRect(0, 0, grid.rows * grid.size, grid.cols * grid.size);
graphics.setColor(Color.BLACK);
for (int i=0; i <= grid.rows; i++) {
graphics.drawLine(0, i * grid.size, grid.rows * grid.size, i * grid.size);
}
for (int i = 0; i <= grid.cols; i++) {
graphics.drawLine(i * grid.size, 0, i * grid.size, grid.cols * grid.size);
}
}
/** * 判断蛇是否吃到食物 * @return 吃到食物 false-没有吃到食物 */ public boolean isEatFood(){
//拿到蛇的头部节点 Node head = snake.getSnakeBody().getFirst();
//判断蛇头的节点与食物的节点是否相等 return food.getNode().isSame(head);
}
/** * 画食物 */ public void drawFood() {
drawNode(food.getNode(),Color.BLUE);
/* graphics = canvas.getGraphics(); graphics.setColor(Color.RED); //拿到食物节点的坐标 graphics.fillRect(food.getX() * grid.size, food.getY() * grid.size, grid.size, grid.size); */ }
/** * 画蛇 */ public void drawSnake() {
LinkedList<Node> snakeBody = snake.getSnakeBody();
graphics = canvas.getGraphics();
for (int i = 0; i < snakeBody.size(); i++) {
Node node = snakeBody.get(i);
drawNode(node,0==i?Color.MAGENTA:Color.CYAN);
// if (i == 0) { drawNode(node,Color.CYAN); } else { drawNode(node,Color.cyan); } }
}
/** * 绘制节点 * @param node 待绘制的节点 * @param color 待绘制的背景色 */ private void drawNode(Node node,Color color){
graphics = canvas.getGraphics();
graphics.setColor(color);
graphics.fillRect(node.getCol() * grid.size, node.getRow() * grid.size, grid.size, grid.size);
}
/** *改变蛇的方向 * @param keyCode 按键键码 */ private void handleKeyPress(int keyCode) {
int dir =snake.beforeDirection;
switch (keyCode) {
case KeyEvent.VK_SPACE:
case KeyEvent.VK_LEFT:
if (dir!= snake.RIGHT){
snake.setDirection(Snake.LEFT);
snake.beforeDirection = snake.getDirection();
}
break;
case KeyEvent.VK_UP: //上 if (dir!= snake.DOWN){
snake.setDirection(Snake.UP);
snake.beforeDirection = snake.getDirection();
}
break;
case KeyEvent.VK_RIGHT: // 右 if (dir!=snake.LEFT){
snake.setDirection(snake.RIGHT);
snake.beforeDirection = snake.getDirection();
}
break;
case KeyEvent.VK_DOWN: // 下 if (dir!=snake.UP) {
snake.setDirection(snake.DOWN);
snake.beforeDirection = snake.getDirection();
}
break;
default:
break;
}
}
public static void main(String[] args) {
Game game = new Game(25, 25, 20);
game.start();
}
public void start() {
new Thread(){
@Override
public void run() {
LinkedList<Node> snakeBody = snake.getSnakeBody();
while (true) {
snake.move(); //移动蛇 //如果蛇吃到自己或者碰到了墙游戏结束 if (snake.eatSelf() || snake.isCollide()){
int res=JOptionPane.showConfirmDialog(null, "是否继续游戏" , "游戏结束" , JOptionPane.YES_NO_OPTION);
if(res==JOptionPane.YES_OPTION){ //点击“是”后执行这个代码块 System.out.println( "重新2来过" );
break;
}else{ //点击“否”后执行这个代码块 System.exit(1);
return;
}
}
//如果吃到了食物 蛇就生长 if (isEatFood()){
snake.grow();
food = new Food(grid,snake);
}
drawGrid();
drawFood();
drawSnake();
try { //线程 延迟五百毫秒 也就是0.5秒动一下 sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}