简易贪吃蛇小游戏java版

package com.java20180917.snake;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.LinkedList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * 1.初始化界面 2.初始化面板 3.面板与界面合并
 * 
 * @author Xiaolei
 *
 */
public class Main extends JFrame implements KeyListener {
    private static final long serialVersionUID = -1803858577233572276L;
    private JPanel jp = null;
    private int fw = 600;
    private int fh = 600;

    private int count = 4;
    private int b_size=20;
    private int se_size = 20;
    private int se_x = 100;
    private int se_y = 200;
    private LinkedList<SE> snake = new LinkedList<SE>();
    private String direction = Constant.UP;
    private String tip = "";
    private String status = "";
    private long speed = 300;
    // 豆子初始化
    private LinkedList<Bean> b = new LinkedList<Bean>();
    
    private int Score;
    
    // 总初始化方法
    private void init() {
        initSnake();
        initPanel();
        initFrame();
        initBean();
        initThread();
    }

    private void initBean() {
        // 返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
        int b_x = 20 * Math.round((new Random().nextInt(30)));
        int b_y = 20 * Math.round((new Random().nextInt(30)));
        //如果蛇的列表中不包含豆子的位置                        如果此列表包含指定元素,则返回 true。
        if(!(snake.contains(new SE(b_size, b_x, b_y)))) {
            b.add(new Bean(b_x, b_y, b_size));
        }

    }

    // 如果方面符合条件,就触发该方法,弹出窗口
    private void popup() {
        tip = Constant.TIP;
        status = Constant.STOP;
        int op_result = JOptionPane.showConfirmDialog(jp, "GAME OVER!", "你挂了!", JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.ERROR_MESSAGE);
        if (op_result == 0) {
            // 重新开始游戏
            // 让蛇的运动条件重新开始
            status = "";
            // 把蛇的链表集合清空掉
            snake.clear();
            // 把Game Over字体清空。
            tip = "";
            // 让方块重新向上跑
            direction = Constant.UP;
            // 重新调用方块,初始化蛇
            initSnake();
            speed=300;
            Score=0;
        }
        if (op_result == 2) {
            System.exit(0);
        }
    }

    private void initThread() {
        // 添加线程,让方块跟着键盘的指定方面运动
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if ("".equalsIgnoreCase(status)) {
                        if (snake.getFirst().getSe_x() == b.getFirst().getB_x()
                                && snake.getFirst().getSe_y() == b.getFirst().getB_y()) {
                            //吃掉一个豆子,就把原来的豆子清掉,重新在创建一个豆子
                            b.clear();
                            //新建一个豆子
                            
                            //在蛇方块的尾部增加一个方块
                            snake.add(new SE(se_size, snake.getLast().getSe_x(), snake.getLast().getSe_y()));
                            initBean();
                            Score++;
//                            加速
                            if(Score==5) {
                                speed-=100;
                            }
                            else if(Score==15) {
                                speed-=150;
                            }
                            else if(Score==25) {
                                speed-=200;
                            }
                            
                        }
                        
                        // 判断是否咬到自己(即头部坐标与身体上的任何一个元素的坐标重合)
                        for (int i = 1; i < snake.size(); i++) {
                            if (snake.getFirst().getSe_x() == snake.get(i).getSe_x()
                                    && snake.getFirst().getSe_y() == snake.get(i).getSe_y()) {
                                popup();
                            }
                        }
                        // 操作snake容器中的元素
                        // 移除最后一个
                        snake.removeLast();
                        // 添加一个到头部
                        // 让方块往上走
                        if (direction.equalsIgnoreCase(Constant.UP)) {
                            // 如果新的头部y的坐标出界,提示game over
                            if (snake.getFirst().getSe_y() - se_size < 0) {
                                popup();
                            }
                            //在蛇方块的头部加一个蛇方块
                            snake.addFirst(
                                    new SE(se_size, snake.getFirst().getSe_x(), snake.getFirst().getSe_y() - se_size));
                        }
                        // 让方块往下走
                        if (direction.equalsIgnoreCase(Constant.Down)) {
                            //蛇方块的坐标从左上角开始计算
                            //如果蛇的头部的位置+自身的大小大于窗口总宽度就结束游戏
                            if (snake.getFirst().getSe_y() + se_size > fh) {
                                popup();
                            }
                            snake.addFirst(
                                    new SE(se_size, snake.getFirst().getSe_x(), snake.getFirst().getSe_y() + se_size));
                        }
                        // 让方块往左走
                        if (direction.equalsIgnoreCase(Constant.LEFT)) {
                            // 如果方面的头碰到墙壁就结束游戏,弹窗
                            if (snake.getFirst().getSe_x() - se_size < 0) {
                                popup();
                            }
                            snake.addFirst(
                                    new SE(se_size, snake.getFirst().getSe_x() - se_size, snake.getFirst().getSe_y()));
                        }
                        // 让方块往右走
                        if (direction.equalsIgnoreCase(Constant.RIGHT)) {
                            if (snake.getFirst().getSe_x() + se_size > fw) {
                                popup();
                            }
                            snake.addFirst(
                                    new SE(se_size, snake.getFirst().getSe_x() + se_size, snake.getFirst().getSe_y()));
                        }
                        // 方块动起来后,重画填充
                        jp.repaint();
                        try {
                            Thread.sleep(speed);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

    private void initSnake() {
        // 创建多个有关联着的SE
        // 添加到snake容器中
        for (int i = 0; i < count; i++) {
            snake.add(new SE(se_size, se_x, se_y + se_size * i));
        }
    }

    private void initPanel() {
        jp = new JPanel() {
            private static final long serialVersionUID = 1L;

            // 在面板中填充方块的初始位置和颜色
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                if (!"".equals(tip)) {
                    g.setColor(Color.red);
                    g.setFont(new Font("", Font.BOLD, 40));
                    g.drawString(tip, 160, 160);
                }
                // 初始化豆子
                for (int i = 0; i < b.size(); i++) {
                    g.setColor(Color.YELLOW);
                    g.fillRect(b.get(i).getB_x(), b.get(i).getB_y(), b.get(i).getB_size(), b.get(i).getB_size());
                }
                for (int i = 0; i < snake.size(); i++) {
                    if (i == 0) {
                        g.setColor(Color.GRAY);
                    } else {
                        g.setColor(Color.BLUE);
                    }
                    g.fill3DRect(snake.get(i).getSe_x(), snake.get(i).getSe_y(), snake.get(i).getSe_size(),
                            snake.get(i).getSe_size(), true);
                }
                Integer a = new Integer(Score);
                g.setColor(Color.ORANGE);
                g.setFont(new Font("", Font.BOLD, 30));
                g.drawString("成绩:"+a.toString(), 460, 50);
            }
        };
        // 设置透明度
        jp.setOpaque(false);
    }

    private void initFrame() {
        // 设置窗口标题
        this.setTitle("测试");
        // 设置窗口大小
        this.setSize(fw, fh);
        // 设置窗口背景颜色
        this.getContentPane().setBackground(Color.black);
//        禁用或启用此框架的装饰。
        this.setUndecorated(true);
        // 把面板放到窗口上
        this.add(jp);
        // 设置窗口可见
        this.setVisible(true);
        // 当前对象具有多重身份 (这是由继承结构决定的)
        // 第一个this --- 窗口对象
        // 第二个this --- 键盘监听器
        this.addKeyListener(this);
        // 把窗口设置在指定的位置
        this.setLocationRelativeTo(null);
    }

    public Main() {
        init();
    }

    public static void main(String[] args) {
        new Main();
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // 按下按一个按键 停止虚拟机运行
//        System.out.println(e.getKeyCode());
        // 按下esc键 关停虚拟机

        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
        }
        // 获取键盘值的上下左右,赋于我的当前对象
        if (!this.direction.equalsIgnoreCase(Constant.LEFT) && e.getKeyCode() == KeyEvent.VK_RIGHT) {
            this.direction = Constant.RIGHT;
        }
        if (!this.direction.equalsIgnoreCase(Constant.RIGHT) && e.getKeyCode() == KeyEvent.VK_LEFT) {
            this.direction = Constant.LEFT;
        }
        if (!this.direction.equalsIgnoreCase(Constant.UP) && e.getKeyCode() == KeyEvent.VK_DOWN) {
            this.direction = Constant.Down;
        }
        if (!this.direction.equalsIgnoreCase(Constant.Down) && e.getKeyCode() == KeyEvent.VK_UP) {
            this.direction = Constant.UP;
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            // 先检查status的值 如果是 "" 就修改成 pause 如果是 pause 就改成 ""
            switch (status) {
            case Constant.PAUSE:
                this.status = "";
                break;
            case "":
                this.status = Constant.PAUSE;
                break;
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

接口:

package com.java20180917.snake;
/**
 * 常量接口
 * @author Xiaolei
 *
 */
public interface Constant {
    /**
     *方向常量
     */
    public static final String UP = "up";
    public static final String Down = "down";
    public static final String LEFT = "left";
    public static final String RIGHT = "right";
    public static final String TIP = "GAME OVER !";
    public static final String STOP = "stop";//停止
    public static final String PAUSE = "pause";//暂停
}
 

蛇类:

package com.java20180917.snake;

import java.io.Serializable;
/**
 * 蛇身体关节元素  实体类
 * @author Xiaolei
 *
 */
public class SE implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 4103030147063529932L;
    private int se_size;
    private int se_x;
    private int se_y;
    public SE(int se_size, int se_x, int se_y) {
        super();
        this.se_size = se_size;
        this.se_x = se_x;
        this.se_y = se_y;
    }
    public SE() {
        super();
        // TODO Auto-generated constructor stub
    }
    public int getSe_size() {
        return se_size;
    }
    public void setSe_size(int se_size) {
        this.se_size = se_size;
    }
    public int getSe_x() {
        return se_x;
    }
    public void setSe_x(int se_x) {
        this.se_x = se_x;
    }
    public int getSe_y() {
        return se_y;
    }
    public void setSe_y(int se_y) {
        this.se_y = se_y;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
    @Override
    public String toString() {
        return "SE [se_size=" + se_size + ", se_x=" + se_x + ", se_y=" + se_y + "]";
    }
    
    
}

豆子类:

package com.java20180917.snake;


public class Bean {
    private int b_x;
    private int b_y;
    private int b_size;
    public Bean() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Bean(int b_x, int b_y, int b_size) {
        super();
        this.b_x = b_x;
        this.b_y = b_y;
        this.b_size = b_size;
    }
    public int getB_x() {
        return b_x;
    }
    public void setB_x(int b_x) {
        this.b_x = b_x;
    }
    public int getB_y() {
        return b_y;
    }
    public void setB_y(int b_y) {
        this.b_y = b_y;
    }
    public int getB_size() {
        return b_size;
    }
    public void setB_size(int b_size) {
        this.b_size = b_size;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + b_size;
        result = prime * result + b_x;
        result = prime * result + b_y;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Bean other = (Bean) obj;
        if (b_size != other.b_size)
            return false;
        if (b_x != other.b_x)
            return false;
        if (b_y != other.b_y)
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Bean [b_x=" + b_x + ", b_y=" + b_y + ", b_size=" + b_size + "]";
    }
    
}
 

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值