Java贪吃蛇 (有窗口)

先画好网格 游戏范围
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<Node> 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<Node> 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();
    }
}

猜你喜欢

转载自blog.csdn.net/zyz0225/article/details/80186883