GUI 基于Swing制作贪吃蛇小游戏

1 篇文章 0 订阅

启动游戏类

public class StartGame {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("贪吃蛇游戏");
        jFrame.setBounds(10,10,900,720);//框架大小

        jFrame.add(new GamePanel()); //创建游戏面板
        jFrame.setResizable(false); //窗口大小不可变
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);  //窗口关闭监听
        jFrame.setVisible(true);  //设置窗口可以见性,建议在测试类最后设置,以免焦点丢失,导致键盘监听失效
    }
}

游戏画面素材类

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

public class Data{
   public static URL headerURL= Data.class.getResource("statics/header2.png"); //获得头目栏资源地址
   public static ImageIcon header = new ImageIcon(headerURL); //创建头目栏图标

    public static URL bodyURL= Data.class.getResource("statics/body.png"); //获得蛇身体资源地址
    public static ImageIcon body = new ImageIcon(bodyURL);  //创建蛇身体图标

    public static URL upURL= Data.class.getResource("statics/up.png"); //获得蛇头向上资源地址
    public static ImageIcon up = new ImageIcon(upURL);  //创建蛇头向上图标

    public static URL downURL= Data.class.getResource("statics/down.png");  //获得蛇头向下资源地址
    public static ImageIcon down = new ImageIcon(downURL);  //创建蛇头向下图标

    public static URL leftURL= Data.class.getResource("statics/left.png");  //获得蛇头向左资源地址
    public static ImageIcon left = new ImageIcon(leftURL);   //创建蛇头向左图标

    public static URL rightURL= Data.class.getResource("statics/right.png");  //获得蛇头向右资源地址
    public static ImageIcon right = new ImageIcon(rightURL);  //创建蛇头向右图标

    public static URL foodURL= Data.class.getResource("statics/food.png");  //获得食物资源地址
    public static ImageIcon food = new ImageIcon(foodURL);  //创建食物图标

}

游戏面板类

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
/*总思路:
1.创建状态变量
2.利用画笔,“画”到游戏面板
3.编写监听事件或键盘监听
 */
public class GamePanel extends JPanel implements KeyListener , ActionListener {
    int length;  //蛇的长度
    boolean isStart;  //游戏是否开始
    int[] x = new int[100]; //头部和身体坐标
    int[] y = new int[100];
    int foodx;  //食物坐标
    int foody;
    Random random = new Random(); //生成随机数,为食物坐标
    String des ;//蛇头方向
    boolean isFail;  //游戏是否失败
    int score;  //分数
    Timer timer = new Timer(100,this);  //创建定时器

    public void init(){   //初始化方法
        x[0] = 100;  //蛇初始状态
        y[0] = 100;
        x[1] = 75;
        y[1] = 100;
        x[2] = 50;
        y[2] = 100;
        length = 3;     //初始长度
        isStart = false;  //默认初始游戏状态关
        isFail = false;  //默认初始状态为非失败
        des = "R";  //默认蛇头向右
        score = 0;  //初始分数为0
        foodx = 25 + random.nextInt(34) * 25; //食物初始位置
        foody = 75 + random.nextInt(24) * 25;
        timer.start();  //定时器记时开始
    }

    public GamePanel(){   //构造体
        init(); //调用初始化方法
        this.setFocusable(true);  //设置焦点
        this.addKeyListener(this); //添加键盘监听
    }

    @Override
    protected void paintComponent(Graphics g) {  //画笔
        super.paintComponent(g);    //清屏
        this.setBackground(Color.white);   //面板背景色
        Data.header.paintIcon(this,g,25,11); //画头目栏
        g.fillRect(25,75,850,600);  //创建矩形游戏空间
        if (des.equals("R")){      //根据方向,画蛇头
            Data.right.paintIcon(this,g,x[0],y[0]);
        }else if (des.equals("L")){
            Data.left.paintIcon(this,g,x[0],y[0]);
        }else if (des.equals("U")){
            Data.up.paintIcon(this,g,x[0],y[0]);
        }else if (des.equals("D")){
            Data.down.paintIcon(this,g,x[0],y[0]);
        }

        for (int i = 1; i < length; i++) {  //画身体
            Data.body.paintIcon(this,g,x[i],y[i]);
        }
        Data.food.paintIcon(this,g,foodx,foody);  //画食物
        g.setColor(Color.white); //画分数
        g.setFont(new Font("微软雅黑",Font.BOLD,18)); //画长度和分数
        g.drawString("长度"+length,750,35);
        g.drawString("分数"+score,750,50);

        if (!isStart){    //画游戏未开始画面
            g.setColor(Color.white);
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            g.drawString("按下空格开始游戏",300,300);
        }
        if (isFail){   //画失败画面
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            g.drawString("失败,按下空格重新开始",300,300);
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {   //键盘监听事件
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_SPACE ) {  //按下空格键监听
            if (isFail){     //若游戏失败,游戏重新开始
                isFail = false;   //ifFail值改变
                init();   //初始化
            }
            else {
                isStart = !isStart;  //否则,游戏开始与暂停切换
            }
            repaint();  //重画
        }

        if (keyCode == KeyEvent.VK_UP){  //按下方向键改变蛇头方法
            des = "U";
        }else if (keyCode == KeyEvent.VK_DOWN){
            des = "D";
        }else if (keyCode == KeyEvent.VK_LEFT){
            des = "L";
        }else if (keyCode == KeyEvent.VK_RIGHT){
            des = "R";
        }
    }

    public void actionPerformed(ActionEvent e) {   //事件监听事件
        if(isStart && !isFail) {  //如果游戏为开始状态且未失败事件,让小蛇动起来
            for (int i = length - 1; i > 0; i--) { //身体改变
                x[i] = x[i - 1];
                y[i] = y[i - 1];
            }
            if (des.equals("R")) { //根据蛇头方向,改变蛇头位置
                x[0] = x[0] + 25;
                if (x[0] > 850) {
                    x[0] = 0;
                }
            }else if (des.equals("L")){
                x[0] = x[0] - 25;
                if (x[0]<25){
                    x[0] = 850;
                }
            }else if (des.equals("U")){
                y[0] = y[0] - 25;
                if (y[0] < 75){
                    y[0] = 650;
                }
            }else if (des.equals("D")){
                y[0] = y[0] + 25;
                if (y[0] > 650){
                    y[0] = 75;
                }
            }

            if (foodx == x[0] && foody == y[0] ){  //吃到食物事件
                length++;
                score = score + 10;
                foodx = 25 + 25 * random.nextInt(34);
                foody = 75 + 25 * random.nextInt(24);
            }
            repaint();  //重画
        }
        for (int i = 1; i < length; i++) {  //判断游戏失败事件
            if (x[0] == x[i] && y[0] == y[i]){
                isFail = true;
            }
        }
        timer.start(); //定时器开启
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

}

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值