飞机大战源码进来就领


前言

        千山万水总是情,留下关注行不行。大家好,我是小猿,这是我的第一篇blog文章,如果喜欢的话,记得留下关注,让我们一起前行呢。

        飞机大战项目是小猿在一次培训中做过的项目,我重温它,决定将它我作为入驻优快云的第一篇文章,也是送给大家的见面礼。废话不多说,上代码!!

        下面是项目源代码在百度网盘的链接

链接:https://pan.baidu.com/s/1uhg525qS7weIAiP2IE6Q-g
提取码:1234


目录

前言

一、小敌机类

二、大敌机类

 三、蜜蜂类

四、英雄机类

五、子弹类

六、抽象类——飞行物对象

七、图片类——加载图片资源

八、天空类

九、奖励接口和得分接口

十、窗口类

总结





一、小敌机类

import java.awt.image.BufferedImage;
/** 小敌机:是飞行物,也能得分 */
public class Airplane extends FlyingObject implements Enemy {
	private int speed; //移动速度
	/** 构造方法 */
	public Airplane(){
		super(48,50);
		speed = 2;
	}
	
	/** 重写step()移动 */
	public void step() {
		y+=speed; //y+(向下)
	}
	
	int index = 1; //下标
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() { //每10毫秒走一次
		if(isLife()) { //若活着的
			return Images.airplanes[0]; //返回第1张图片
		}else if(isDead()) { //若死了的
			BufferedImage img = Images.airplanes[index++]; //依次获取第2张到第5张爆破图
			if(index==Images.airplanes.length) { //若到最后一张图了
				state = REMOVE; //将当前状态修改为REMOVE删除
			}
			return img; //返回爆破图
		}
		return null; //删除状态时,返回null
		/*
		 *                      index=1
		 * 10M img=airplanes[1] index=2                  返回airplanes[1]
		 * 20M img=airplanes[2] index=3                  返回airplanes[2]
		 * 30M img=airplanes[3] index=4                  返回airplanes[3]
		 * 40M img=airplanes[4] index=5(REMOVE) 返回airplanes[4]
		 * 50M 
		 */
	}
	/** 重写getScore()得分 */
	public int getScore() {
		return 1; //打掉小敌机,玩家得1分
	}
}




二、大敌机类

import java.awt.image.BufferedImage;
/** 大敌机:是飞行物,也能得分 */
public class BigAirplane extends FlyingObject implements Enemy{
	private int speed; //移动速度
	/** 构造方法 */
	public BigAirplane(){
		super(66,89);
		speed = 2;
	}
	
	/** 重写step()移动 */
	public void step() {
		y+=speed; //y+(向下)
	}
	
	int index = 1;
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() { //每10毫秒走一次
		if(isLife()) {
			return Images.bigairplanes[0];
		}else if(isDead()) {
			BufferedImage img = Images.bigairplanes[index++];
			if(index==Images.bigairplanes.length) {
				state = REMOVE;
			}
			return img;
		}
		return null;
	}
	
	/** 重写getScore()得分 */
	public int getScore() {
		return 3; //打掉大敌机,玩家得3分
	}
	
}

 三、蜜蜂类

import java.awt.image.BufferedImage;
import java.util.Random;
/** 小蜜蜂:是飞行物,也是奖励 */
public class Bee extends FlyingObject implements Award{
	private int xSpeed; //x坐标移动速度
	private int ySpeed; //y坐标移动速度
	private int awardType; //奖励类型(0或1)
	/** 构造方法 */
	public Bee(){
		super(60,51);
		xSpeed = 1;
		ySpeed = 2;
		Random rand = new Random();
		awardType = rand.nextInt(2); //0或1
	}
	
	/** 重写step()移动 */
	public void step() {
		x+=xSpeed; //x+(向左或向右)
		y+=ySpeed; //y+(向下)
		if(x<=0 || x>=World.WIDTH-this.width) { //到两边了
			xSpeed*=-1; //切换方向(负变正、正变负)
		}
	}
	
	int index = 1;
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() { //每10毫秒走一次
		if(isLife()) {
			return Images.bees[0];
		}else if(isDead()) {
			BufferedImage img = Images.bees[index++];
			if(index==Images.bees.length) {
				state = REMOVE;
			}
			return img;
		}
		return null;
	}
	
	/** 重写getAwardType()获取奖励类型 */
	public int getAwardType() {
		return awardType; //返回奖励类型
	}
	
}

四、英雄机类

import java.awt.image.BufferedImage;
/** 英雄机 */
public class Hero extends FlyingObject {
	private int life; //命数
	private int doubleFire; //火力值
	/** 构造方法 */
	public Hero(){
		super(97,139,140,400);
		life = 3;
		doubleFire = 0;
	}
	
	/** 英雄机随着鼠标移动 x/y:鼠标的x坐标/y坐标 */
	public void moveTo(int x,int y) {
		this.x = x-this.width/2;  //英雄机的x=鼠标的x-1/2英雄机的宽
		this.y = y-this.height/2; //英雄机的y=鼠标的y-1/2英雄机的高
	}
	
	/** 重写step()移动 */
	public void step() {
		
	}
	
	int index = 0; //下标
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() { //每10毫秒走一次
		if(isLife()) { //若活着的
			return Images.heros[index++%Images.heros.length]; //返回heros[0]和heros[1]来回切换
		}
		return null; //死了的和删除的状态时,都返回null
		/*
		 *                  index=0
		 * 10M 返回heros[0] index=1
		 * 20M 返回heros[1] index=2
		 * 30M 返回heros[0] index=3
		 * 40M 返回heros[1] index=4
		 * 50M 返回heros[0] index=5
		 */
	}
	
	/** 英雄机发射子弹(生成子弹对象) */
	public Bullet[] shoot() {
		int xStep = this.width/4; //1/4英雄机的宽
		int yStep = 20; //固定的20
		if(doubleFire>0) { //双
			Bullet[] bs = new Bullet[2]; //2发子弹
			bs[0] = new Bullet(this.x+1*xStep,this.y-yStep); //x:英雄机的x+1/4英雄机的宽  y:英雄机的y-固定的20
			bs[1] = new Bullet(this.x+3*xStep,this.y-yStep); //x:英雄机的x+3/4英雄机的宽  y:英雄机的y-固定的20
			doubleFire-=2; //发射一次双倍火力,则火力值减2
			return bs;
		}else { //单
			Bullet[] bs = new Bullet[1]; //1发子弹
			bs[0] = new Bullet(this.x+2*xStep,this.y-yStep); //x:英雄机的x+2/4英雄机的宽  y:英雄机的y-固定的20
			return bs;
		}
	}
	
	/** 英雄机增命 */
	public void addLife() {
		life++; //命数增1
	}
	/** 获取英雄机的命 */
	public int getLife() {
		return life; //返回命数
	}
	/** 英雄机减命 */
	public void subtractLife() {
		life--; //命数减1
	}
	
	/** 英雄机增火力 */
	public void addDoubleFire() {
		doubleFire+=40; //火力值增40
	}
	
	/** 清空火力值 */
	public void clearDoubleFire() {
		doubleFire=0; //火力值归零
	}
	
}

五、子弹类

import java.awt.image.BufferedImage;
/** 子弹:是飞行物 */
public class Bullet extends FlyingObject{
	private int speed; //移动速度
	/** 构造方法 */
	public Bullet(int x,int y){
		super(8,20,x,y);
		speed = 3;
	}
	
	/** 重写step()移动 */
	public void step() {
		y-=speed; //y-(向上)
	}
	
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() {
		if(isLife()) {            //若活着的
			return Images.bullet; //则返回bullet图片
		}else if(isDead()) { //若死了的
			state = REMOVE;	 //则将当前状态修改为删除状态
		}
		return null; //死了的和删除的状态时,都返回null
	}
	
	/** 重写outOfBounds()判断子弹是否越界 */
	public boolean outOfBounds() {
		return this.y<=-this.height; //子弹的y<=负的子弹的高,即为越界了
	}
	
}

六、抽象类——飞行物对象

import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
/** 飞行物 */
public abstract class FlyingObject extends Object {
	public static final int LIFE = 0;   //活着的
	public static final int DEAD = 1;   //死了的
	public static final int REMOVE = 2; //删除的
	protected int state = LIFE; //当前状态(默认活着的)
	
	protected int width;  //宽
	protected int height; //高
	protected int x;      //x坐标
	protected int y;      //y坐标
	/** 专门给小敌机、大敌机、小蜜蜂提供的 */
	public FlyingObject(int width,int height){
		this.width = width;
		this.height = height;
		Random rand = new Random();
		x = rand.nextInt(World.WIDTH-this.width); //x:0到(400-敌人宽)之间的随机数
		y = -this.height; //y:负的敌人的高
	}
	/** 专门给英雄机、天空、子弹提供的 */
	public FlyingObject(int width,int height,int x,int y){
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}
	
	/** 飞行物移动 */
	public abstract void step();
	
	/** 获取图片 */
	public abstract BufferedImage getImage();
	
	/** 判断是否是活着的 */
	public boolean isLife() {
		return state==LIFE; //当前状态为LIFE,表示活着的
	}
	/** 判断是否是死了的 */
	public boolean isDead() {
		return state==DEAD; //当前状态为DEAD,表示死了的
	}
	/** 判断是否是删除的 */
	public boolean isRemove() {
		return state==REMOVE; //当前状态为REMOVE,表示删除的
	}
	
	/** 画对象 g:画笔 */
	public void paintObject(Graphics g) {
		g.drawImage(this.getImage(),this.x,this.y,null); //画对象
	}
	
	/** 判断飞行物是否越界---主要是判断敌人 */
	public boolean outOfBounds() {
		return this.y>=World.HEIGHT; //敌人的y>=窗口的高,即为越界了
	}
	
	/** 碰撞检测  this:敌人  other:子弹或英雄机 */
	public boolean hit(FlyingObject other) {
		int x1 = this.x-other.width;  //x1:敌人的x-子弹的宽
		int x2 = this.x+this.width;   //x2:敌人的x+敌人的宽
		int y1 = this.y-other.height; //y1:敌人的y-子弹的高
		int y2 = this.y+this.height;  //y2:敌人的y+敌人的高
		int x = other.x;              //x:子弹的x
		int y = other.y;              //y:子弹的y
		
		return x>=x1 && x<=x2
			   &&
			   y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了
	}
	
	/** 飞行物去死 */
	public void goDead() {
		state = DEAD; //将对象状态修改为DEAD(死了的)
	}
	
}

七、图片类——加载图片资源

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
/** 图片工具类 */
public class Images {
	public static BufferedImage sky; //天空
	public static BufferedImage bullet; //子弹
	public static BufferedImage[] heros; //英雄机数组
	public static BufferedImage[] airplanes; //小敌机数组
	public static BufferedImage[] bigairplanes; //大敌机数组
	public static BufferedImage[] bees; //小蜜蜂数组
	public static BufferedImage start; //启动图
	public static BufferedImage pause; //暂停图
	public static BufferedImage gameover; //游戏结束图
	
	static { //初始化静态图片
		start = readImage("start.png");
		pause = readImage("pause.png");
		gameover = readImage("gameover.png");
		
		sky = readImage("background1.png");
		bullet = readImage("bullet.png");
		
		heros = new BufferedImage[2];
		heros[0] = readImage("hero0.png");
		heros[1] = readImage("hero1.png");
		
		airplanes = new BufferedImage[5];
		bigairplanes = new BufferedImage[5];
		bees = new BufferedImage[5];
		airplanes[0] = readImage("airplane0.png");
		bigairplanes[0] = readImage("bigairplane0.png");
		bees[0] = readImage("bee0.png");
		for(int i=1;i<airplanes.length;i++) {
			airplanes[i] = readImage("bom"+i+".png");
			bigairplanes[i] = readImage("bom"+i+".png");
			bees[i] = readImage("bom"+i+".png");
		}
		
	}
	
	/** 读取图片 */
	public static BufferedImage readImage(String fileName) {
		try{
			BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName)); //同包下读取图片
			return img;
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	
}

八、天空类

import java.awt.Graphics;
import java.awt.image.BufferedImage;
/** 天空:是飞行物 */
public class Sky extends FlyingObject {
	private int speed; //移动速度
	private int y1;    //第2张图的y坐标
	/** 构造方法 */
	public Sky(){
		super(World.WIDTH,World.HEIGHT,0,0);
		speed = 1;
		y1 = -World.HEIGHT;
	}
	
	/** 重写step()移动 */
	public void step() {
		y+=speed;  //y+(向下)
		y1+=speed; //y1+(向下)
		if(y>=World.HEIGHT) { //y到最下面了
			y=-World.HEIGHT;  //修改y的值为负的窗口的高(移到最上面去)
		}
		if(y1>=World.HEIGHT) { //y1到最下面了
			y1=-World.HEIGHT;  //修改y1的值为负的窗口的高(移到最上面去)
		}
	}
	
	/** 重写getImage()获取图片 */
	public BufferedImage getImage() {
		return Images.sky; //直接返回sky图片即可
	}
	
	/** 重写paintObject()画对象 */
	public void paintObject(Graphics g) {
		g.drawImage(this.getImage(),this.x,this.y,null);
		g.drawImage(getImage(),x,y1,null);
	}
	
}

九、奖励接口和得分接口

/** 奖励接口 */
public interface Award {
	public int DOUBLE_FIRE = 0; //火力值
	public int LIFE = 1;        //命
	
	/** 获取奖励类型(0或1) */
	public int getAwardType();
}


/** 得分接口 */
public interface Enemy {
	/** 得分 */
	public int getScore();
}

十、窗口类

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Arrays;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** 整个窗口 */
public class World extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	static final int WIDTH = 400;  //窗口的宽
	static final int HEIGHT = 700; //窗口的高
	
	public static final int START = 0;     //启动状态
	public static final int RUNNING = 1;   //运行状态
	public static final int PAUSE = 2;     //暂停状态
	public static final int GAME_OVER = 3; //游戏结束状态
	private int state = START; //当前状态(默认为启动状态)
	
	protected Sky sky = new Sky();    //天空
	protected Hero hero = new Hero(); //英雄机
	protected FlyingObject[] enemies = {}; //敌人(小敌机、大敌机、小蜜蜂)数组
	protected Bullet[] bullets = {};  //子弹数组
	
	/** 生成敌人(小敌机、大敌机、小蜜蜂)对象 */
	public FlyingObject nextOne() {
		Random rand = new Random(); //随机数对象
		int type = rand.nextInt(20); //0到19
		if(type<5) { //0到4时,返回小蜜蜂对象
			return new Bee();
		}else if(type<12) { //5到11时,返回小敌机对象
			return new Airplane();
		}else { //12到19时,返回大敌机对象
			return new BigAirplane();
		}
	}
	
	int enterIndex = 0; //敌人入场计数
	/** 敌人(小敌机、大敌机、小蜜蜂)入场 */
	public void enterAction() { //每10毫秒走一次
		enterIndex++; //每10毫秒增1
		if(enterIndex%40==0) { //每400(10*40)毫秒走一次
			FlyingObject obj = nextOne(); //获取敌人对象
			enemies = Arrays.copyOf(enemies,enemies.length+1); //扩容
			enemies[enemies.length-1] = obj; //将敌人对象添加到enemies的最后一个元素上
		}
	}
	
	int shootIndex = 0; //子弹入场计数
	/** 子弹入场 */
	public void shootAction() { //每10毫秒走一次
		shootIndex++; //每10毫秒增1
		if(shootIndex%30==0) { //每300(10*30)毫秒走一次
			Bullet[] bs = hero.shoot(); //获取子弹对象
			bullets = Arrays.copyOf(bullets,bullets.length+bs.length); //扩容(bs有几个元素就扩大几个容量)
			System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); //数组的追加
		}
	}
	
	/** 飞行物移动 */
	public void stepAction() { //每10毫秒走一次
		sky.step(); //天空动
		for(int i=0;i<enemies.length;i++) { //遍历所有敌人
			enemies[i].step(); //敌人动
		}
		for(int i=0;i<bullets.length;i++) { //遍历所有子弹
			bullets[i].step(); //子弹动
		}
	}
	
	/** 删除越界的敌人和子弹--避免内存泄漏 */
	public void outOfBoundsAction() { //每10毫秒走一次
		int index = 0; //1)不越界敌人数组下标  2)不越界敌人个数
		FlyingObject[] enemyLives = new FlyingObject[enemies.length]; //不越界敌人数组
		for(int i=0;i<enemies.length;i++) { //遍历所有敌人
			FlyingObject f = enemies[i]; //获取每一个敌人
			if(!f.outOfBounds() && !f.isRemove()) { //不越界并且非删除状态的
				enemyLives[index] = f; //将不越界敌人添加到不越界敌人数组中
				index++; //1)不越界敌人数组下标增一 2)不越界敌人个数增一
			}
		}
		enemies = Arrays.copyOf(enemyLives, index); //将不越界敌人数组复制到enemies中,enemies的长度为index(有几个不越界的则长度为几)
		
		index = 0; //归零
		Bullet[] bulletLives = new Bullet[bullets.length];
		for(int i=0;i<bullets.length;i++) {
			Bullet b = bullets[i];
			if(!b.outOfBounds() && !b.isRemove()) {
				bulletLives[index] = b;
				index++;
			}
		}
		bullets = Arrays.copyOf(bulletLives, index);
		
	}
	
	int score = 0; //玩家的得分
	/** 子弹与敌人的碰撞 */
	public void bulletBangAction() { //每10毫秒走一次
		for(int i=0;i<bullets.length;i++) { //遍历所有子弹
			Bullet b = bullets[i]; //获取每个子弹
			for(int j=0;j<enemies.length;j++) { //遍历所有敌人
				FlyingObject f = enemies[j]; //获取每个敌人
				if(f.isLife() && b.isLife() && f.hit(b)) { //撞上了
					f.goDead(); //敌人去死
					b.goDead(); //子弹去死
					if(f instanceof Enemy) { //若被撞敌人能得分
						Enemy e = (Enemy)f; //将被撞敌人强转为得分接口
						score += e.getScore(); //玩家得分
					}
					if(f instanceof Award) { //若被撞敌人为奖励
						Award a = (Award)f; //将被撞敌人强转为奖励接口
						int type = a.getAwardType(); //获取奖励类型
						
						switch(type) { //根据奖励类型来获取不同的奖励
						case Award.DOUBLE_FIRE:   //若奖励类型为火力值
							hero.addDoubleFire(); //则英雄机增火力
							break;
						case Award.LIFE:    //若奖励类型为命
							hero.addLife(); //则英雄机增命
							break;
						}
						
					}
				}
			}
		}
	}
	
	/** 英雄机与敌人的碰撞 */
	public void heroBangAction() { //每10毫秒走一次
		for(int i=0;i<enemies.length;i++) { //遍历所有敌人
			FlyingObject f = enemies[i]; //获取每个敌人
			if(f.isLife() && hero.isLife() && f.hit(hero)) { //撞上了
				f.goDead(); //敌人去死
				hero.subtractLife(); //英雄机减命
				hero.clearDoubleFire(); //英雄机清空火力值
			}
		}
	}
	
	/** 检测游戏结束 */
	public void checkGameOverAction() { //每10毫秒走一次
		if(hero.getLife()<=0) { //游戏结束了
			state = GAME_OVER;  //修改当前状态为游戏结束状态
		}
	}
	
	/** 启动程序的运行 */
	public void action() {
		//侦听器对象
		MouseAdapter l = new MouseAdapter() {
			/** 重写mouseMoved()鼠标移动事件 */
			public void mouseMoved(MouseEvent e) {
				if(state==RUNNING) { //仅在运行状态下执行
					int x = e.getX(); //获取鼠标的x坐标
					int y = e.getY(); //获取鼠标的y坐标
					hero.moveTo(x, y); //英雄机随着鼠标移动
				}
			}
			/** 重写mouseClicked()鼠标点击事件 */
			public void mouseClicked(MouseEvent e) {
				switch(state) { //根据当前状态做不同的处理
				case START:        //启动状态时
					state=RUNNING; //修改为运行状态
					break;
				case GAME_OVER:  //游戏结束状态时
					score = 0;   //清理现场(数据归零)
					sky = new Sky();
					hero = new Hero();
					enemies = new FlyingObject[0];
					bullets = new Bullet[0];
					state=START; //修改为启动状态
					break;
				}
			}
			/** 重写mouseExited()鼠标移出事件 */
			public void mouseExited(MouseEvent e) {
				if(state==RUNNING) { //运行状态时
					state=PAUSE;     //修改为暂停状态
				}
			}
			/** 重写mouseEntered()鼠标移入事件 */
			public void mouseEntered(MouseEvent e) {
				if(state==PAUSE) { //暂停状态时
					state=RUNNING; //修改为运行状态
				}
			}
		};
		this.addMouseListener(l); //处理鼠标操作事件
		this.addMouseMotionListener(l); //处理鼠标滑动事件
		
		Timer timer = new Timer(); //定时器对象
		int intervel = 10; //定时间隔(以毫秒为单位)
		timer.schedule(new TimerTask() {
			public void run() { //定时干的那个事(每10毫秒走一次)
				if(state==RUNNING) { //仅在运行状态下执行
					enterAction(); //敌人(小敌机、大敌机、小蜜蜂)入场
					shootAction(); //子弹入场
					stepAction();  //飞行物移动
					outOfBoundsAction(); //删除越界的敌人和子弹
					bulletBangAction();  //子弹与敌人的碰撞
					heroBangAction();    //英雄机与敌人的碰撞
					checkGameOverAction(); //检测游戏结束
				}
				repaint();     //重画(重新调用paint())
			}
		},intervel,intervel); //定时计划表
	}
	
	/** 重写paint()画 */
	public void paint(Graphics g) {
		sky.paintObject(g);  //画天空
		hero.paintObject(g); //画英雄机
		for(int i=0;i<enemies.length;i++) { //遍历所有敌人
			enemies[i].paintObject(g); //画敌人
		}
		for(int i=0;i<bullets.length;i++) { //遍历所有子弹
			bullets[i].paintObject(g); //画子弹
		}
		
		g.drawString("SCORE: "+score,10,25); //画分
		g.drawString("LIFE: "+hero.getLife(),10,45); //画命
		
		switch(state) { //根据当前状态画不同的图
		case START: //启动状态时画启动图
			g.drawImage(Images.start,0,0,null);
			break;
		case PAUSE: //暂停状态时画暂停图
			g.drawImage(Images.pause,0,0,null);
			break;
		case GAME_OVER: //游戏结束状态时画游戏结束图
			g.drawImage(Images.gameover,0,0,null);
			break;
		}
		
	}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		World world = new World();
		frame.add(world);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(WIDTH,HEIGHT);
		frame.setLocationRelativeTo(null); 
		frame.setVisible(true); //1)设置窗口可见  2)尽快调用paint()    
		
		world.action(); //启动程序的运行
	}
	
}




总结

        以上就是今天要讲的内容,小猿将整个项目源码放在了下面的百度网盘链接里面,方便大家获取。关注一下,惊喜不断哟。

链接:https://pan.baidu.com/s/1uhg525qS7weIAiP2IE6Q-g
提取码:1234

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值