java实现贪吃蛇

准备工作

  1. 理解GUI图形化界面操作
  2. 理解面向对象
  3. 理解数组使用
  4. 理解随机数的使用
  5. 理解定时器的使用
  6. 理解将图片转化为流对象

代码实现

  • 图片工具类
public class GetImage {
	//静态属性获取蛇的上下左右,头,身体,食物的图片的BufferedImage对象
    static BufferedImage right=GetImage.GetImg("/image/right.png");
    static BufferedImage left=GetImage.GetImg("/image/left.png");
    static BufferedImage down=GetImage.GetImg("/image/down.png");
    static BufferedImage up=GetImage.GetImg("/image/up.png");
    static BufferedImage header=GetImage.GetImg("/image/header.png");
    static BufferedImage body=GetImage.GetImg("/image/body.png");
    static BufferedImage food=GetImage.GetImg("/image/food.png");
	
	//静态方法加载图片转化为BufferedImage对象
    public static BufferedImage GetImg(String path){


        BufferedImage img;
        try {
			//加载图片路径
            img=ImageIO.read(GetImage.class.getResource(path));
			//返回结果
            return img;
        } catch (IOException e) {
            e.printStackTrace();
        }
		//如果路径错误,返回为null
        return null;
    }
}
  • 面板类
public class GameJPanel extends JPanel {
    //定义小蛇的初始长度
    int length;
    //定义小蛇的X轴坐标
    int[] snakeX = new int[100];
    //定义小蛇的Y轴坐标
    int[] snakeY = new int[100];
    //定义游戏开始
    boolean isStart = false;


    //定义头部背景图片
    BufferedImage header;
    //定义小蛇的头部图片
    BufferedImage right;
    BufferedImage left;
    BufferedImage down;
    BufferedImage up;
    //定义小蛇的身体图片
    BufferedImage body;
    //定义小蛇的方向
    String direction = "R";
    //定义食物的X坐标
    int foolX;
    //定义食物的Y坐标
    int foolY;
    //定义一个记分板
    int score;
    //定义定时器
    Timer timer;
    //定义小蛇是否死亡
    boolean isDie = false;

    public GameJPanel() {
		//初始化面板
        init();
        //将焦点置为面板
        setFocusable(true);
        //设置监听器监听键盘按钮
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
				//获取键盘的key值
                char c = e.getKeyChar();

                if (c == KeyEvent.VK_SPACE) {

                        if (isDie) {
                            //如果小蛇死了,初始化界面,小蛇状态改变
                            init();
                            score = 0;
                            isDie = false;
                        }else {
							//否则游戏开始
                            isStart = !isStart;
                        }

						//重复重绘画面(动的效果)
                        repaint();
                }
                if (isStart){
					//如果游戏开始,监听键盘按钮是哪个方向移动小蛇
                    if (c == 119) {
                        direction = "U";
                    }
                    if (c == 115) {
                        direction = "D";
                    }
                    if (c == 97) {
                        direction = "L";
                    }
                    if (c == 100) {
                        direction = "R";
                    }
                }

            }
        });
        //每隔0.15秒做一次actionPerformed(定时器,小蛇移动)
        timer = new Timer(150, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                //当游戏开始
                if (isStart && isDie == false) {
                    //身体先动
                    for (int i = length - 1; i > 0; i--) {
                        snakeX[i] = snakeX[i - 1];
                        snakeY[i] = snakeY[i - 1];
                    }
                    //头部动
                    if (direction.equals("R")) {
                        snakeX[0] += 25;

                    }
                    if (direction.equals("U")) {
                        snakeY[0] -= 25;
                    }
                    if (direction.equals("L")) {
                        snakeX[0] -= 25;
                    }
                    if (direction.equals("D")) {
                        snakeY[0] += 25;
                    }
                    //防止小蛇跑出边界
                    //右边界
                    if (snakeX[0] > 750) {
                        snakeX[0] = 25;
                    }
                    //下边界
                    if (snakeY[0] > 725) {
                        snakeY[0] = 100;
                        //左边界
                    }
                    if (snakeX[0] < 25) {
                        snakeX[0] = 750;
                        //上边界
                    }
                    if (snakeY[0] < 100) {
                        snakeY[0] = 725;
                    }
                    //如果小蛇碰到自己任何一节身体,则死亡
                    for (int i = 1; i < length; i++) {
                        if (snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0]) {
                            isDie = true;


                        }
                    }
                    if (snakeX[0] == foolX && snakeY[0] == foolY) {
                        //每吃一个食物蛇长度加一
                        length++;
                        //随机食物出现的位置
                        int X = 25 + 25 * (new Random().nextInt(28));
                        int Y = 100 + 25 * (new Random().nextInt(25));
                        foolX = X;
                        foolY = Y;
						//通过判断长度判断当前分数
                        score = (length - 3) * 10;

                    }

                    //重新绘制图像
                    repaint();
                }
            }
        });
        //调用定时器启动
        timer.start();
    }

    public void init() {
        //初始化背景、蛇和食物的位置
        length = 3;
        snakeX[0] = 250;
        snakeY[0] = 375;

        snakeX[1] = 225;
        snakeY[1] = 375;

        snakeX[2] = 200;
        snakeY[2] = 375;
        //设置面板背景图片
        setBackground(new Color(0x226C6F));
        //设置食物初始坐标

        foolX = 325;
        foolY = 300;
        //初始化游戏为暂停
        isStart = false;
        //初始化游戏向右方向
        direction="R";
    }

	//画板方法
    @Override
    public void paint(Graphics g) {
        //添加画板
        super.paint(g);
        g.drawImage(GetImage.food, foolX, foolY, null);
        //将头部背景图片画入
        g.drawImage(GetImage.header, 10, 10, null);
        //将小蛇头部画入
        if (direction.equals("R")) {
            g.drawImage(GetImage.right, snakeX[0], snakeY[0], null);
        }
        if (direction.equals("L")) {
            g.drawImage(GetImage.left, snakeX[0], snakeY[0], null);
        }
        if (direction.equals("U")) {
            g.drawImage(GetImage.up, snakeX[0], snakeY[0], null);
        }
        if (direction.equals("D")) {
            g.drawImage(GetImage.down, snakeX[0], snakeY[0], null);
        }

        //将小蛇身体画入
        for (int i = 1; i < length; i++) {
            g.drawImage(GetImage.body, snakeX[i], snakeY[i], null);
        }
        //设置当游戏开始或者暂停时出现画面
        if (isStart == false) {
            g.setColor(new Color(0x894D14));
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("点击空格开始或者暂停", 200, 300);
        }
        //设置积分数
        g.setColor(new Color(0xFFFFFF));
        g.setFont(new Font("微软雅黑", Font.BOLD, 20));
        g.drawString("积分:   " + score, 620, 40);
        if (isDie) {
            //如果小蛇死亡,则出现死亡画面
            g.setColor(new Color(0xFF3DFD));
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("游戏结束,请重新按空格进行游戏", 100, 400);
        }
    }
}
  • 窗体和启动入口
public class GameJFrame extends JFrame{
	
	//构造方法中设置一些属性
    public GameJFrame(){
		//设置窗体标题
        setTitle("贪吃蛇小游戏");
		//设置窗体不能改变大小
        setResizable(false);
		//获取当前电脑的屏幕的宽度
        int width=Toolkit.getDefaultToolkit().getScreenSize().width;
		//获取当前电脑的屏幕的高度
        int height=Toolkit.getDefaultToolkit().getScreenSize().height;
		//设置窗体的大小(x轴,y轴,宽度,高度)
        setBounds((width-800)/2,(height-800)/2,800,800);
		//设置窗体关闭按钮结束程序
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        //创建一个窗体:
        GameJFrame frame=new GameJFrame();
		//创建一个面板:
        GameJPanel panel=new GameJPanel();
		//将面板添加到窗体中
        frame.add(panel);
		//设置窗体可见
        frame.setVisible(true);
    }
}

图片素材

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值