day08———射击游戏(完结)

面向对象(OOP):

类和对象:

shoot射击游戏项目一

需求分析

1.运行项目看结果

A:

小敌机、大敌机、蜜蜂--------敌人

英雄机发射子弹

子弹打中敌人

B:

子弹击中小敌机------玩家得1分

子弹击中打敌机------玩家得5分

子弹击中小蜜蜂------玩家得1命或者得火力值30

C:单倍火力、双倍火力的变化

英雄机的火力值变为0的时候,就成了单倍火力

火力值大于0 的时候,变为双倍火力;依次减少2

D:碰撞

敌人可以与英雄机发生碰撞,碰撞之后,英雄机的生命值减少,变为0的时候,游戏结束。

2.技术分析

设计类:

A:找对象:(6个)

英雄机、小敌机、大敌机、小蜜蜂、子弹、天空

B:抽类:

Hero、Airplane、BigAirplane、Bee、Bullet、Sky

C:设计成员变量和方法

D:测试

shoot射击游戏项目二

1.需求分析

A:设计一个父类、超类;冰洁让6个对象继承超类,测试

B:给超类添加构造方法;让6个对象分别调用超类

C:设置对象数组,进行测试

D:在6个子类、派生类中重写

E:画窗体

2.技术分析

3.代码实现

shoot射击游戏项目三

1.需求分析

A:给类中添加修饰符

B:给6个派生类中添加图片属性

1)6个派生类中添加static属性

2)在父类中添加静态方法loadimage()加载图片

3)6个派生类中static代码块,调用loadimage()方法

2.技术实现

修饰符:

					public			protected			default			private
同一个类  	  			√   	   		 √ 		   	   	√			   	   √   
同一个包中不同类	  		√   	    	 √    	  		√   	       
不同包子类  	  			√   	    	 √    	       	       
不同包中的类 	  			√   	         	       	       

shoot射击游戏项目四

1.需求分析

A:将窗体的大小设置为常量

B:画对象

想画对象先获取到图片,针对每一个对象都能够获取到图片,获取到图片的行为是共有的,设计到父类中;

每一个对象得到图片的行为都是不一样的,设计了一个抽象方法-----getimages();

在不同状态下,得到不同的图片:

状态:设计到父类中,设计常量:LEFT;DEAD;REMOVE;

默认状态:state =LEFT

获取图片的同时,需不需要判断当前的状态???需要

每一个对象都需要判断,设计到超类/父类中

而每一个对象判断的行为都是一样的,设计普通方法即可;

---------FlyingObject:isLife()/isDead()/isRemove()

C:在6个子类对象中重写getimages()方法

  • 背景sky:直接返回即可
  • 子弹bullet:如果只存活的,返回images即可
    如果是over的,删除即可
  • 英雄机:如果是存活的,返回images[0]/images[1]
  • 小敌机、大敌机、蜜蜂:如果是存活的,返回images[0]
    如果是over的,images[1]到images[4]进行切换,切换完毕,到了images[4]后进行删除;

D:得到不同状态下的图片,进行开始画出来;

画对象的行为是共有的没所以设计到超类中;

每一个对象画的方式都是一样的,所以设计为普通方法

E:测试,调用即可;

设计规则:

  • 将所有子类所共有的行为和属性,可以设计到超类中;-----抽共性
  • 所有子类的行为都是一样的,设计为普通方法;所有子类的行为都是不一样的,设计为抽象方法;

shoot射击游戏项目五

1.需求分析

A:敌人入场

  • 产生敌人;在主函数(ShootMain)类中nextOne()
  • 需要定时加载敌人—enterAction()实现敌人入场
  • 每400毫秒,获取到敌人,扩容,将敌人添加到数组的最后一位

B:子弹入场

  • 英雄机中发射子弹,Hero类设计一个方法用来实现子弹的发射----shoot()
  • run()方法中,子弹的发射shootAction()
  • 每400毫秒,获取到子弹,扩容,将子弹数组添加到数组的最后一位

C:飞行物的移动

  • 敌人的移动
  • 子弹的移动
  • 天空的移动

D:英雄机随着鼠标进行移动

  • 在hero中设计方法:movedTo()实现英雄机的移动
  • 在shootMian中建立监听机制,检测鼠标的移动事件

E:删除越界的飞行物

  • 在FlyingObject中涉及一个方法outOfBounds()-----检测是否越界
  • 在run()方法中,写一个方法outOfBoundsAction()—删除越界的飞行物
    • 遍历敌人、子弹数组,如果对象不越界,那么将存放到不越界的数组中,将不越界的数组复制到敌人、子弹数组中

F:设计接口:

  • 击中小敌机+大敌机-------得1分 或3分-------Enemy
  • 击中蜜蜂-----随机得生命或者火力-----Award

shoot射击游戏项目六

1.需求分析
A:子弹与敌人碰撞

  • 设计到父类中,hit()方法,实现检测子弹与敌人发生碰撞

  • 在父类中设计一个goDead()实现飞行物over;

  • 在Hero类中设计实现addLife(),addDoubleFire()

  • 通过Airplane和BigAirplane中的接口来实现玩家得分

  • 通过Bee中的接口实现玩家得奖励

  • [1] Hero

     package shoot;
     
     import java.awt.image.BufferedImage;
     
     /**
      * 英雄机:
      * 
      * @author YANG
      *
      */
     	public class Hero extends FlyingObject {
     		private static BufferedImage[] images;
     		// 静态代码块
     		static {
     			images = new BufferedImage[2];
     			for (int i = 0; i < images.length; i++) {
     				images[i] = loadImage("hero" + i + ".png");
     			}
     		}
     		// 成员变量
     		private int life;// 生命值
     		private int doubleFire;// 火力
     		public Hero() {
     			super(97, 124, 140, 400);
     			life = 6;
     			doubleFire = 0;// 单倍火力
     		}
     			
     	public void movedTo(int x, int y) {
     		this.x = x - this.width/2;
     		this.y = y - this.height/2;
     	}
     //	移动
     	public void step() {
     		System.out.println("图片的切换");
     	}
     //	英雄机发射子弹
     	public Bullet[] shoot(){
     		int xStep= this.width/4;
     		int yStep=15;
     		if (doubleFire>=500) {
     			Bullet[] bs = new Bullet[3];
     			bs[0]=new Bullet(this.x+xStep*1, this.y-yStep);
     			bs[1]=new Bullet(this.x+xStep*6, this.y-yStep);
     			bs[2]=new Bullet(this.x+xStep*9, this.y-yStep);	
     			return bs;
     		}
     		else if(doubleFire>100&&doubleFire<500){//双倍火力
     			Bullet[] bs = new Bullet[2];
     			bs[0]=new Bullet(this.x+xStep*1, this.y-yStep);
     			bs[1]=new Bullet(this.x+xStep*3, this.y-yStep);
     			return bs;
     		}else{//单倍火力
     			Bullet[] bs = new Bullet[1];
     			bs[0]=new Bullet(this.x+xStep*2, this.y-yStep);
     			return bs;
     		}
     	}
     	public void substractLife(){
     		life--;
     	}
     	public void clearDoubleFire(){
     		doubleFire=0;
     	}
     	@Override
     	public BufferedImage getImage() {
     		// TODO Auto-generated method stub
     		return images[0];
     	}
     	public void addDoubleFire(){
     		doubleFire += 30;
     	}
     	public void addLife(){
     		life++;
     	}
     	public int getLife() {
     		// TODO 自动生成的方法存根
     		return life;
     	}
     }
    
  • [2] Airplane

     package shoot;
     import java.awt.image.BufferedImage;
     /**
      * 小敌机:
      * @author YANG
      *
      */
     public class Airplane extends FlyingObject implements Enemy{
     	private static BufferedImage[] images;
     	//静态代码块
     	static {
     		images = new BufferedImage[5];
     		for (int i = 0; i < images.length; i++) {
     			images[i] = loadImage("airplane" + i + ".png");
     		}
     	}
     	private int speed;//速度
     	
     /**构造方法*/
     public Airplane(){
     	super(49,36);
     	this.speed = 2;
     }
     
     /**移动*/
     public void step(){
     	this.y += speed;
     }
    
     //TODO...
     //得到图片
     int index =1;
     @Override
     public BufferedImage getImage() {
     	if (isLife()){
     		return images[0];
     	}else if(isDead()){
     		BufferedImage img = images[index++];
     		if(index == images.length){
     			state =REMOVE;
     		}
     		return img;
     	}
     return null;
     }
     @Override
     public int getScore() {
     	// TODO 自动生成的方法存根
     	return 1;
     }
     }
    
  • [3] BigAirplane

     package shoot;
     import java.awt.image.BufferedImage;
     /**
      * 大敌机:
      * @author YANG
      *
      */
     public class BigAirplane extends FlyingObject implements Enemy{
     	private static BufferedImage[] images;
     	//静态代码块
     	static {
     		images = new BufferedImage[5];
     		for (int i = 0; i < images.length; i++) {
     			images[i] = loadImage("bigplane" + i + ".png");
     		}
     	}
     int speed;//速度
     /**构造方法*/
     public BigAirplane(){
     	super(23,33);
     	this.speed = 4;
     }
     public void step(){
     	this.y += speed;
     }
     int index =1;
     @Override
     public BufferedImage getImage() {
     	// TODO Auto-generated method stub
     	if (isLife()) {
     		return images[0];
     	}else if(isDead()){
     		BufferedImage img = images[index++];
     		if(index == images.length){
     			state =REMOVE;
     		}
     		return img;
     	}
     	return null;
     }
     @Override
     public int getScore() {
     	// TODO 自动生成的方法存根
     	return 3;
     }
     }
    
  • [4] Bee

   package shoot;
    		import java.awt.image.BufferedImage;
    		import java.util.Random;
    		/**
    		 * 蜜蜂:
    		 * @author YANG
    		 *
    		 */
    		public class Bee extends FlyingObject implements Award{
    			private int xSpeed;//x坐标的速度
    			private int ySpeed;//y坐标的速度
    			private int awardType;//获取奖励的类型
    			private static BufferedImage[] images;
    			//静态代码块
    			static {
    				images = new BufferedImage[5];
    				for (int i = 0; i < images.length; i++) {
    					images[i] = loadImage("bee" + i + ".png");
    				}
    			}
    			public Bee(){
    				super(100,400);
    				xSpeed = 2;
    				ySpeed = 4;
    				Random rand = new Random();
    				awardType = rand.nextInt(2);//0 1
    			}
    		public void step(){
    			x += xSpeed;
    			y += ySpeed;
    			if (x < 0 || x >= ShootMain.SCREEN_WIDTH - width) {
    				xSpeed *= -1;
    			}
    		}
    		int index =1;
    		@Override
    		public BufferedImage getImage() {
    			if (isLife()){
    				return images[0];
    			}else if(isDead()){
    				BufferedImage img = images[index++];
    				if(index == images.length){
    					state =REMOVE;
    				}
    				return img;
    			}
    			/**
    			 * index  =1;
    			 * 10m images[1]
    			 * */
    			return null;
    		}
    		@Override
    		public int getAwardType() {
    			// TODO 自动生成的方法存根
    			return awardType;
    		}
    		}
  • [5]Sky

     package shoot;
     import java.awt.Graphics;
     import java.awt.image.BufferedImage;
     
     /**
      * 天空:
      * @author YANG
      *
      */
     public class Sky extends FlyingObject{
     	private static BufferedImage images;
     	//静态代码块
     	static {
     		images = loadImage("background.png");
     	}
     	private int speed;//速度
     	public int y1;//第二张图片的坐标
     	/**构造方法*/
     	public Sky(){
     		super(ShootMain.SCREEN_WIDTH, ShootMain.SCREEN_HEIGHT, 0, 0);
     		speed = 1;
     		y1 = -ShootMain.SCREEN_HEIGHT;
     	}
     	/**天空移动*/
     	public void step(){
     		y+= speed;
     		y1+=speed;
     		if (y>=ShootMain.SCREEN_HEIGHT) {
     			y=-ShootMain.SCREEN_HEIGHT;
     		}
     		if (y1>=ShootMain.SCREEN_HEIGHT) {
     			y1=-ShootMain.SCREEN_HEIGHT;
     		}
     	}
    
     @Override
     public BufferedImage getImage() {
     	// TODO Auto-generated method stub
     	return images;
     }
     public void paintObject(Graphics g){
     	g.drawImage(getImage(), x, y, null);
     	g.drawImage(getImage(), x, y1, null);
     }
     }
    
  • [6] Bullet

package shoot;
import java.awt.image.BufferedImage;

/**
 * 子弹
 * @author YANG
 *
 */
public class Bullet extends FlyingObject{

	private static BufferedImage images;
	//静态代码块
	static {
		images = loadImage("bullet.png");
	}
	private int speed;//速度
	/**构造方法*/
	public Bullet(int x, int y){
		super(8, 14, x, y);
		speed = 1;
	}
	/**子弹的移动*/
	public void step(){
		this.y -= speed;
	}
	//重写getImage()中的方法获取图片
	@Override
	public BufferedImage getImage() {
		// TODO Auto-generated method stub
		if (isLife()) {
			return images;
		}else if(isDead()){
			state = REMOVE;
		}
		return null;
	}
	public boolean outOfBounds() {
		// TODO 自动生成的方法存根
		return this.y<=-this.height;
	}
}

  • [7] ShootMain
package shoot;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.text.StyledEditorKit.ForegroundAction;

/**
 * 主函数的类:
 * 
 * @author YANG
 *
 */
public class ShootMain extends JPanel {
	public static final int SCREEN_WIDTH  = 400;
	public static final int SCREEN_HEIGHT = 700;
//	起始状态START、RUNNING、PAUSE、GAME_OVER
//	默认起始状态
	/**
	 * 鼠标点击事件:
	 * 启动状态:结束----启动
	 * 暂停状态:鼠标从屏幕里滑道外;
	 * 运行状态:从外到里
	 * 结束状态:英雄机的生命值为0
	 */
	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;
	public int state = START;
	public static BufferedImage start;
	public static BufferedImage pause;
	public static BufferedImage gameover;
	static{
		start = FlyingObject.loadImage("start.png");
		pause = FlyingObject.loadImage("pause.png");
		gameover = FlyingObject.loadImage("gameover.png");
	}
	
	private Sky sky = new Sky();
	private Hero hero = new Hero();
	private FlyingObject[] flys ={};
	private Bullet[]  bullets ={};
	
	public FlyingObject nextOne(){
		Random rand  =new Random();
		int type = rand.nextInt(20);
		if(type<5){
			return new Airplane();
		}else if(type < 12){
			return new Bee();
		}else{
			return new BigAirplane();
		}
	}
//	实现敌人入场
	int enterindex=0;
	public void enterAction(){
		enterindex++;
		if (enterindex % 40 == 0) {
//			获取到敌人
			FlyingObject f = nextOne();
			flys = Arrays.copyOf(flys, flys.length+1);
			flys[flys.length-1]=f;
//			敌人添加到数组的最后一位
		}
	}
//	子弹入场
	int shootIndex=0;
	public void shootAction(){
		shootIndex++;
		if (shootIndex % 40 == 0) {
			Bullet[] bs = hero.shoot();//获取子弹数组
			bullets =Arrays.copyOf(bullets, bullets.length+bs.length);
//			将产生的子弹数组放到原数组中的最后
			System.arraycopy(bs, 0, bullets, bullets.length-bs.length, bs.length);
			
		}
		
	}
//	飞行物移动
	
	public void stepAction(){
		sky.step();
		for (int i = 0; i < flys.length; i++) {
			flys[i].step();
		}
		for (int i = 0; i < bullets.length; i++) {
			bullets[i].step();
		}
	}
	
	public void outOfBoundsAction(){
		int index = 0; //存放不越界的数组下标
//		新建不越界的敌人数组
		FlyingObject[] flysLive = new FlyingObject[flys.length];
		for (int i = 0; i < flys.length; i++) {
//			获取到每一个敌人
			FlyingObject f =flys[i] ;
//			判断是否不越界
			if(!f.outOfBounds()){
				flysLive[index] = f;
				index++;
			}
//			如果不越界,
//			将不越界的敌人存放到不越界的数组中

			
		}
		
		flys =Arrays.copyOf(flysLive, index);
		index = 0;
		Bullet[] bulletsLive = new Bullet[bullets.length];
		
		for (int i = 0; i < bullets.length; i++) {
			Bullet b = bullets[i];
			if (!b.outOfBounds()) {
				bulletsLive[index] = b;
				index++;
			}
		}
		bullets = Arrays.copyOf(bulletsLive, index);
	}
	int score =0;
//	子弹与敌人的碰撞
	public void bulletBangAction(){
		//遍历所有的子弹
		for (int i = 0; i < bullets.length; i++) {
			//获取每一个子弹
			Bullet b = bullets[i];
//			遍历所有的敌人
			for (int j = 0; j < flys.length; j++) {
				FlyingObject  f = flys[j];
				if(f.hit(b)&&b.isLife()&&f.isLife()){
					f.goDead();//敌人over
					b.goDead();//子弹over
					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(){
/**
 * 思路:
 * (1)借助FlyingObject中的hit()方法检测碰撞
 * (2)借助FlyingObject中的goDead()方法over
 * (3)在hero类中设计一个方法实现碰撞之后substractLife()减少生命,clearDoubleFire()
 * (4)在run()方法中实现英雄机与敌人发生碰撞
 *  heroBangAction();
 *  遍历敌人获取到每一个敌人
 *  判断撞上了
 *  敌人over,英雄机减少生命,清空火力。
 *
 */
//		遍历所有的敌人
		for (int i = 0; i < flys.length; i++) {
			FlyingObject f = flys[i];
			if (hero.isLife()&&f.isLife()&&f.hit(hero)) {
				f.goDead();
				hero.substractLife();
				hero.clearDoubleFire();
			}
		}
	}
//	检测游戏是否结束
	public void checkGameOver(){
//		判断英雄机的生命值如果小于零的话,游戏结束,修改状态。
		if (hero.getLife() <= 0) {
			state  =GAME_OVER;
			
		}
	}

	public void action() {
//		鼠标的点击事件
//		鼠标适配器
		MouseAdapter ma =new MouseAdapter() {
			/**重写*/
			public void mouseMoved(MouseEvent e){
				int x = e.getX();
				int  y = e.getY();
//				System.out.println(x+","+y);
				hero.movedTo(x, y);
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO 自动生成的方法存根
				switch (state) {
				case START:
					state =RUNNING;
					break;
				case GAME_OVER:
					score =0;
					sky = new Sky();
					hero = new Hero();
					flys = new FlyingObject[0];
					bullets = new Bullet[0];
					state = START;
					break;

				default:
					break;
				}
			}
			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO 自动生成的方法存根
				if (state == PAUSE) {
					state = RUNNING;
				}
			}
			@Override
			public void mouseExited(MouseEvent e) {
				// TODO 自动生成的方法存根
				if (state==RUNNING) {
					state = PAUSE;
				}
			}
		
		};
		this.addMouseListener(ma);//处理鼠标的操作事件
		this.addMouseMotionListener(ma);//处理鼠标的移动事件
//		定时器  
		Timer timer =new Timer();
		int inters = 10;
		timer.schedule(new TimerTask() {	
			@Override
			public void run() {
				
				// TODO 自动生成的方法存根
				if (state == RUNNING) {
//					敌人入场
					stepAction();
					enterAction();
//					子弹入场
					shootAction();
//					删除越界的飞行物
					outOfBoundsAction();
					bulletBangAction();
					heroBangAction();
					checkGameOver();
				}

//				重绘
				repaint();
			}	
		}, inters, inters);//计划任务
	}
	public void paint(Graphics g) {
		super.paint(g);
		sky.paintObject(g);
		hero.paintObject(g);
		for (int i = 0; i < flys.length; i++) {
			flys[i].paintObject(g);
		}
		for (int i = 0; i < bullets.length; i++) {
			bullets[i].paintObject(g);
		}
		g.drawString("分数:"+score, 30, 60);
		g.drawString("生命:"+hero.getLife(), 30, 80);
		switch (state) {
		case START:
			g.drawImage(start, 0, 0, null);
			break;
		case PAUSE:
			g.drawImage(pause, 0, 0, null);
			break;
		case GAME_OVER:
			g.drawImage(gameover, 0, 0, null);
			break;

		default:
			break;
		}
	}
	
	public static void main(String[] args) {
		ShootMain sm = new ShootMain();
		JFrame jf = new JFrame();
		jf.add(sm);// 将画布装在窗体上
		jf.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);// 窗体大小
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setLocationRelativeTo(null);// 居中显示
		jf.setVisible(true);
		sm.action();
	}
	

}

  • [8] FlyingObject
package shoot;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;

/**
 * 父类:飞行物
 * @author YANG
 * 
 */
public abstract class FlyingObject {

	// 成员变量
	protected int width;// 宽
	protected int height;// 高
	protected int x;// x坐标
	protected int y;// y坐标
	public static final int LIFE = 0;//存活
	public static final int DEAD = 1;//over
	public static final int REMOVE = 2;//删除
	public int state = LIFE;// 当前状态


	
	public FlyingObject(int width, int height) {
		this.width = width;
		this.height = height;
		Random rand = new Random();

		this.x = rand.nextInt(ShootMain.SCREEN_WIDTH - this.width);
		this.y = -this.height;
	}

	public FlyingObject(int width, int height, int x, int y) {
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}

	public void step() {
		System.out.println("飞行物移动!");
	}

	public static BufferedImage loadImage(String fileName) {
		try {

			BufferedImage img = ImageIO.read(FlyingObject.class
					.getResource(fileName));
			return img;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}

	public abstract BufferedImage getImage();

	public void paintObject(Graphics g) {
		g.drawImage(this.getImage(),x, y, null);
	}
	//判断当前状态是不是存活的
	public boolean isLife(){
		return state ==LIFE;
	}
	//判断当前状态是不是存活的
	public boolean isDead(){
		return state ==DEAD;
	}
	//判断当前状态是不是存活的
	public boolean isRemove(){
		return state ==REMOVE;
	}
//	检测是否越界
	public boolean outOfBounds(){
		return this.y>=ShootMain.SCREEN_HEIGHT;
		
	}
//	检测子弹与敌人发生碰撞this:
	public boolean hit(FlyingObject other){
		int x1 = this.x - other.width;
		int y1 = this.y - other.height;
		int x2 = this.x + this.width;
		int y2 = this.y +this.height;
		int x = other.x;
		int y = other.y;
		return x >= x1 && x <= x2 && y >= y1 && y <= y2;
	}
	public void goDead(){
		state = DEAD;//将对象的状态修改为DEAD;
	}
}

  • [9] Enemy
package shoot;
/**
 * 得分接口
 * @author YANG
 *
 */
public interface Enemy {
//	得分接口
	public int getScore();
}

  • [10] Award
package shoot;
/**
 * 奖励接口
 * @author YANG
 *
 */
public interface Award {
	public int DOUBLE_FIRE =0;
	public int LIFE =1;
//	获取奖励类型
	public int getAwardType();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值