【JAVA游戏】贪吃蛇的初步实现(五)


本文链接

相关文章(一)

相关文章(二)

相关文章(三)

相关文章(四)


一、总结

  • 贪吃蛇的初步实现的实践就到这里完结。还有一些问题需要去解决(游戏最小化时弹窗依旧显示、弹窗多次弹出、美化图形界面、代码结构有待改进等问题)。
  • 还可以增设一些功能(将游戏的历史最高积分做记录、设置游戏不同难度等级、设置游戏难度递增、添加游戏音效等功能)。

二、功能扩展报告

  • 增设了迷幻食物(吃到后加两百分,但按键控制反向,吃到普通食物后恢复正常)
  • 增设了游戏弹窗(启始弹窗、暂停弹窗、失败弹窗)

三、预期功能展望

代码还有很多需要修改的地方:

  • 问题优化
  1. 优化弹窗最小化问题
  2. 美化图形界面
  3. 优化代码结构
  • 功能补充
  1. 记录游戏的历史最高积分
  2. 设置游戏不同难度等级
  3. 设置难度递增
  4. 添加游戏音效

四、游戏效果展示

游戏效果展示


五、程序代码展示

1:游戏进入弹窗

SignDialog.java

代码如下:

package snakedialog;

import snakegame5.GamePanel5;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SignDialog extends JDialog {

    public SignDialog() {

        setTitle("贪吃蛇");
        setSize(650, 450); //宽高
        setLocationRelativeTo(null); //屏幕中央弹出
        setResizable(false); //不可改变窗口大小

        JPanel panel = new JPanel();
        panel.setLayout(null);

        JButton jb1 = new JButton("开始游戏");
        JButton jb2 = new JButton("退出游戏");
        jb1.setBounds(150, 250, 130, 70);
        jb2.setBounds(370, 250, 130, 70);
        jb1.setFont(new Font("方正舒体", Font.BOLD, 22));
        jb2.setFont(new Font("方正舒体", Font.BOLD, 22));

        JLabel label = new JLabel("贪吃蛇游戏");
        label.setFont(new Font("方正舒体", Font.BOLD, 70));
        label.setBounds(120, 80, 400, 80);
        label.setHorizontalAlignment(SwingConstants.CENTER);

        panel.add(jb1);
        panel.add(jb2);
        panel.add(label);
        add(panel);

        setVisible(true); //展现窗口
        setAlwaysOnTop(true); //窗口置顶
        setModal(true);

        //按钮监听
        jb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                setVisible(false);
                //开始按钮
                GamePanel5.setIsStart(true); //开始游戏
            }
        });

        jb2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //退出按钮
                System.exit(0); //退出游戏
            }
        });
    }
}

2:游戏暂停弹窗

PauseDialog.java

代码如下:

package snakedialog;

import snakegame5.GamePanel5;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class PauseDialog extends JDialog {

    public PauseDialog() {

        setTitle("游戏暂停");
        setSize(650, 450); //宽高
        setLocationRelativeTo(null); //屏幕中央弹出
        setResizable(false); //不可改变窗口大小

        JPanel panel = new JPanel();
        panel.setLayout(null);

        JButton jb1 = new JButton("重新开始");
        JButton jb2 = new JButton("退出游戏");
        JButton jb3 = new JButton("继续游戏");
        jb1.setBounds(260, 250, 130, 70);
        jb2.setBounds(420, 250, 130, 70);
        jb3.setBounds(100, 250, 130, 70);
        jb1.setFont(new Font("方正舒体", Font.BOLD, 22));
        jb2.setFont(new Font("方正舒体", Font.BOLD, 22));
        jb3.setFont(new Font("方正舒体", Font.BOLD, 22));

        JLabel label = new JLabel("游戏暂停");
        label.setFont(new Font("方正舒体", Font.BOLD, 70));
        label.setBounds(120, 80, 400, 80);
        label.setHorizontalAlignment(SwingConstants.CENTER);

        panel.add(jb1);
        panel.add(jb2);
        panel.add(jb3);
        panel.add(label);
        add(panel);

        setVisible(true); //展现窗口
        setAlwaysOnTop(true); //窗口置顶

        //按钮监听
        jb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //重新开始按钮
                setVisible(false);
                GamePanel5.setIsAgain(true); //重新开始游戏
            }
        });

        jb2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //退出按钮
                System.exit(0); //退出游戏
            }
        });

        jb3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //继续按钮
                setVisible(false);
                GamePanel5.setIsStart(true); //继续游戏
            }
        });
    }
}

3:游戏失败弹窗

FailDialog.java

代码如下:

package snakedialog;

import snakegame5.GamePanel5;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FailDialog extends JDialog {

    public FailDialog() {

        setTitle("游戏结束");
        setSize(650, 450); //宽高
        setLocationRelativeTo(null); //屏幕中央弹出
        setResizable(false); //不可改变窗口大小

        JPanel panel = new JPanel();
        panel.setLayout(null);

        JButton jb1 = new JButton("重新开始");
        JButton jb2 = new JButton("退出游戏");
        jb1.setBounds(150, 250, 130, 70);
        jb2.setBounds(370, 250, 130, 70);
        jb1.setFont(new Font("方正舒体", Font.BOLD, 22));
        jb2.setFont(new Font("方正舒体", Font.BOLD, 22));

        if(GamePanel5.isIsFail()) {
            JLabel label1 = new JLabel();
            if (GamePanel5.isWallFail()) {
                label1.setText("撞到墙壁");
            } else if(GamePanel5.isOwnFail()) {
                label1.setText("撞到自己");
            } else if(GamePanel5.isPoisonFail()){
                label1.setText("食物中毒");
            }
            label1.setFont(new Font("方正舒体", Font.BOLD, 70));
            label1.setForeground(Color.red);
            label1.setBounds(120, 40, 400, 80);
            label1.setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(label1);
        }

        JLabel label2 = new JLabel();
        label2.setText("最终得分:"+GamePanel5.getScore());
        label2.setFont(new Font("方正舒体", Font.BOLD, 50));
        label2.setBounds(120, 120, 400, 80);
        label2.setHorizontalAlignment(SwingConstants.CENTER);

        panel.add(jb1);
        panel.add(jb2);
        panel.add(label2);
        add(panel);

        setVisible(true); //展现窗口
        setAlwaysOnTop(true); //窗口置顶

        //按钮监听
        jb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //重新开始按钮
                setVisible(false);
                GamePanel5.setIsAgain(true); //重新开始游戏
            }
        });

        jb2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //退出按钮
                System.exit(0); //退出游戏
            }
        });
    }
}

4:程序的入口

StartGame.java

代码如下:

package snakegame5;

import snakedialog.SignDialog;

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

//程序启动
public class StartGame5 {

    public static void main(String[] args) {
        //绘制静态窗口
        JFrame frame = new JFrame("贪吃蛇小游戏");
        //设置界面的宽高
        frame.setSize(965, 655);
        //屏幕中央弹出
        frame.setLocationRelativeTo(null);
        //窗口大小固定
        frame.setResizable(false);
        //关闭窗口时退出程序
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //添加窗口图标
        frame.setIconImage(Data5.Timage);

        //添加游戏面板
        frame.add(new GamePanel5());
        //设置窗体可见
        frame.setVisible(true);

        new SignDialog(); //游戏初始进入界面

        //如果平台支持系统托盘则设置系统托盘
        /* if (SystemTray.isSupported()) {
            //新建弹出菜单
            PopupMenu popupMenu = new PopupMenu();
            //新建菜单选项
            MenuItem openItem = new MenuItem("open");
            MenuItem hideItem = new MenuItem("hide");
            MenuItem exitItem = new MenuItem("exit");

            //设置open菜单监听
            openItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!frame.isShowing()) {
                        frame.setExtendedState(JFrame.NORMAL);
                        frame.setVisible(true);
                    }
                }
            });

            //设置hide菜单监听
            hideItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    frame.setExtendedState(JFrame.ICONIFIED);
                }
            });

            //设置exit菜单监听
            exitItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });

            //添加菜单项
            popupMenu.add(openItem);
            popupMenu.add(hideItem);
            popupMenu.add(exitItem);

            //调用构造器//图片/信息/菜单
            TrayIcon trayIcon = new TrayIcon(Data.image, "贪吃蛇小游戏", popupMenu);
            //获得系统托盘
            SystemTray systemTray = SystemTray.getSystemTray();
            //自适应图片大小
            trayIcon.setImageAutoSize(true);
            //添加到系统托盘
            try {
                systemTray.add(trayIcon);
            } catch (AWTException e) {
                e.printStackTrace();
            }

            //窗口最小化事件监听
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowIconified(WindowEvent e) {
                    frame.dispose();
                }
            });

            //鼠标点击托盘事件监听
            trayIcon.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON1 && !frame.isShowing()) {
                        frame.setExtendedState(JFrame.NORMAL);
                        frame.setVisible(true);
                    }
                }
            });
        } */
    }
}

5:程序的主体

GamePanel.java

代码如下:

package snakegame5;

import snakedialog.*;

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 GamePanel5 extends JPanel implements KeyListener, ActionListener {

    //一、基本属性

    //定义蛇
    private static int length; //蛇的长度
    //蛇的坐标
    private static final int[] snakeX = new int[800];
    private static final int[] snakeY = new int[800];
    private static String order; //方向,"R"(右),"L"(左),"U"(上),"D"(下);

    private static boolean isStart; //开始判断(默认暂停)
    private static boolean isFail; //死亡判断(默认存活)
    //细分失败种类判定
    private static boolean wallFail;
    private static boolean ownFail;
    private static boolean poisonFail;
    //添加是否取反判定
    private static boolean isRevere;
    //添加弹窗所需判定
    private static boolean isFirst;
    private static boolean isAgain;

    //初始化定时器
    Timer timer = new Timer(100, this);

    //定义食物
    //定义随机数,用于概率生成不同食物
    private static int randomInt1;
    private static int randomInt2;
    //食物的坐标
    private static int foodX;
    private static int foodY;
    //实例化Random对象
    Random random = new Random();

    //设置积分系统
    private static int score; //积分
    private static final int f = 50; //蓝豆50分
    private static final int Df = 100; //红豆100分
    private static final int Rf = 200; //紫豆200分

    //特殊食物的坐标
    private static int specialX;
    private static int specialY;

    //get()/set()方法

    public static boolean isIsFail() {
        return isFail;
    }

    public static boolean isOwnFail() {
        return ownFail;
    }

    public static boolean isWallFail() {
        return wallFail;
    }

    public static boolean isPoisonFail() {
        return poisonFail;
    }

    public static int getScore() {
        return score;
    }

    public static void setIsAgain(boolean isAgain) {
        GamePanel4.isAgain = isAgain;
    }

    public static void setIsStart(boolean isStart) {
        GamePanel4.isStart = isStart;
    }

    //二、初始化操作

    //定义构造器
    public GamePanel5() {
        init(); //调用初始化方法
        isFirst = true; //初始启动
        //获取键盘监听事件
        this.setFocusable(true); //对窗口设置键盘焦点
        this.addKeyListener(this); //添加监听器
        //启动定时器
        timer.start();
    }

    //生成食物坐标的方法
    public void foodUpdate() {

        //生成随机数(0~100)//用于概率生成不同食物
        //(0~20)(大积分),(20~100)(小积分)
        randomInt1 = (int) (Math.random() * 100);
        randomInt2 = (int) (Math.random() * 100);

        //随机生成食物/毒食物位置
        int cnt;
        do {
            //生成食物坐标
            foodX = 25 + 25 * random.nextInt(36);
            foodY = 50 + 25 * random.nextInt(22);
            specialX = 100 + 25 * random.nextInt(30);
            specialY = 100 + 25 * random.nextInt(16);
            //循环判定是否有两者坐标重合
            cnt = 0;
            for (int i = 0; i <= length; i++) {
                if (!((snakeX[i] == foodX && snakeY[i] == foodY) ||
                        (snakeX[i] == specialX && snakeY[i] != specialY) ||
                        (foodX == specialX && foodY == specialY))) { //只要有两者位置重合则不执行自加操作
                    cnt++;
                }
            }
        } while (cnt <= length); //cnt<=length说明有重合现象,回到循环
    }

    //定义初始化方法
    public void init() {

        length = 3; //初始化蛇长(3节)
        score = 0; //积分清零

        //判定初始化
        isFail = false;
        poisonFail = false;
        wallFail = false;
        ownFail = false;
        isRevere = false;

        //随机生成蛇头位置//25为最小单位
        snakeX[0] = 100 + 25 * random.nextInt(30);
        snakeY[0] = 100 + 25 * random.nextInt(16);

        //等概率生成蛇头方向
        //根据蛇头方向生成初始蛇身
        int r = (int) (Math.random() * 4);
        int a = snakeX[0];
        int b = snakeY[0];
        switch (r) {
            case 0:
                order = "R";
                snakeX[1] = a - 25;
                snakeY[1] = b;
                snakeX[2] = a - 50;
                snakeY[2] = b;
                snakeX[3] = a - 75;
                snakeY[3] = b;
                break;
            case 1:
                order = "L";
                snakeX[1] = a + 25;
                snakeY[1] = b;
                snakeX[2] = a + 50;
                snakeY[2] = b;
                snakeX[3] = a + 75;
                snakeY[3] = b;
                break;
            case 2:
                order = "U";
                snakeX[1] = a;
                snakeY[1] = b + 25;
                snakeX[2] = a;
                snakeY[2] = b + 50;
                snakeX[3] = a;
                snakeY[3] = b + 75;
                break;
            case 3:
                order = "D";
                snakeX[1] = a;
                snakeY[1] = b - 25;
                snakeX[2] = a;
                snakeY[2] = b - 50;
                snakeX[3] = a;
                snakeY[3] = b - 75;
                break;
        }
        foodUpdate(); //调用食物位置初始化方法
    }

    //三、画板:绘制操作

    @Override
    protected void paintComponent(Graphics g) {

        //画界面
        super.paintComponent(g); //清屏操作
        this.setBackground(Color.white); //设置背景颜色

        //绘制游戏区域
        g.setColor(Color.black);
        g.fillRect(25, 50, 900, 550);

        //绘制帮助提示
        g.setColor(Color.black);
        g.setFont(new Font("方正舒体", Font.BOLD, 25));
        //食物列表
        g.drawString("食物列表:", 30, 45);
        Data5.food.paintIcon(this, g, 150, 24);
        Data5.Dfood.paintIcon(this, g, 240, 24);
        Data5.poison.paintIcon(this, g, 340, 24);
        Data5.reverse.paintIcon(this, g, 545, 24);
        g.drawString("50分", 180, 45);
        g.drawString("100分", 270, 45);
        g.drawString("有毒食物(死亡)", 370, 45);
        g.drawString("迷幻食物(200分)", 575, 45);
        //按键控制
        g.drawString("按键控制:", 30, 20);
        g.drawString("(W/A/S/D)(UP/LEFT/DOWN/RIGHT)(上/左/下/右)", 150, 20);
        //画框
        g.drawRect(25, 0, 900, 50);
        g.drawLine(760, 0, 760, 50);
        g.drawLine(25, 23, 925, 23);

        //画积分
        g.setColor(Color.black); //设置字体颜色
        g.setFont(new Font("方正舒体", Font.BOLD, 25));
        g.drawString("分数:" + (score) + "分", 760, 45);
        g.drawString("长度:" + (length) + "节", 760, 20);

        //根据当前的方向(order)画蛇头
        switch (order) {
            case "R":
                Data5.right.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "L":
                Data5.left.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "U":
                Data5.up.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
            case "D":
                Data5.down.paintIcon(this, g, snakeX[0], snakeY[0]);
                break;
        }

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

        //画食物
        if (randomInt1 < 20) { //蓝豆(1/5)
            Data5.Dfood.paintIcon(this, g, foodX, foodY);
        } else { //红豆(4/5)
            Data5.food.paintIcon(this, g, foodX, foodY);
        }

        if (randomInt2 < 20) { //有毒食物
            if (!poisonFail) //非中毒死亡时显示有毒食物
                Data5.poison.paintIcon(this, g, specialX, specialY);
        } else { //致幻食物
            Data5.reverse.paintIcon(this, g, specialX, specialY);
        }

        //对话框交互事件

        //游戏开始提示语句(游戏暂停时且游戏未失败)(非首次暂停)
        if (!isStart && !isFail && !isFirst) {
            new PauseDialog(); // 游戏停止对话框
        }

        //游戏结束提示语句(游戏失败时)
        if (isFail) {
            isStart = false; //停止游戏
            new FailDialog(); //游戏失败对话框
        }
    }

    //四、监听器:执行键盘操作

    @Override
    //键盘按下(未释放)
    public void keyPressed(KeyEvent e) {
        //接收键盘的输入
        int keyCode = e.getKeyCode();

        //若按下了空格键
        if (keyCode == KeyEvent.VK_SPACE) {
            //按下空格键暂停游戏
            isFirst = false;
            //停止后不再是进入游戏的第一次
            isStart = false;
            //刷新(重画)界面
            repaint();
        }

        //('W'/'S'/'A'/'D'键或'up'/'down'/'left'/'right'键)按键控制蛇头转向//防止蛇头反向转动
        if (isStart) { //防止游戏暂停时方向按键被有效监听//增加取反判定
            if (!order.equals("R") && !order.equals("L")) {
                if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
                    if (isRevere) {
                        order = "R";
                    } else {
                        order = "L";
                    }
                }
                if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
                    if (isRevere) {
                        order = "L";
                    } else {
                        order = "R";
                    }
                }
            } else { //(!order.equals("W") && !order.equals("D"))
                if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
                    if (isRevere) {
                        order = "D";
                    } else {
                        order = "U";
                    }
                }
                if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
                    if (isRevere) {
                        order = "U";
                    } else {
                        order = "D";
                    }
                }
            }
        }
    }

    //五、定时器:执行定时操作

    @Override
    public void actionPerformed(ActionEvent e) {

        //如果选择重新开始则重新初始化程序
        if (isAgain) {
            init(); //重新做初始化操作
            isAgain = false; //重置判定
            isStart = true; //开始游戏
        }

        //若游戏处于开始状态(蛇发生移动)
        if (isStart) {

            //蛇身移动//保留第length个蛇身的坐标
            for (int i = length; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }

            //蛇头移动
            switch (order) {
                case "R":
                    snakeX[0] += 25;
                    break;
                case "L":
                    snakeX[0] -= 25;
                    break;
                case "U":
                    snakeY[0] -= 25;
                    break;
                case "D":
                    snakeY[0] += 25;
                    break;
            }

            //游戏失败判定

            //蛇头碰到墙后失败(判定蛇头坐标是否在墙外)
            if (snakeX[0] > 900 || snakeX[0] < 25 || snakeY[0] < 50 || snakeY[0] > 575) {
                //判定为失败
                isFail = true;
                wallFail = true;
            }

            //蛇头碰到蛇身后失败(循环判定蛇头坐标是否与任一节蛇身重合)
            for (int i = 1; i < length; i++) {
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                    //判定为失败
                    isFail = true;
                    ownFail = true;
                    break;
                }
            }

            //游戏失败后对蛇体展示优化
            if (isFail) {
                snakeX[0] = snakeX[1];
                snakeY[0] = snakeY[1];
                snakeX[1] = snakeX[length];
                snakeY[1] = snakeY[length];
            }

            //蛇头与特殊食物重合时
            if (snakeX[0] == specialX && snakeY[0] == specialY) {
                if (randomInt2 < 20) { //蛇吃到毒食物(坐标重合)后游戏失败
                    isFail = true;
                    poisonFail = true;
                } else { //蛇吃到致幻食物(坐标重合)后方向控制取反
                    isRevere = true;
                    length++;
                    score += Rf;
                    foodUpdate(); //调用食物位置初始化方法
                }
            }

            //蛇吃到食物(坐标重合)后增长/积分
            if (snakeX[0] == foodX && snakeY[0] == foodY) {
                length++; //蛇身长度加一
                //根据随机数判断生成的食物
                if (randomInt1 < 20) {
                    score += Df;
                } else {
                    score += f;
                }

                isRevere = false; //吃到普通食物后恢复

                foodUpdate(); //调用食物位置初始化方法
            }
            //刷新(重画)界面
            repaint();
        }
        //启动定时器
        timer.start();
    }

    @Override
    public void keyTyped(KeyEvent keyEvent) {
    }

    @Override
    public void keyReleased(KeyEvent keyEvent) {
    }
}


6:存放图片资源

Data.java

代码如下:

package snakegame5;

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

public class Data5 {

    //导入素材图片

    //窗口图标
    public static Image Timage = new ImageIcon(Data5.class.getResource("/resources5/Thetitle5.jpg")).getImage();

    //托盘图标
    public static Image image = Toolkit.getDefaultToolkit().getImage(Data5.class.getResource("/resources5/Thetitle5.jpg"));

    //蛇头图片
    public static ImageIcon up = new ImageIcon(Data5.class.getResource("/resources5/up5.jpg"));
    public static ImageIcon left = new ImageIcon(Data5.class.getResource("/resources5/left5.jpg"));
    public static ImageIcon right = new ImageIcon(Data5.class.getResource("/resources5/right5.jpg"));
    public static ImageIcon down = new ImageIcon(Data5.class.getResource("/resources5/down5.jpg"));

    //蛇身图片
    public static ImageIcon body = new ImageIcon(Data5.class.getResource("/resources5/body5.jpg"));

    //食物图片
    public static ImageIcon food = new ImageIcon(Data5.class.getResource("/resources5/food5.jpg"));
    public static ImageIcon Dfood = new ImageIcon(Data5.class.getResource("/resources5/Dfood5.jpg"));
    public static ImageIcon poison = new ImageIcon(Data5.class.getResource("/resources5/poison5.jpg"));
    public static ImageIcon reverse = new ImageIcon(Data5.class.getResource("/resources5/reverse5.jpg"));
}


  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值