JAVA简易版坦克大战

package mytankgame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Vector;

public class MyTankGame implements ActionListener{

    JFrame jf=null;
    StartPanel sp=null;
    JMenuBar jmb=null;
    //菜单
    JMenu jm=null;
    //菜单选项
    JMenuItem ji1=null;
    JMenuItem ji2=null;
    JMenuItem ji3=null;
    //构造函数初始化程序的界面
    MyTankGame()
    {
        jf=new JFrame("坦克大战");
        sp=new StartPanel();
        jf.setBounds(300, 200, 800, 700);
        //菜单条
        jmb=new JMenuBar();
        //菜单
        jm=new JMenu("游戏");
        //开始游戏菜单选项
        ji1=new JMenuItem("开始游戏");
        ji1.setActionCommand("newgame");
        ji1.addActionListener(this);
        //存盘退出
        ji2=new JMenuItem("存盘退出");
        ji2.setActionCommand("saveexit");
        ji2.addActionListener(this);

        jf.setJMenuBar(jmb);
        jmb.add(jm);
        jm.add(ji1);
        jm.add(ji2);
        jm.add(ji3);
        jf.add(sp);
        new Thread(sp).start();
        jf.setVisible(true);
    }
    //主函数
    public static void main(String[] args) {
                 MyTankGame mtg=new MyTankGame();
    }

    @Override
    //事件监听方法
    public  void actionPerformed(ActionEvent e) {
        //当点击新游戏的时候的方法
        if(e.getActionCommand().equals("newgame"))
        {
            MyPanel mp=new MyPanel();
            jf.remove(sp);
            jf.add(mp);
            new Thread(mp).start();
            jf.addKeyListener(mp);
            jf.setVisible(true);
        }else if(e.getActionCommand().equals("saveexit"))//点击存盘退出时的方法
        {
            Recorder.saveExit();
            System.exit(0);
        }
    }


}
//设置一个开始时的面板,并且实现字体闪动效果
class StartPanel extends JPanel implements Runnable
{
    int times=0;
    public void paint(Graphics g)
    {
        super.paint(g);
        g.fillRect(0, 0, 500, 400);
        //让面板实现闪动效果
        if(times%2==0)
        {
        g.setColor(Color.lightGray);
        Font myfont=new Font("华文新魏", Font.BOLD, 100);
        g.setFont(myfont);
        g.drawString("STAGE :1", 30, 150);
        }
    }

    @Override
    public void run() {
        while(true)
        {
        try {
            Thread.sleep(500);
        } catch (Exception e) {
            // TODO: handle exception
        }
        times++;
        this.repaint(); 
        }
    }
}
//游戏主界面
class MyPanel extends JPanel implements KeyListener,Runnable
{
    //定义爆炸时候的图片
    Image i1=null;
    Image i2=null;
    Image i3=null;
    Image i4=null;
    Image i5=null;
    Image i6=null;
    Image i7=null;
    Image i8=null;
    //存放爆炸类的集合
    Vector<Boom> vboom=new Vector<Boom>();

    HeroTank hero=null;
    //存放敌方坦克的集合
    Vector<enemyTank> v=new Vector<enemyTank>();



    MyPanel()
    {
        //将敌方坦克的集合传入
        Recorder.setV(v);
        //初始化我的坦克
        hero=new HeroTank(10,10);
        //初始化敌方坦克
        for (int x=0;x<3;x++)
        {
            enemyTank enemy=new enemyTank((x+1)*100,0);
            //将面板上的所有坦克传入,来判断是否碰撞
            enemy.setEt(v);
            enemy.setDirect(2);
            new Thread(enemy).start();
            Bullet bullet=new Bullet(enemy.x+23,enemy.y+25,enemy.direct);
            enemy.enemyV.add(bullet);
            new Thread(bullet).start();
            v.add(enemy);   
        }
        i1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast1.gif"));
        i2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast2.gif"));
        i3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast3.gif"));
        i4=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast4.gif"));
        i5=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast5.gif"));
        i6=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast6.gif"));
        i7=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast7.gif"));
        i8=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/blast8.gif"));
    }
    public void paint(Graphics g)
    {

        super.paint(g);
        g.fillRect(0, 0, 500, 400);
        //画出记录坦克总数的方法
        showInfo(g);
        //画自己的坦克
        if(hero.isLive)
        {
        drawTank(hero.getX(),hero.getY(),g,1,hero.getDirect());
        }
        //画出敌方坦克和子弹
        for (int x=0;x<v.size();x++)
        {
            enemyTank et=v.get(x);
            if(et.isLive==true)
            {
            drawTank(et.getX(),et.getY(),g,0,et.direct);
            for(int i=0;i<et.enemyV.size();i++)
            {
                Bullet b=et.enemyV.get(i);
                if(b.isLive)
                {
                g.drawOval(b.x,b.y, 2, 2);
                }else
                {
                    et.enemyV.remove(b);
                }
            }
            }
        }

        //画出自己的子弹
        for(int i=0;i<hero.vb.size();i++)
        {
            Bullet mybullet=hero.vb.get(i);
            if(mybullet!=null&&mybullet.isLive==true)
            {
                 g.drawOval(mybullet.x, mybullet.y, 2, 2);
            }
            if(mybullet.isLive==false)
            {
                hero.vb.remove(i);
            }
        }
        //画出爆炸的效果
        for(int j=0;j<vboom.size();j++)
        {

            Boom b=vboom.get(j);
            //System.out.println(b.x+":"+b.y);
            if(b.live>42)
            {
                g.drawImage(i1, b.x, b.y, 60, 60,this);

            }else if(b.live>36)
            {
                g.drawImage(i2, b.x, b.y, 60, 60, this);

            }else if(b.live>30)
            {
                g.drawImage(i3, b.x, b.y, 60, 60, this);

            }else if(b.live>24)
            {
                g.drawImage(i4,b.x, b.y, 60, 60, this);

            }else if(b.live>18)
            {
                g.drawImage(i5, b.x, b.y, 60, 60, this);

            }else if(b.live>12)
            {
                g.drawImage(i6, b.x, b.y, 60, 60, this);

            }else if(b.live>6)
            {
                g.drawImage(i7, b.x, b.y, 60, 60, this);
            }else 
            {
                g.drawImage(i8, b.x, b.y, 60, 60, this);
            }
            b.lifeDown();
            if(b.live==0)
            {
                vboom.remove(b);
            }
        }
    }
    //画出记录坦克数量的函数
    public void showInfo(Graphics g)
    {
        this.drawTank(50,450,g,0,0);
        g.setColor(Color.BLACK);
        Font myfont=new Font("华文新魏", Font.BOLD, 30);
        g.setFont(myfont);
        g.drawString(Recorder.getEnemynum()+"", 100, 480);
        this.drawTank(150,450,g,1,0);
        g.drawString(Recorder.getMenum()+"", 200, 480);
        g.setColor(Color.black);
        g.drawString("您的总成绩", 530, 50);
        this.drawTank(530, 90, g, 0, 0);
        g.setColor(Color.black);
        g.drawString(Recorder.getAllen()+"", 600, 120);

    }   
    //画坦克的函数
    public void drawTank(int x,int y,Graphics g,int type,int direct)
    {
        //根据类型画出不同颜色的坦克来区分
        switch(type)
        {
        case 0:
            g.setColor(Color.CYAN);
            break;
        case 1:
            g.setColor(Color.ORANGE);
            break;
        }
        //判断方向画出不同方向的坦克
        switch(direct)
        {
        case 0:
            g.fill3DRect(x, y, 10, 50,false);
            g.fill3DRect(x+5, y+5,25,40,false);
            g.fill3DRect(x+30, y, 10, 50,false);;
            g.fillOval(x+9, y+13, 20, 20);
            g.drawLine(x+20, y+18, x+20, y-15);
            break;
        case 1:
            g.fill3DRect(x, y, 50, 10, false);
            g.fill3DRect(x+5, y+5, 40, 25, false);
            g.fill3DRect(x, y+30, 50, 10, false);
            g.fillOval(x+13, y+9, 20, 20);
            g.drawLine(x+13, y+18, x+65, y+18);
            break;
        case 2:
            g.fill3DRect(x, y, 10, 50,false);
            g.fill3DRect(x+5, y+5,25,40,false);
            g.fill3DRect(x+30, y, 10, 50,false);;
            g.fillOval(x+9, y+13, 20, 20);
            g.drawLine(x+20, y+18, x+20, y+63);
            break;
        case 3:
            g.fill3DRect(x, y, 50, 10, false);
            g.fill3DRect(x+5, y+5, 40, 25, false);
            g.fill3DRect(x, y+30, 50, 10, false);
            g.fillOval(x+13, y+9, 20, 20);
            g.drawLine(x+20, y+18,x-15 , y+18);
            break;
        }
        this.repaint();

    }
    //判断是否击中,子弹的坐标是否在坦克的范围内
    public void hitTank(Tank et,Bullet b)
    {
        switch(et.direct)
        {
        case 0:
        case 2:
            if(b.x>et.x&&b.x<et.x+45&&b.y>et.y&&b.y<et.y+50)
            {

                et.isLive=false;
                b.isLive=false;
                if(et instanceof enemyTank)
                {
                    Recorder.enemydown();
                    Recorder.allUp();
                }else
                {
                    Recorder.medown();
                }
                Boom bm=new Boom(et.x,et.y);
                vboom.add(bm);

            }
            break;
        case 1:
        case 3:
            if(b.x>et.x&&b.x<et.x+50&&b.y>et.y&&b.y<et.y+45)
            {

                et.isLive=false;
                b.isLive=false;
                if(et instanceof enemyTank)
                {
                    Recorder.enemydown();
                    Recorder.allUp();
                }else
                {
                    Recorder.medown();
                }

                Boom bm=new Boom(et.x,et.y);
                vboom.add(bm);
            }
            break;
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    //控制方向
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_W)
        {
            //方向向上
            this.hero.setDirect(0);
            this.hero.moveUp();
        }else if(e.getKeyCode()==KeyEvent.VK_D)
        {
            this.hero.setDirect(1);
            this.hero.moveRight();
        }else if(e.getKeyCode()==KeyEvent.VK_S)
        {
            this.hero.setDirect(2);
            this.hero.moveDown();
        }else if(e.getKeyCode()==KeyEvent.VK_A)
        {
            this.hero.setDirect(3);
            this.hero.moveLeft();
        }
        if(e.getKeyCode()==KeyEvent.VK_J)
        {
            if(hero.isLive)
            {
            if(hero.vb.size()<5)
            {
            hero.shot();
            }
            }
        }
        if(e.getKeyCode()==KeyEvent.VK_SPACE)
        {
            hero.speed=0;
            hero.bullet.speed=0;
            hero.setDirect(hero.direct);

            for(int i=0;i<v.size();i++)
            {
                v.get(i).speed=0;
                v.get(i).setDirect(v.get(i).direct);
                for(int j=0;j<v.get(i).enemyV.size();j++)
                {
                    v.get(i).enemyV.get(j).speed=0;
                }
            }
        }

    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void run() {
        while(true)
        {
        try{
            Thread.sleep(100);

        }catch (Exception e) {
            // TODO: handle exception
        }
        //判断敌人坦克是否被子弹击中
        for (int i=0;i<hero.vb.size();i++)
        {
            Bullet b=hero.vb.get(i);
            if(b.isLive)
            {
                for (int j=0;j<v.size();j++)
                {
                    enemyTank et=v.get(j);
                    if(et.isLive)
                    {
                        hitTank(et,b);
                    }
                }
            }
        }
        //判断自己坦克有没有被坦克击中
        for(int i=0;i<v.size();i++)
        {
            enemyTank et=v.get(i);
            for(int j=0;j<et.enemyV.size();j++)
            {
                Bullet b=et.enemyV.get(j);
                if(hero.isLive)
                {
                hitTank(hero,b);
                }
            }
        }
        this.repaint();
    }
    }
}
//记录类
class Recorder
{
    //敌人坦克的数量
    private static int enemynum=20;
    //自己坦克的生命
    private static int menum=3;
    //杀死坦克的数量
    private static int allen=0;

    private static BufferedReader br=null;
    private static BufferedWriter bw=null;

    private static Vector<enemyTank> v=new Vector<enemyTank>();

    public static Vector<enemyTank> getV() {
        return v;
    }
    public static void setV(Vector<enemyTank> v) {
        Recorder.v = v;
    }
    public static int getAllen() {
        return allen;
    }
    public static void setAllen(int allen) {
        Recorder.allen = allen;
    }
    public static int getEnemynum() {
        return enemynum;
    }
    public  void setEnemynum(int enemynum) {
        this.enemynum = enemynum;
    }
    public static int getMenum() {
        return menum;
    }
    public void setMenum(int menum) {
        this.menum = menum;
    }
    public static void enemydown()
    {
        enemynum--;
    }
    public static void medown()
    {
        menum--;
    }
    public static void allUp()
    {
        allen++;
    }
    public static void saveExit()
    {
        //将传进来的敌方坦克的集合里的坦克的坐标方向都存在文件里
        try
        {
        bw=new BufferedWriter(new FileWriter("myRecorder.txt"));
        for(int i=0;i<v.size();i++)
        {
            if(v.get(i).isLive)
            {
            bw.write(allen+""+"\r\n");
            String recorder=v.get(i).x+" "+v.get(i).y+" "+v.get(i).direct+"\r\n";
            bw.write(recorder);
            }
        }
        }catch (Exception e) {
            // TODO: handle exception
        }finally
        {
            try
            {
            bw.close();
            }catch (Exception e) {
                // TODO: handle exception
            }
        }

    }
}
//爆炸类
class Boom
{
    //定义爆炸的坐标
    int x;
    int y;
    //爆炸随着时间的不同来显示不同的图片,来造成爆炸的视觉效果,定义一个时间
    int live=48;
    boolean isLive=true;
    public Boom(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
    public void lifeDown()
    {
        if(live>0)
        {
        live--;
        }else
        {
            isLive=false;
        }
    }
}
//坦克类
class Tank
{
    //坦克的横纵坐标
    int x=0;
    int y=0;
    //坦克的方向
    int direct=0;
    int speed=1;
    boolean isLive=true;
    public int getSpeed() {
        return speed;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public int getDirect() {
        return direct;
    }
    public void setDirect(int direct) {
        this.direct = direct;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    Tank(int x,int y)
    {
        this.x=x;
        this.y=y;
    }
}
//敌方坦克
class enemyTank extends Tank implements Runnable
{
    int times=0;
    //存放子弹的集合,为每个坦克自带的属性
    Vector<Bullet> enemyV=new Vector<Bullet>();
    //取出所有panel里面的坦克的集合,来判断是否有碰撞
    Vector<enemyTank> vv=new  Vector<enemyTank>();
    Bullet bullet=null;
    enemyTank(int x,int y)
    {
        super(x,y);
    }
    //将所有面板上的坦克传进的方法
    public void setEt(Vector v)
    {
        this.vv=v;
    }
    //判断是否碰撞的方法
    public boolean isTouch()
    {
        boolean flag=false;
        switch(this.direct)
        {
        case 0:
            for(int i=0;i<vv.size();i++)
            {
                enemyTank et=vv.get(i);
                //判断取出的坦克是不是自己
                if(et!=this)
                {
                    //敌方坦克向上或者向下
                    if(et.direct==0||et.direct==2)
                    {
                        //判断最前面的两个点即可
                        if(this.x>=et.x&&this.x<et.x+45&&this.y>=et.y&&this.y<=et.y+50)
                        {
                            return true;
                        }
                        if(this.x+45>=et.x&&this.x+45<=et.x+45&&this.y>=et.y&&this.y<=et.y+50)
                        {
                            return true;
                        }

                    }
                    //敌方坦克向左或者向右
                    if(et.direct==1||et.direct==3)
                    {
                        if(this.x>=et.x&&this.x<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
                        {
                            return true;
                        }
                        if(this.x+45>=et.x&&this.x+45<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
                        {
                            return true;
                        }
                    }
                }
            }
            break;
        case 1:
            for(int i=0;i<vv.size();i++)
            {
                enemyTank et=vv.get(i);
                //判断取出的坦克是不是自己
                if(et!=this)
                {
                    //敌方坦克向上或者向下
                    if(et.direct==0||et.direct==2)
                    {
                        //判断最前面的两个点即可
                        if(this.x+50>=et.x&&this.x+50<et.x+45&&this.y>=et.y&&this.y<=et.y+50)
                        {
                            return true;
                        }
                        if(this.x+50>=et.x&&this.x+50<=et.x+45&&this.y+45>=et.y&&this.y+45<=et.y+50)
                        {
                            return true;
                        }

                    }
                    //敌方坦克向左或者向右
                    if(et.direct==1||et.direct==3)
                    {
                        if(this.x+50>=et.x&&this.x+50<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
                        {
                            return true;
                        }
                        if(this.x+50>=et.x&&this.x+50<=et.x+50&&this.y+45>=et.y&&this.y+45<=et.y+45)
                        {
                            return true;
                        }
                    }
                }
            }
            break;
        case 2:
            for(int i=0;i<vv.size();i++)
            {
                enemyTank et=vv.get(i);
                //判断取出的坦克是不是自己
                if(et!=this)
                {
                    //敌方坦克向上或者向下
                    if(et.direct==0||et.direct==2)
                    {
                        //判断最前面的两个点即可
                        if(this.x>=et.x&&this.x<et.x+45&&this.y+50>=et.y&&this.y+50<=et.y+50)
                        {
                            return true;
                        }
                        if(this.x+45>=et.x&&this.x+45<=et.x+45&&this.y+50>=et.y&&this.y+50<=et.y+50)
                        {
                            return true;
                        }

                    }
                    //敌方坦克向左或者向右
                    if(et.direct==1||et.direct==3)
                    {
                        if(this.x>=et.x&&this.x<=et.x+50&&this.y+50>=et.y&&this.y+50<=et.y+45)
                        {
                            return true;
                        }
                        if(this.x+45>=et.x&&this.x+45<=et.x+50&&this.y+50>=et.y&&this.y+50<=et.y+45)
                        {
                            return true;
                        }
                    }
                }
            }
            break;
        case 3:
            for(int i=0;i<vv.size();i++)
            {
                enemyTank et=vv.get(i);
                //判断取出的坦克是不是自己
                if(et!=this)
                {
                    //敌方坦克向上或者向下
                    if(et.direct==0||et.direct==2)
                    {
                        //判断最前面的两个点即可
                        if(this.x>=et.x&&this.x<et.x+45&&this.y>=et.y&&this.y<=et.y+50)
                        {
                            return true;
                        }
                        if(this.x>=et.x&&this.x<=et.x+45&&this.y+45>=et.y&&this.y+45<=et.y+50)
                        {
                            return true;
                        }

                    }
                    //敌方坦克向左或者向右
                    if(et.direct==1||et.direct==3)
                    {
                        if(this.x>=et.x&&this.x<=et.x+50&&this.y>=et.y&&this.y<=et.y+45)
                        {
                            return true;
                        }
                        if(this.x>=et.x&&this.x<=et.x+50&&this.y+45>=et.y&&this.y+45<=et.y+45)
                        {
                            return true;
                        }
                    }
                }
            }
            break;
        }
        return flag;
    }

    @Override
    public void run() {
        while(true)
        {
            //判断方向,然后让坦克向一定方向走一段时间,再转换方向
            switch(direct)
            {
            case 0:
                for(int i=0;i<30;i++)
                {
                    if(y>0&&!isTouch())
                    {
                        y-=speed;
                        try {
                            Thread.sleep(50);
                        } catch (Exception e) {

                        }
                    }
                }
                break;
            case 1:
                for(int i=0;i<30;i++)
                {
                    if(x<500&&!isTouch())
                    {
                        x+=speed;
                        try {
                            Thread.sleep(50);
                        } catch (Exception e) {

                        }
                    }
                }
                break;
            case 2:
                for(int i=0;i<30;i++)
                {
                    if(y<400&&!isTouch())
                    {
                        y+=speed;
                        try {
                            Thread.sleep(50);
                        } catch (Exception e) {

                        }
                    }
                }
                break;
            case 3:
                for(int i=0;i<30;i++)
                {
                if(x>0&&!isTouch())
                {
                    x-=speed;
                    try {
                        Thread.sleep(50);
                    } catch (Exception e) {

                    }
                }
                }
                break;
            }
            times++;
            if(times%2==0)
            {
                if(isLive)
                {
                    Bullet bullet=null;
                    if(enemyV.size()<5)
                    {
                        switch(direct)
                        {
                        case 0:
                            bullet=new Bullet(x+20,y-15,0);
                            enemyV.add(bullet);
                            break;
                        case 1:
                            bullet=new Bullet(x+65,y+18,1);
                            enemyV.add(bullet);
                            break;
                        case 2:
                            bullet=new Bullet(x+20,y+63,2);
                            enemyV.add(bullet);
                            break;
                        case 3:
                            bullet=new Bullet(x-15,y+18,3);
                            enemyV.add(bullet);
                            break;
                        }
                        new Thread(bullet).start();
                    }
                }

            }
            //随机产生方向
            direct=(int)(Math.random()*4);
            if(isLive==false)
            {
                break;
            }
        }
    }
}
//我方坦克
class HeroTank extends Tank
{

    int speed=1;
    Bullet bullet=null;
    Vector <Bullet>vb=new Vector<Bullet>();
    HeroTank(int x,int y)
    {
        super(x,y);
    }
    public void shot()
    {
        switch(direct)
        {
        case 0:
            bullet=new Bullet(x+20,y-15,0);
            vb.add(bullet);
            break;
        case 1:
            bullet=new Bullet(x+65,y+18,1);
            vb.add(bullet);
            break;
        case 2:
            bullet=new Bullet(x+20,y+63,2);
            vb.add(bullet);
            break;
        case 3:
            bullet=new Bullet(x-15,y+18,3);
            vb.add(bullet);
            break;
        }
        new Thread(bullet).start();
    }
    public void moveUp()
    {
        y-=speed;
    }
    public void moveRight()
    {
        x+=speed;
    }
    public void moveDown()
    {
        y+=speed;
    }
    public void moveLeft()
    {
        x-=speed;
    }
}
//子弹
class Bullet implements Runnable
{
    int x;
    int y;
    int direct;
    int speed=1;
    boolean isLive=true;
    Bullet(int x,int y,int direct)
    {
        this.x=x;
        this.y=y;
        this.direct=direct;
    }
    @Override
    public void run() 
    {
        while(true)
        {
            //每发射一颗子弹都停50ms
            try{
                Thread.sleep(50);
            }catch(InterruptedException e)
            {

            }
            //判断子弹的方向,然后移动
            switch(direct)
            {
                case 0:
                    y-=speed;
                    break;
                case 1:
                    x+=speed;
                    break;
                case 2:
                    y+=speed;
                    break;
                case 3:
                    x-=speed;
                    break;
            }
            //如果子弹超出了panel的大小就视为死亡
            if(x<0||x>500||y<0||y>400)
            {
                isLive=false;
                break;
            }
        }
    }
}

跟着教程做了简易版的坦克大战,才知道自己要学习的东西还有很多很多。挺艰难的,很多东西也都还没有实现。以后的路还有很远很远。与君共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值