Java-贪吃蛇游戏

前言

此实现较为简陋,如有错误请指正。
其次代码中的图片需要自行添加地址并修改。

主类

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

游戏类

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;
import java.util.Timer;

public class myGame extends JFrame implements KeyListener {

    private int[] foodPos; // 食物位置坐标
    private List<int[]> coordinateS;    // 总地址
    private int score = 0;   // 玩家得分
    private Random random;
    private final String cell = "img/cell.png";  //格子地址
    private int keyCode = -1;

    public myGame() {
        random = new Random();
        foodPos = new int[]{-1, -1};   // 初始化为-1
        // 创建一个定时器
        Timer gameTimer = new Timer();
        // 设置定时器
        gameTimer.schedule(new timer(), 0, 200);

        InitCoordinate();   // 初始化格子地址
        InitJFrame();       // 初始化窗体
        LoadPicture();      // 加载图片
    }

    // 初始化地址
    private void InitCoordinate() {
        coordinateS = new ArrayList<>();
        coordinateS.add(new int[]{200, 200});
        coordinateS.add(new int[]{200, 200});
        this.getContentPane().removeAll();  // 清空图片显示
    }

    // 加载图片
    public void LoadPicture() {
        this.getContentPane().removeAll();  // 清空图片显示

        // 目前得分展示
        JLabel scoreTips = new JLabel("目前得分:" + score);
        scoreTips.setBounds(500, 10, 100, 20);
        this.getContentPane().add(scoreTips);

        // 提示
        JLabel Tips = new JLabel("<html> 按下任意方向键 <br><br> 即开始游戏 </html>");
        Tips.setBounds(500, 100, 100, 60);
        Tips.setVerticalTextPosition(1);
        this.getContentPane().add(Tips);

        // 上
        for (int i = 0, x = 0; i < 25; i++, x += 20) {
            JLabel upImg = new JLabel(new ImageIcon(cell));  // 获取图片对象
            upImg.setBounds(x, 0, 20, 20); // 设置图片位置与宽高
            this.getContentPane().add(upImg);       // 将图片添加到窗口中
        }
        // 左
        for (int i = 0, y = 20; i < 21; i++, y += 20) {
            JLabel upImg = new JLabel(new ImageIcon(cell));  // 获取图片对象
            upImg.setBounds(0, y, 20, 20); // 设置图片位置与宽高
            this.getContentPane().add(upImg);       // 将图片添加到窗口中
        }
        //右
        for (int i = 0, y = 20; i < 21; i++, y += 20) {
            JLabel upImg = new JLabel(new ImageIcon(cell));  // 获取图片对象
            upImg.setBounds(480, y, 20, 20); // 设置图片位置与宽高
            this.getContentPane().add(upImg);       // 将图片添加到窗口中
        }
        // 下
        for (int i = 0, x = 0; i < 25; i++, x += 20) {
            JLabel upImg = new JLabel(new ImageIcon(cell));  // 获取图片对象
            upImg.setBounds(x, 440, 20, 20); // 设置图片位置与宽高
            this.getContentPane().add(upImg);       // 将图片添加到窗口中
        }

        // 显示 “ 蛇 ”
        for (int i = 0, n = coordinateS.size(); i < n; ++i) {
            int[] data = coordinateS.get(i);
            JLabel CellImg = new JLabel(new ImageIcon(cell));  // 获取图片对象
            CellImg.setBounds(data[0], data[1], 10, 10); // 设置图片位置与宽高
            this.getContentPane().add(CellImg);       // 将图片添加到窗口中
        }

        // 设置 “ 食物 ” 位置
        if (foodPos[0] != -1 && foodPos[1] != -1) {
            JLabel TargetImg = new JLabel(new ImageIcon("img/targetCell.png"));  // 获取图片对象
            TargetImg.setBounds(foodPos[0], foodPos[1], 10, 10); // 设置图片位置与宽高
            this.getContentPane().add(TargetImg);       // 将图片添加到窗口中
        }
        this.getContentPane().repaint();    // 刷新窗口显示
    }

    // 初始化窗体
    private void InitJFrame() {
        this.setSize(620, 507);  // 设置大小
        this.setAlwaysOnTop(true);          // 顶层显示方法
        this.setLocationRelativeTo(null);   // 将窗口位置设置为屏幕中心
        this.addKeyListener(this);      // 为窗口设置键盘监听
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);  //设置关闭模式
        this.setVisible(true);            //设置为显示
    }

    @Override
    public void keyTyped(KeyEvent e) {}     // 按键按下立即执行

    @Override
    public void keyReleased(KeyEvent e) {}  // 按键被释放时生效

     /*按键被按下时执行*/
    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();  // 获取刚才按下的按键
        if (!(code >= 37 && code <= 40)) { return; }    // 排除非方向键的操作
        this.keyCode = -1;  // 关闭定时器
        this.keyCode = Key_Detection(code); // 重新赋值
    }

    // 按键操作
    private int Key_Detection(int code) {
        // 获取当前位置坐标
        int[] curCoordinate = coordinateS.get(0);
        /* 上 */
        if (38 == code && curCoordinate[1] != 20) { curCoordinate[1] -= 10; }
        /* 下 */
        else if (40 == code && curCoordinate[1] != 430) { curCoordinate[1] += 10; }
        /* 左 */
        else if (37 == code && curCoordinate[0] != 20) { curCoordinate[0] -= 10; }
        /* 右 */
        else if (39 == code && curCoordinate[0] != 470) { curCoordinate[0] += 10; }
        else { gameOver(); }    // 撞墙了,游戏结束

        // 当方块与目标方块重合时
        if (curCoordinate[0] == foodPos[0] && curCoordinate[1] == foodPos[1]) {
            ++score;
            foodPos[0] = -1;
            foodPos[1] = -1;
            // 尾部新增
            int[] tail = coordinateS.get(coordinateS.size() - 1);
            coordinateS.add(Arrays.copyOf(tail, tail.length));
        }

        if (foodPos[0] == -1 && foodPos[1] == -1) {
            int x = random.nextInt(420) + 20;
            int y = random.nextInt(400) + 20;
            foodPos[0] = x - (x % 10);
            foodPos[1] = y - (y % 10);
        }

        for (int i = 1, n = coordinateS.size(); i < n; i++) {
            int[] curPos = coordinateS.get(i);
            // 判断当前位置是否与身体格子重合
            if (curCoordinate[0] == curPos[0] && curCoordinate[1] == curPos[1]) {
                code = -1;
                gameOver();
                break;
            }
        }
        Refresh_coordinateS();
        LoadPicture();  //刷新图片
        return code;
    }

    // 游戏结束
    private void gameOver() {
        // 结束消息提醒
        JOptionPane.showMessageDialog(this, "游戏结束!\n 总计得分为:" + score + "分");
        score = 0;
        foodPos[0] = -1;
        foodPos[1] = -1;
        keyCode = -1;
        InitCoordinate();   // 初始化地址
    }

    // 刷新格子操作
    public void Refresh_coordinateS() {
        for (int i = coordinateS.size() - 1; i > 0; --i) {
            int[] cur = coordinateS.get(i);
            int[] pre = coordinateS.get(i - 1);
            cur[0] = pre[0];
            cur[1] = pre[1];
        }
    }

    // 定时器类
    class timer extends TimerTask {
        @Override
        public void run() {
            if (keyCode == -1) {
                return;
            }
            Key_Detection(keyCode);
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值