Java Swing 贪吃蛇小游戏

静态资源参考:
在这里插入图片描述
注:实际上没有用到header.png.

工程目录:
Java Swing 贪吃蛇小游戏_第1张图片
源码:

package snake;

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

/**
 * 存放蛇的数据
 */
public class Data {
     

    private static URL bodyURL = Data.class.getResource("img/body.png");
    private static URL downURL = Data.class.getResource("img/down.png");
    private static URL foodURL = Data.class.getResource("img/food.png");
    private static URL headerURL = Data.class.getResource("img/header.png");
    private static URL leftURL = Data.class.getResource("img/left.png");
    private static URL rightURL = Data.class.getResource("img/right.png");
    private static URL upURL = Data.class.getResource("img/up.png");


    private static ImageIcon bodyIMG = new ImageIcon(bodyURL);
    private static ImageIcon downIMG = new ImageIcon(downURL);
    private static ImageIcon foodIMG = new ImageIcon(foodURL);
    private static ImageIcon headerIMG = new ImageIcon(headerURL);
    private static ImageIcon leftIMG = new ImageIcon(leftURL);
    private static ImageIcon rightIMG = new ImageIcon(rightURL);
    private static ImageIcon upIMG = new ImageIcon(upURL);

    public static ImageIcon getBodyIMG() {
     
        return bodyIMG;
    }

    public static void setBodyIMG(ImageIcon bodyIMG) {
     
        Data.bodyIMG = bodyIMG;
    }

    public static ImageIcon getDownIMG() {
     
        return downIMG;
    }

    public static void setDownIMG(ImageIcon downIMG) {
     
        Data.downIMG = downIMG;
    }

    public static ImageIcon getFoodIMG() {
     
        return foodIMG;
    }

    public static void setFoodIMG(ImageIcon foodIMG) {
     
        Data.foodIMG = foodIMG;
    }

    public static ImageIcon getHeaderIMG() {
     
        return headerIMG;
    }

    public static void setHeaderIMG(ImageIcon headerIMG) {
     
        Data.headerIMG = headerIMG;
    }

    public static ImageIcon getLeftIMG() {
     
        return leftIMG;
    }

    public static void setLeftIMG(ImageIcon leftIMG) {
     
        Data.leftIMG = leftIMG;
    }

    public static ImageIcon getRightIMG() {
     
        return rightIMG;
    }

    public static void setRightIMG(ImageIcon rightIMG) {
     
        Data.rightIMG = rightIMG;
    }

    public static ImageIcon getUpIMG() {
     
        return upIMG;
    }

    public static void setUpIMG(ImageIcon upIMG) {
     
        Data.upIMG = upIMG;
    }
}

package snake;

import javax.swing.*;

/**
 * 游戏主启动类
 */
public class StartGame {
     
    public static void main(String[] args) {
     

        /*
        窗口基本设置
         */
        JFrame jFrame = new JFrame("贪吃蛇小游戏");
        //固定窗口大小
        jFrame.setResizable(false);

        /*
        面板:一定要放在setVisible(true)的前面;
        因为获得的焦点事件setFocusable(true)和键盘的监听事件addKeyListener(this)
        一定要放在setVisible(true)的前面;
        否则会导致键盘监听失效
         */
        jFrame.add(new GamePanel());

        //设置窗口可见性
        jFrame.setVisible(true);
        //设置窗口定位和大小
        jFrame.setBounds(10,10,900,720);
        //设置关闭窗口监听
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }
}

package snake;

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{
     

    int length;// 蛇的长度
    int[] snakeX = new int[500];// 蛇的X坐标
    int[] snakeY = new int[500];// 蛇的Y坐标

    // 食物的坐标
    int foodx;
    int foody;
    // 随机数
    Random random = new Random();

    String direction;// 小蛇头的方向

    boolean isStart = false;// 游戏初始状态为停止

    boolean isFail = false;// 游戏失败状态

    int score;// 游戏得分

    /*
    定时器:每隔100毫秒执行一次实现的ActionListener接口中的actionPerformed的方法体
     */
    Timer timer = new Timer(100,this);

    // 启动
    public GamePanel(){
     
        //初始化蛇
        init();
        //获得焦点事件
        this.setFocusable(true);
        //获得键盘的监听事件
        this.addKeyListener(this);
        // 开启定时器
        timer.start();
    }

    /*
    初始化蛇
     */
    public void init(){
     
        /*
        每个方块图形大小:25*25
        X坐标依次减25便于蛇身排列在一行
         */
        length = 3;// 初始时蛇只有三个块
        snakeX[0] = 100;snakeY[0] = 100;// 初始时蛇第一个块的坐标(蛇头)
        snakeX[1] = 75;snakeY[1] = 100;// 初始时蛇第二个块的坐标
        snakeX[2] = 50;snakeY[2] = 100;// 初始时蛇第三个块的坐标

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

        // 把食物随机分布在游戏界面上
        foodx = 25+random.nextInt(34)*25;//850除25=34
        foody = 75+random.nextInt(24)*25;//600除25=24

        score = 0;// 游戏得分
    }

    /*
    画笔
     */
    @Override
    protected void paintComponent(Graphics g) {
     
        // 清屏
        super.paintComponent(g);
        // 设置背景颜色
        this.setBackground(Color.WHITE);

        // 广告栏界面
        //Data.getHeaderIMG().paintIcon(this,g,250,11);
        g.setFont(new Font("微软雅黑",Font.BOLD,40));
        g.drawString("广告位招租",320,50);

        //动态绘制游戏得分
        g.setColor(Color.BLUE);
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        g.drawString("当前长度:"+length,750,25);
        g.drawString("当前得分:"+score,750,50);

        // 绘制矩形游戏界面
        g.setColor(Color.BLACK);
        g.fillRect(25,75,850,600);

        // 动态绘制小蛇头的方向
        if (direction.equals("R")){
     
            Data.getRightIMG().paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if (direction.equals("L")){
     
            Data.getLeftIMG().paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if (direction.equals("U")){
     
            Data.getUpIMG().paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if (direction.equals("D")){
     
            Data.getDownIMG().paintIcon(this,g,snakeX[0],snakeY[0]);
        }else {
     
            System.out.println("错误:未知的方向!");
        }

        // 动态绘制小蛇身体
        for (int i = 1; i < length; i++) {
     
            Data.getBodyIMG().paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        //动态绘制食物
        Data.getFoodIMG().paintIcon(this,g,foodx,foody);

        /*
        游戏状态
         */
        if (isStart==false){
     
            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("游戏失败!按下空格重新开始!",300,300);
            g.setColor(Color.BLUE);
            g.drawString("当前得分:"+score,300,350);
        }
    }

    // 键盘监听
    @Override
    public void keyPressed(KeyEvent e) {
     
        int keyCode = e.getKeyCode();
        // 如果按下空格
        if (keyCode == KeyEvent.VK_SPACE){
     
            if (isFail){
     
                /*
                 游戏重新开始
                  */
                isFail = false;
                // 重新开始小蛇的初始位置
                init();
            }else {
     
                // 取反,这样空格才能开始和停止游戏,不能写死
                isStart = !isStart;
            }
            // isStart值已经发生变化,需要重新加载画笔paintComponent(Graphics g)方法
            repaint();
        }

        /*
        游戏开始后键盘才能控制小蛇头上下左右动
         */
        if (isStart){
     
            if (keyCode == KeyEvent.VK_UP){
     
                direction = "U";
            }else if (keyCode == KeyEvent.VK_DOWN){
     
                direction = "D";
            }else if (keyCode == KeyEvent.VK_LEFT){
     
                direction = "L";
            }else if (keyCode == KeyEvent.VK_RIGHT){
     
                direction = "R";
            }
            // direction值已经发生改变,需要重新加载画笔paintComponent(Graphics g)方法
            repaint();
        }
    }

    // 定时器事件监听
    @Override
    public void actionPerformed(ActionEvent e) {
     
        /*
        游戏开始状态
         */
        if (isStart && isFail == false){
     

             // 小蛇头direction默认等于R
             // 小蛇身体移动
            for (int i = length-1;i>0;i--){
     
                snakeX[i] = snakeX[i-1];
                snakeY[i] = snakeY[i-1];
            }

            if (direction.equals("U")){
     
                // 小蛇头上移
                snakeY[0] = snakeY[0]-25;
                // 上边界判断
                if (snakeY[0]<75){
     
                    snakeY[0]=600;
                }
            }else if(direction.equals("D")){
     
                // 小蛇头下移
                snakeY[0] = snakeY[0]+25;
                // 下边界判断
                if (snakeY[0]>650){
     
                    snakeY[0]=75;
                }
            }else if (direction.equals("L")){
     
                // 小蛇头左移
                snakeX[0] = snakeX[0]-25;
                // 左边界判断
                if (snakeX[0]<25){
     
                    snakeX[0]=850;
                }
            }else if (direction.equals("R")){
     
                // 小蛇头右移
                snakeX[0] = snakeX[0]+25;
                // 右边界判断
                if (snakeX[0]>850){
     
                    snakeX[0]=25;
                }
            }

            /*
            小蛇吃食物:蛇头的坐标等于食物的坐标
             */
            if (snakeX[0]==foodx&&snakeY[0]==foody){
     
                length++;// 蛇身长度加1
                score+=10;// 分数加10

                /*
                食物再次出现:把食物随机分布在游戏界面上
                 */
                foodx = 25+random.nextInt(34)*25;//850除25=34
                foody = 75+random.nextInt(24)*25;//600除25=24
            }

            /*
            判断游戏失败:蛇头撞到自己的身体就算失败
             */
            for (int i = 1; i < length; i++) {
     
                if (snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
     
                    isFail = true;// 游戏失败
                }
            }

            /*
            判断游戏失败:蛇头撞到上下左右边界就算失败
             */
//            if (snakeX[0]==875||snakeX[0]==0||snakeY[0]==675||snakeY[0]==0){
     
//                isFail = true;// 游戏失败
//                snakeX[0] = 875;
//            }
            //蛇的参数改变了,需要重新加载画笔
            repaint();
        }

        // 开启定时器
        timer.start();
    }

    /*
    无用的两个键盘监听方法
     */
    @Override
    public void keyReleased(KeyEvent e) {
     
    }

    @Override
    public void keyTyped(KeyEvent e) {
     
    }

}

运行结果:
Java Swing 贪吃蛇小游戏_第2张图片
生成jar包:链接

注:仅供学习参考,非商用。侵权私信本人删除。

参考资料:

https://www.bilibili.com/video/BV1DJ411B75F?p=26

你可能感兴趣的:(Java,java,游戏,游戏开发)