Java学习(8):贪吃蛇游戏

根据视频编写的贪吃蛇游戏

主方法

public class Start {

    public static void main(String[] args) {
        new Yard().launch();
    }
}
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 *
 * @author xcx
 * @time 2017年7月28日下午3:44:48
 */
public class Yard extends Frame {
    //设置游戏结束字体
    Font goFont = new Font("宋体",Font.ITALIC|Font.BOLD,50);
    //游戏开始的线程
    PaintThread paintThread = new PaintThread();
    //游戏得分
    public static int score = 0;
    //判断蛇是否死掉
    private static boolean flag = true;
    //行数与列数
    public static final int ROWS = 30;
    public static final int COLS = 30;
    // 每个格子的边长
    public static final int BLOCK_SIZE = 15;

    //定义一条蛇,一个蛋
    Snake s = new Snake();
    Egg e = new Egg();

    // 加入双缓冲
    Image offScreenImage = null;

    public void launch() {
        setLayout(null);
        setLocation(200, 200);
        setSize(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0) {
                setVisible(true);
                System.exit(0);
            }
        });

        // 添加键盘控制事件
        addKeyListener(new KeyMonitor());
        // 运行线程
        paintThread.start();

    }

    @Override
    public void paint(Graphics g) {
        // 保存画笔额颜色
        Color color = g.getColor();
        // 设置画笔的颜色
        g.setColor(Color.gray);
        g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
        g.setColor(Color.DARK_GRAY);
        // 画出横线
        for (int i = 0; i < ROWS; i++) {
            g.drawLine(0, BLOCK_SIZE * i, BLOCK_SIZE * COLS, BLOCK_SIZE * i);
        }
        // 画出竖线
        for (int i = 0; i < ROWS; i++) {
            g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);
        }
        g.setColor(Color.yellow);
        g.drawString("score"+score, 10, 60);
        if(flag == false){
            g.setFont(goFont);
            g.drawString("game over", 100, 180);
            paintThread.gameOver();
        }
        // 还原画笔的颜色
        g.setColor(color);
        s.eat(e);
        e.draw(g);
        s.draw(g);
        
    }

    @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);

    }

    //停止
    public static void stop(){
        flag = false;
    }
    // 不断刷新界面
    private class PaintThread extends Thread {
        private boolean running = true;
        @Override
        public void run() {
            while (running) {
                repaint();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        public void gameOver(){
            running = false;
        }
    }

    //键盘监听事件
    private class KeyMonitor extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            s.keyPressed(e);
        }
    }
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

/**
 *
 * @author xcx
 * @time 2017年7月28日下午3:45:03
 */
public class Snake {
    // 蛇的头结点和尾结点
    private Node head = null;
    private Node tail = null;
    private int size = 0;

    // 自己定义一个头
    private Node node = new Node(20, 30, Dir.L);

    public Snake() {
        head = node;
        tail = node;
        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 R:
            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 D:
            node = new Node(head.row + 1, head.col, head.dir);
            break;
        }
        node.next = head;
        head.prev = node;
        head = node;
        size++;
    }

    // 从蛇的尾巴删除一个结点
    private void deleteFromTail() {
        if (size == 0)
            return;
        tail = tail.prev;
        tail.next = null;

    }

    // 将蛇画出
    public void draw(Graphics g) {
        if (size <= 0)
            return;
        move();
        for (Node node = head; node != null; node = node.next) {
            node.draw(g);
        }
    }

    // 蛇移动一下
    private void move() {
        addToHead();
        deleteFromTail();
        checkDead();
    }

    // 检查蛇是否死掉
    private void checkDead() {
        // 判断蛇是否撞在了墙上
        if (head.row < 0 || head.row > Yard.ROWS || head.col < 0
                || head.col > Yard.COLS) {
            Yard.stop();
        }
        // 判断蛇是否撞在了自己的身上
        for (Node node = head.next; node != null; node = node.next) {
            if (this.getRect().intersects(node.getRect())) {
                Yard.stop();
            }
        }
    }

    // 键盘按下后蛇头方向改变
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        switch (key) {
        case KeyEvent.VK_LEFT:
            if (head.dir != Dir.R)
                head.dir = Dir.L;
            break;
        case KeyEvent.VK_RIGHT:
            if (head.dir != Dir.L)
                head.dir = Dir.R;
            break;
        case KeyEvent.VK_UP:
            if (head.dir != Dir.D)
                head.dir = Dir.U;
            break;
        case KeyEvent.VK_DOWN:
            if (head.dir != Dir.U)
                head.dir = Dir.D;
            break;
        }
    }

    // 蛇吃蛋
    public void eat(Egg e) {
        if (this.getRect().intersects(e.getRect())) {
            e.reAppear();
            addToTail();
            Yard.score += 5;
        }
    }

    // 判断蛇头所在的格子
    private Rectangle getRect() {
        return new Rectangle(Yard.BLOCK_SIZE * head.col, Yard.BLOCK_SIZE
                * head.row, head.w, head.h);
    }

    // 定义结点内部类
    private class Node {
        // 结点的高度与宽度
        int w = Yard.BLOCK_SIZE;
        int h = Yard.BLOCK_SIZE;
        // 所在的位置
        int row, col;
        // 结点的方向
        Dir dir = Dir.L;
        // 后一个结点
        Node next = null;
        // 前一个结点
        Node prev = null;

        Node(int row, int col, Dir dir) {
            this.row = row;
            this.col = col;
            this.dir = dir;
        }

        void draw(Graphics g) {
            Color color = g.getColor();
            g.setColor(Color.black);
            g.fillRect(Yard.BLOCK_SIZE * col, Yard.BLOCK_SIZE * row, w, h);
            g.setColor(color);
        }

        // 判断节点所在的格子
        private Rectangle getRect() {
            return new Rectangle(Yard.BLOCK_SIZE * col, Yard.BLOCK_SIZE * row,
                    w, h);
        }
    }
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;

/**
 *
 * @author xcx
 * @time 2017年7月28日下午3:45:11
 */
public class Egg {
    // 设置蛋的颜色
    Color color = Color.green;
    // 出现的坐标
    private int row, col;
    // 蛋的高与宽
    private int w = Yard.BLOCK_SIZE;
    private int h = Yard.BLOCK_SIZE;

    private static Random r = new Random();

    public Egg(int x, int y) {
        this.row = x;
        this.col = y;
    }

    public Egg() {
        this(r.nextInt(Yard.ROWS), r.nextInt(Yard.COLS));

    }

    public void reAppear() {        
        this.row = r.nextInt(Yard.ROWS) ;
        this.col = r.nextInt(Yard.COLS) ;

    }

    // 画出一个蛋
    public void draw(Graphics g) {
        Color c = g.getColor();
        g.setColor(color);
        g.fillOval(Yard.BLOCK_SIZE * row, Yard.BLOCK_SIZE * col, w, h);
        g.setColor(c);
        if (color == Color.green) {
            color = Color.red;
        } else {
            color = Color.green;
        }
    }

    // 得到蛋所在的格子
    public Rectangle getRect() {
        return new Rectangle(Yard.BLOCK_SIZE * row, Yard.BLOCK_SIZE * col, w, h);
    }
}
/**
 *
 *@author xcx 
 *@time 2017年7月28日下午4:14:38
 */
public enum Dir {
    L,R,U,D

}
原文地址:https://www.cnblogs.com/xcxfuryit/p/7256170.html