zoukankan      html  css  js  c++  java
  • 贪吃蛇java版

    主要的蛇的类

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.HeadlessException;
    import java.awt.Rectangle;
    import java.awt.event.KeyEvent;
    import java.util.Random;
    
    
    public class Snake {
        
        private Node head = null;
        private Node tail = null;
        int size = 0;
        private boolean live = true;
        
        /**
         * 判断蛇是否活着
         * @return true则活着 false则死亡
         */
        public boolean isLive() {
            return live;
        }
        /**
         * 设置蛇的生死
         * @param live true则活着 false则死亡
         */
        void setLive(boolean live){
            this.live = live;
        }
        
        
        private Yard y;
        
        Node n = new Node(15, 15, Dir.L);
        /**
         * 构造方法 
         * @param y
         */
        public Snake(Yard y){
            this.y = y;
            head = n;
            tail = n;
            size++;
        }
        
        /**
         * 将一个结点添加到蛇的链表中
         */
        void addToTail(){
            Node node = null;
            switch (tail.dir) {
            case L:
                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 R:
                node = new Node(tail.row, tail.col-1, 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++;
        }
        
        /**
         * 将一个结点从蛇的尾巴处删除
         */
        void deleteFromTail(){
            if(size == 0) return;
            tail = tail.prev;
            tail.next = null;
            size--;
        }
        
        /**
         * 设置使蛇的位置向前移动一步
         */
        void move(){
            addToHead();
            deleteFromTail();
            checkDead();
        }
        /**
         * 蛇的重画方法
         * @param g
         */
        void draw(Graphics g){
            if(!isLive() || size == 0) {
                return;
            }
            move();
            for(Node node = head ; node != null ; node = node.next){
                node.draw(g);
            }
            
        }
        /**
         * 将一个结点加到蛇链表的头部
         */
        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++;
        }
        
        /**
         * 保存蛇单个结点信息的类
         */
        private class Node{
            int w = Yard.BLOCK_SIZE;
            int h = Yard.BLOCK_SIZE;
            Dir dir = Dir.L;
            int row,col;
            
            Node next = null;
            Node prev = null;
            
            public Node(int row,int col,Dir dir){
                this.row = row;
                this.col = col;
                this.dir = dir;
            }
            //蛇单个节点的画法
            public void draw(Graphics g){
                Color c = g.getColor();
                g.setColor(Color.BLACK);
                g.fillRect(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
                g.setColor(c);
            }
    
        }
        /**
         * 键盘监听
         * @param e
         */
        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_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_DOWN:
                if(head.dir != Dir.U) head.dir = Dir.D;
                break;
            case KeyEvent.VK_F2:
                if(!this.isLive()){
                    y.snake = new Snake(y);
                }
                break;
            }
        }
        
        /**
         * 吃食物
         * @param f
         */
        public void eatFood(Food f){
            if(this.getRect().intersects(f.getRect())){
                f.setPos();
                y.setScore();
                this.addToTail();
            }
        }
        
        /**
         * 通过检测来设置蛇的生死
         */
        public void checkDead(){
            if(head.col < 0 || head.col > Yard.COLS || head.row < 3 || head.row > Yard.ROWS-1){
                setLive(false);
            }
            if(size >= 4){
                for(Node node = head.next;node != null ; node = node.next){
                    if(head.row == node.row && head.col == node.col){
                        setLive(false);
                    }
                }
            }
        }
        
        public Rectangle getRect(){
            return new Rectangle(head.col*Yard.BLOCK_SIZE,head.row*Yard.BLOCK_SIZE,Yard.BLOCK_SIZE,Yard.BLOCK_SIZE);
        }
    }

    吃的食物的类

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.util.Random;
    
    
    public class Food {
        int row,col;
        int h = Yard.BLOCK_SIZE;
        int w = Yard.BLOCK_SIZE;
        private static Random rd = new Random();
        int step = 0;
    
        public Food(int row ,int col) {
            this.row = row;
            this.col = col;
        }
        
        public void draw(Graphics g){
            Color c = g.getColor();
            if(step == 0){
                g.setColor(Color.RED);
                step++;
            }else if(step == 1){
                g.setColor(Color.green);
                step++;
            }else {
                g.setColor(Color.WHITE);
                step = 0;
            }
            
            g.fillOval(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
            g.setColor(c);
        }
        
        public Rectangle getRect(){
            return new Rectangle(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
        }
        
        void setPos(){
            this.row = rd.nextInt(Yard.ROWS-3)+3; 
            this.col = rd.nextInt(Yard.COLS);
        }
    }

    方向的枚举

    public enum Dir {
        L,U,R,D
    }

    主界面的类

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    
    class Yard extends Frame{
        
    
        PaintThread pt = null;
        /**
         * 速度 设置数字越大 越慢
         */
        public static final int SPEED = 4;
        /**
         * 行数
         */
        public static final int ROWS = 30;
        /**
         * 列数
         */
        public static final int COLS = 30;
        /**
         * 行列的宽度
         */
        public static final int BLOCK_SIZE = 15;
        
        /**
         * 在游戏窗口中加入一条蛇
         */
        public Snake snake = new Snake(this);
        
        /**
         * 在游戏窗口中加入一个食物
         */
        public Food food = new Food(10,10);
        
        private Font font = new Font("宋体", Font.BOLD,30 );
        
        private Image offScreenImage = null;
        
        //分数
        private int score = 0;
        
        public int getScore() {
            return score;
        }
    
        public void setScore() {
            this.score += 5;
        }
        
        /**
         * 窗口构建函数
         */
        public void launch(){
    
            pt = new PaintThread();
            this.setLocation(200, 200);
            this.setSize(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
            this.addWindowListener(new WindowAdapter() {
    
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
                
            });
            
            this.setVisible(true);
            this.addKeyListener(new KeyMonitor());
            this.setResizable(false);
            //开始重画线程
            new Thread(pt).start();
            
        }
        
        /**
         * 主方法
         * @param args
         */
        public static void main(String[] args){
             new Yard().launch();
        }
        
        /**
         * 重写的paint方法 用来画出各个元素
         */
        @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.DARK_GRAY);
            
            //画出横线
            for(int i=1; i<ROWS; i++) {
                g.drawLine(0, BLOCK_SIZE * i, COLS * BLOCK_SIZE, BLOCK_SIZE * i);
            }
            for(int i=1; i<COLS; i++) {
                g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);
            }
            
            snake.eatFood(food);
            g.setColor(Color.YELLOW);
            g.drawString("score :" + score, 10, 50);
            food.draw(g);
            
            if(snake.isLive()) {
                snake.draw(g);
            }else{
                g.setColor(Color.YELLOW);
                g.setFont(font);
                g.drawString("Game Over!", 125, 225);
            }
            g.setColor(c);
    
        }
    
        /**
         * 重写的update用来防止屏幕闪烁
         */
        @Override
        public void update(Graphics g) {
    
            if(offScreenImage == null){
                offScreenImage = this.createImage(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
            }
            Graphics graphics = offScreenImage.getGraphics();
            paint(graphics);
    
            g.drawImage(offScreenImage, 0, 0,  null);
        }
        
        /**
         * 重画线程
         */
        private class PaintThread implements Runnable{
            private boolean flag = true;
            
            private boolean pause = false;
            @Override
            public void run() {
                while(flag){
                    if(!pause)
                        repaint();
                    try {
                        Thread.sleep(25*SPEED);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            public void stopPaintThread(){
                flag = !flag;
            }
            
            public void pausePaintThread(){
                pause = !pause;
            }
        }
        
        /**
         * 键盘监听类
         */
        private class KeyMonitor extends KeyAdapter{
    
            @Override
            public void keyPressed(KeyEvent e) {
                int key = e.getKeyCode();
                if(key == KeyEvent.VK_SPACE){
                    pt.pausePaintThread();
                }
                snake.keyPressed(e);
            }
            
        }
    }
  • 相关阅读:
    oracle 存储过程 游标
    SQL DateTime查询与格式
    Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理
    C#命名规范
    (转)javascript——各种网页常用小技巧
    (转)WEB免费打印控件推荐
    JS倒计时代码
    使用重写 ajax 用的一些基础东西
    (转)动态加载CSS
    (转)用Javascript获取页面元素的位置
  • 原文地址:https://www.cnblogs.com/mengxingxinqing/p/3564260.html
Copyright © 2011-2022 走看看