使用Java的GUI技术实现 “ 贪吃蛇 ” 游戏

 

目录

 一、StartFrame 主类编写( main方法所在的类),

二、MyData 数据文件类编写(项目所需要用到的图片等其他的一些资源)

 三、GamePanel 游戏面板类编写


项目结构:

 一、StartFrame 主类编写( main方法所在的类),

package com.sfy.greedySnake;

import javax.swing.*;
import java.awt.*;

//游戏开始窗口
public class StartFrame extends JFrame {
    public static void main(String[] args) {
         new StartFrame("贪吃蛇游戏");
    }

    public StartFrame(String title){
        super(title);

        this.setBounds(100,100,900,700);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setResizable(false);
        Container container = this.getContentPane();
        container.setBackground(Color.WHITE);

        GamePanel gamePanel = new GamePanel(); //实例化游戏面板
        container.add(gamePanel);
    }
}

二、MyData 数据文件类编写(项目所需要用到的图片等其他的一些资源)

package com.sfy.greedySnake;

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

//图片数据
public class MyData {
    //广告栏header
    private static final URL HEADER = MyData.class.getResource("./static/header.jpg");
    public static Icon header = new ImageIcon(HEADER);

    //头
    private static final URL UP = MyData.class.getResource("./static/up.png");
    public static Icon up = new ImageIcon(UP);
    private static final URL DOWN = MyData.class.getResource("./static/down.png");
    public static Icon down = new ImageIcon(DOWN);
    private static final URL LEFT = MyData.class.getResource("./static/left.png");
    public static Icon left = new ImageIcon(LEFT);
    private static final URL RIGHT = MyData.class.getResource("./static/right.png");
    public static Icon right = new ImageIcon(RIGHT);

    //身体
    private static final URL BODY = MyData.class.getResource("./static/body.png");
    public static Icon body = new ImageIcon(BODY);

    //食物
    private static final URL FOOD = MyData.class.getResource("./static/food.png");
    public static Icon food = new ImageIcon(FOOD);

    private MyData() {
    }
}

 三、GamePanel 游戏面板类编写

package com.sfy.greedySnake;

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;

//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    private int length; //蛇长度
    private int score; //分数

    //蛇坐标
    private int[] snakeX = new int[600]; //小蛇X轴
    private int[] snakeY = new int[400]; //小蛇Y轴

    //食物坐标
    private int foodX; //食物X轴坐标
    private int foodY; //食物Y轴坐标
    Random random = new Random();//随机数类

    //游戏状态
    private boolean isStart; //是否开始
    private boolean isFail;  //是否失败

    private String direction; //蛇头方向

    Timer timer = new Timer(100,this); //计时器

    public GamePanel() {
        this.setFocusable(true); //获取焦点
        this.addKeyListener(this);
        timer.start(); //启动计时器
        init(); //调用初始化方法
    }

    //面板初始化
    public void init(){
        length = 3; //初始化蛇长度
        score = 0; //初始化分数

        //游戏状态初始化
        isStart = false; //true 开始 false 停止
        isFail = false; //true 失败 false 未失败

        direction = "R"; //初始化蛇头方向 R右

        //初始化蛇坐标
        snakeX[0] = 100; snakeY[0] = 125;
        snakeX[1] = 75; snakeY[1] = 125;
        snakeX[2] = 50; snakeY[2] = 125;

        //初始化食物food坐标
        foodX = 25 + 25 * random.nextInt(34);
        foodY = 100 + 25 * random.nextInt(22);
    }

    //画图
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        //画广告栏 header
        MyData.header.paintIcon(this,g,25,25);

        //画背景
        g.fillRect(25,100,850,550);

        //画头
        switch (direction){
            case "U": MyData.up.paintIcon(this,g,snakeX[0],snakeY[0]); break;
            case "D": MyData.down.paintIcon(this,g,snakeX[0],snakeY[0]); break;
            case "L": MyData.left.paintIcon(this,g,snakeX[0],snakeY[0]); break;
            case "R": MyData.right.paintIcon(this,g,snakeX[0],snakeY[0]); break;
        }

        //画身体
        for (int i = 1; i < length; i++) {
            MyData.body.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        //画暂停文字
        if(!isStart && !isFail){
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("点击空格开始游戏",300,300);
        }

        //画失败文字
        if(isFail){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("游戏失败!点击空格重新开始",180,300);
            g.setFont(new Font("微软雅黑", Font.BOLD,35));
            g.setColor(Color.GREEN);
            g.drawString("最终长度:" + length,340,370);
            g.drawString("最终得分:" + score,340,420);
        }

        //画食物food
        MyData.food.paintIcon(this,g,foodX,foodY);

        //画分数和长度
        g.setFont(new Font("微软雅黑",Font.BOLD,16));
        g.setColor(Color.WHITE);
        g.drawString("长度:" + length,780,47); //长度
        g.drawString("分数:" + score,780,67); //分数

        repaint(); //重绘

    }

    //键盘按下监听事件
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_SPACE){
            if(isFail){
                init(); //初始化 重新开始
            }else{
                isStart = !isStart; //暂停
            }
        }

        //监听方向键上下左右
        if(isStart){
            switch (e.getKeyCode()){
                case KeyEvent.VK_UP: direction="U"; break;
                case KeyEvent.VK_DOWN: direction="D"; break;
                case KeyEvent.VK_LEFT: direction="L"; break;
                case KeyEvent.VK_RIGHT: direction="R"; break;
            }
        }

        repaint(); //重绘
    }

    @Override
    public void keyTyped(KeyEvent e) {}
    @Override
    public void keyReleased(KeyEvent e) {}

    //动作监听
    @Override
    public void actionPerformed(ActionEvent e) {
        if(isStart && !isFail){
            //小蛇移动
            for (int i = length-1; i > 0; i--) {
                snakeX[i] = snakeX[i-1];
                snakeY[i] = snakeY[i-1];
            }

            //蛇头移动方向
            switch (direction){
                case "U": snakeY[0]=snakeY[0]-25; if(snakeY[0]<100){snakeY[0]=625;} break;
                case "D": snakeY[0]=snakeY[0]+25; if(snakeY[0]>625){snakeY[0]=100;} break;
                case "L": snakeX[0]=snakeX[0]-25; if(snakeX[0]<25){snakeX[0]=850;} break;
                case "R": snakeX[0]=snakeX[0]+25; if(snakeX[0]>850){snakeX[0]=25;} break;
            }

            //断定失败
            for (int i = 1; i < length; i++) {
                if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){ //头和身体重合
                    isFail = true; //失败
                }
            }

            //吃食物监听
            if(snakeX[0]==foodX && snakeY[0]==foodY){
                /**
                 * 注意:此处长度+1会出现左上角身体闪烁问题,目前原因不明!
                 */
                length++; //长度+1
                score+=10; //分数+10
                //重新生成食物坐标
                foodX = 25 + 25 * random.nextInt(34);
                foodY = 100 + 25 * random.nextInt(22);
            }

        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值