JAVA做贪吃蛇的第二天

java做的贪吃蛇游戏

设计思想

在图形界面上连续摆放相同的图片来表示蛇身和食物,更换图片的位置来代表蛇的移动。

准备

先弄几张图片来做蛇身和食物。为了在放置时可以更方便的使用像素点坐标来表示蛇的位置,所以在准备的时候就把每张图片的像素都定为25×25.这样图片就可以对齐。

封装图片

把图片封装为对象,以更好的调用。
(这里我只放了两个图片的代码,可以自己弄好多图片。)

package Snake;

import javax.swing.*;
import java.net.URL;

/**
 *把图片封装成一个类
 * 这个类用来获取图片
 * @author mahongwei
 */
public class Images {
    /**
     * 将图片的路径封装为对象:****URL
     * 将把路径的图片封装为对象:****Img
     */
    public static URL bodyURL = Images.class.getResource("/image/body.png");
    public static ImageIcon bodyImg = new ImageIcon(bodyURL);

    public static URL foodURL = Images.class.getResource("/image/food.png");
    public static ImageIcon foodImg = new ImageIcon(foodURL);
}

绘制游戏面板

  • 绘制一个800×800像素的JForm。定放置在屏幕中央。
		JFrame jf = new JFrame("Snake Game");
        //获取屏幕宽度、高度:
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        jf.setBounds((width-800)/2,(height-800)/2,800,800);
        //固定窗体大小:
        jf.setResizable(false);
        //关闭窗口的同时,关闭程序:
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jf.setVisible(true);
  • 定义一个GamePanel。

1、放置一个游戏header(为了美观)。

放置时,只要确定该图片的像素坐标,以确保它在合适的位置。

protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setBackground(new Color(189, 182, 182));
        Images.headerImg.paintIcon(this,g,10,10);
}

2、创建一个矩形区域作为游戏区域,改变颜色,让效果更直观。

g.setColor(new Color(154, 183, 191, 255));
        g.fillRect(10,95,764,653);

3、在矩形区域的四周放置“墙”(图片)。放置要求:需要确定墙之内的

//设置四周的墙
        for (int i=3; i<29; i++) {
            Images.wallImg.paintIcon(this, g, 5, 21 + 25 * i);
        }
        for (int i=3; i<29; i++) {
            Images.wallImg.paintIcon(this, g, 755, 21 + 25 * i);
        }
        for (int i=1; i<30; i++) {
            Images.wallImg.paintIcon(this, g, 5 + 25 * i, 96);
        }
        for (int i=1; i<30; i++) {
            Images.wallImg.paintIcon(this, g, 5 + 25 * i, 721);
        }

4、生成静态的小蛇。

用两个数组来存放蛇的位置。(后期可以优化为用链表)

/**
    *定义两个数组,存储蛇的X轴Y轴
    *snakeX[0],snakeX[0]代表蛇头
    */
    int[] snakeX = new int[300];
    int[] snakeY = new int[300];

定义变量来表示蛇头的方向,一方面是为了放置不同蛇头图片,更重要的是为蛇的移动做准备。

/**
     * direction定义蛇头的方向
     */
    String direction;

此时给定蛇的坐标就已经可以绘制静态的蛇了。

5、让蛇移动。

过程就是把倒数第二个身体的坐标给倒数第一个,把倒数第三个身体的坐标给倒数第二个,以此类推。蛇头就依据当前蛇头的方向来选择向哪个方向移动25个像素点。

for (int i = len - 1; i > 0; i--) {
     snakeX[i] = snakeX[i - 1];
     snakeY[i] = snakeY[i - 1];
}
if ("R".equals(direction)) {
     snakeX[0] = snakeX[0] + 25;
}
if ("L".equals(direction)) {
     snakeX[0] = snakeX[0] - 25;
}
if ("U".equals(direction)) {
     snakeY[0] = snakeY[0] - 25;
     }
if ("D".equals(direction)) {
     snakeY[0] = snakeY[0] + 25;
}
//绘制蛇身:这里我用了四张图片,来分别代表蛇的四个不同的方向。
        if ("R".equals(direction)) {
            Images.rightImg.paintIcon(this, g, snakeX[0], snakeY[0]);
        }
        if ("L".equals(direction)) {
            Images.leftImg.paintIcon(this, g, snakeX[0], snakeY[0]);
        }
        if ("U".equals(direction)) {
            Images.upImg.paintIcon(this, g, snakeX[0], snakeY[0]);
        }
        if ("D".equals(direction)) {
            Images.downImg.paintIcon(this, g, snakeX[0], snakeY[0]);
        }
        for (int i = 1; i<len; i++) {
            Images.bodyImg.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

6、下面完成蛇向不同方向的移动。

定义监听事件,来监听键盘按键,并且来改变蛇头方向。(这里做了一个限制,不让蛇直接掉头)

this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                int keyCode = e.getKeyCode();
                //方向键改变蛇头
                if (keyCode == KeyEvent.VK_LEFT) {
                    if (!"R".equals(direction)) {
                        direction = "L";
                    }
                }
                if (keyCode == KeyEvent.VK_RIGHT) {
                    if (!"L".equals(direction)) {
                        direction = "R";
                    }
                }
                if (keyCode == KeyEvent.VK_UP) {
                    if (!"D".equals(direction)) {
                        direction = "U";
                    }
                }
                if (keyCode == KeyEvent.VK_DOWN) {
                    if (!"U".equals(direction)) {
                        direction = "D";
                    }
                }
            }
        });

7、下面就是该生成食物了。

生成食物时要判定不要生成到墙外或者蛇身上。

/**
     * foodX--食物的X坐标
     * foodY--食物的Y坐标
     */
    int foodX,foodY;
/**
     * chonghe 检测食物和蛇身重合
     */
    Random random = new Random();
    boolean chonghe = false;
/**
     * 初始化食物坐标,如果重合就再生成一次。
     */
    public void initFoodXY() {
        do {
            foodX = 30+25 * random.nextInt(29);
            foodY = 121+25 * random.nextInt(24);
            for (int i = 0; i <len; i++) {
                if ( foodX == snakeX[i] && foodY == snakeY[i]) {
                    chonghe = true;
                }
                else {
                    chonghe = false;
                }
            }
        } while (chonghe);
    }
//放置食物
Images.foodImg.paintIcon(this,g,foodX,foodY);

8、检测蛇是否吃到。

就是检测蛇头的坐标是不是和食物重合(相等)。

若相等就蛇长+1,重新生成食物坐标。

if (snakeX[0] == foodX && snakeY[0] == foodY) {
                        initFoodXY();
                        len++;
                    }

因为蛇的移动是倒数第二给倒数第一赋值,,长度+1就会为一个新的变量赋予蛇尾的坐标值。

9、蛇死的判定,撞墙或是撞到自己。

撞到之后暂停游戏,重置位置。该功能的实现需要添加事件监听。

timer = new Timer(150-len, new ActionListener() {
            //事件监听,每delay处理一下
            @Override
            public void actionPerformed(ActionEvent e) {
            }
        }

下面的代码是要放在事件监听里面的

//超出界限
                    if (snakeX[0] == 755
                            ||snakeX[0] == 5
                            ||snakeY[0] ==96
                            ||snakeY[0] ==721) {
                        isStart = false;
                        init();
                    }
                    //碰到身体
                    for (int i = 1; i <len; i++) {
                        if ( snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                            isStart = false;
                            init();
                        }
                    }

创建类GamePanel

GamePanel gp = new GamePanel();
        jf.add(gp);

结尾

这里仅是主要的思想和代码实现。
待优化

  • 用链表代替数组来存放蛇身的坐标。可以加快移动时的处理速度。
  • 蛇身在移动时不重新绘制所有的图片,而是只改变真正移动的图片。

运行界面。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值