游戏推箱子(c语言)

一、项目背景

​ 游戏推箱子既能锻炼思维的严密性,又有很多乐趣。本章将用C语言实现一个简单的推箱子游戏,旨在介绍推箱子游戏的实现方法,并逐步介绍C语言图形编程的方法和技巧。

二、设计目的

  • 如何实现二维数组定义,操作等功能
  • 如何从键盘输入中获取键值信息
  • 如何在图形方式下实现光标的显示和定位
  • 如何对图像函数进行使用
  • 如何通过C语言实现游戏的基本控制操作和相关设置

三、项目功能需求

1、屏幕绘图输出

能够实现绘制城墙,在空地上绘制箱子,在目的地绘制箱子,绘制小人和绘制目的地等功能

2、移动箱子

能够实现箱子的移动,包括目的地之间,空地之间和目的地与空地之间的箱子移动等功能

3、移动小人

能够实现小人的移动,从而推动箱子到目的地

4、游戏功能控制

能够实现根据用户的键盘输入,指定位置状态判断功能和游戏操作等功能

5、关口选择

能够实现游戏关卡的选择,游戏共分为4关,以便用户选择所需要的关卡数

四、系统的功能结构图

在这里插入图片描述

五、功能模块介绍

1、绘制地图模块

  • 绘制出每一关卡的基本地图,包括绘制城墙,在空地上绘制箱子,在目的地绘制箱子,绘制小人和绘制目的地。
  • 根据用户的每次操作绘制出操作后变化的地图信息**。**

2、移动控制模块

  • 根据用户的输入信息来实现对小人的控制
  • 根据用户的输入信息来判断箱子的移动状态

3、关口选择模块

  • 根据用户的输入的关卡选择相应的关数,并且在用户过关后自动进入下一关
  • 每关对应不同的地图形状,共分为四关,每关的难度依次增大

4、游戏操作模块

  • 判断用户游戏是否过关,以及捕获用户的键盘输入信息

六、详细设计

1、主函数

功能设计

  • 用于实现主界面的显示,并响应用户对菜单项的选择。
  • 主菜单为用户提供了3种不同的操作选项,当用户在界面上输入需要的操作选项时,系统会自动执行该选项对应的功能。
  • 个功能执行完之后,还能自动回到主菜单,便于用户进行其他操作。

主函数程序流程图
在这里插入图片描述

2、绘制地图模块

功能设计

  • 绘制出每一关卡的基本地图。
  • 地图的绘制包括绘制城墙,在空地上绘制箱子,在目的地绘制箱子,绘制小人和绘制目的地等操作。
  • 根据用户的每次操作绘制出操作后变化的地图信息。
  • 模块也包含了对文字颜色的具体设置

3、移动控制模块

功能设计

  • 根据用户的键盘输入信息来实现对小人的控制。
  • 需要分情况判断小人的状态,判断用户输入的操作能否被执行**。**
  • 根据用户输入信息来判断箱子的移动状态。

模块流程图

在这里插入图片描述

4、关口选择模块

功能设计

  • 根据用户的输入的关卡选择相应的关数。
  • 每关对应不同的地图形状,地图由二维数组表示,共分为四关,每关的难度依次增大。
  • 在用户过关后自动进入下一关**。**

模块流程图

在这里插入图片描述

5、游戏操作模块

功能设计

  • 判断用户游戏是否过关,即与箱子匹配的目的地数目是否等于目的地个数。
  • 捕获用户的键盘输入信息:如用户输入N表示进入下一关,用户输入Q表示返回主界面。
  • 用户输入键盘上下左右键实现控制信息。

游戏操作模块流程图

在这里插入图片描述

七、代码

/*****推箱子游戏*****/
#include	<stdio.h>
#include	<stdlib.h>
#include	<conio.h>
#include	<windows.h>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77

#define KEY_RETURN 2
#define KEY_NEXT 4

#define SPACE_OUT 0
#define WALL 1
#define SPACE 2
#define TARGET 3
#define BOX 4
#define TARGET_IN 5
#define PERSON 6


/*函数声明*/
void SelectColor(int iColor);
void DesignUI();
int WelcomePage();/*初始界面,每次通关后跳回*/
void GetLevel1();
void GetLevel2();
void GetLevel3();
void GetLevel4();
int PlayGame(int aiMap[][16], int aiMap2[][16], int iSum, int iImp);
int PrintMap(int aiMap[][16], int iImp);
void MoveBox(int aiMap[][16], int iPlayerX, int iPlayerY, int iSelect, int aiMap2[][16]);

/*主函数*/
int main() {
	while (1)
		DesignUI();
}

/*文字颜色函数*/
void  SelectColor(int iColor)                  //颜色函数
{
	HANDLE  hConsole =
		GetStdHandle((STD_OUTPUT_HANDLE));//得到控制台输出设备的句柄
	SetConsoleTextAttribute(hConsole, iColor);//设置控制台设备的属性
}

/*主界面函数*/
void DesignUI()
{
	int iCh;
	char cNum;
	iCh = WelcomePage();
	if (iCh == 49)/*键盘输入1,开始第一关游戏*/
		GetLevel1();
	else if (iCh == 50){/*键盘输入2,选择1到4关的游戏*/
		printf("\n\t\t Please input level!(From 1 to 4):");
		getchar();
		cNum = getchar();
		switch (cNum){
		case '1':
			GetLevel1();
			break;
		case '2':
			GetLevel2();
			break;
		case '3':
			GetLevel3();
			break;
		case '4':
			GetLevel4();
			break;
		default:
			printf("Enter error!\n");
			Sleep(1000);
			exit(0);
			break;
		}
	}
	else if (iCh == 51){/*键盘输入3,退出游戏*/
		system("cls");
		exit(0);
	}
}

/*初始欢迎界面*/
int WelcomePage()
{
	int i = 0;
	system("cls");/*清屏*/
	system("color 0E");/*设置颜色*/
	printf("\n\n\t\t Welcome to play box!\n\n");
	printf("\t\t Person:♀  Wall:▓ Box: ●  Target:○  Reach target:☆\n");
	printf("\t\t Up:↑\n\t\t Down:↓\n\t\t Left:← \n\t\t Right:→\n\n");
	printf("\t\t Press number 1 to start new game\n\t\t\n");
	printf("\t\t Press number 2 to choose level\n\t\t\n");
	printf("\t\t Press number 3 to quit from game\n\t\t\n");
	printf("\t\t Press right number to continue:");
	while (1)
	{
		i = getchar();
		if (i >= 49 && i <= 51)
			return i;
	}
}

/*打印地图函数*/
int PrintMap(int aiMap[][16], int iImp) {/*参数iImp代表游戏关卡*/
	int i, j;
	int iCount = 0;
	for (i = 0; i<14; i++){
		for (j = 0; j<16; j++)
		{
			switch (aiMap[i][j])
			{
			case 0:                /*空地*/
				printf("  ");
				break;
			case 1:
				SelectColor(14);    /*墙*/
				printf("▓");
				break;
			case 2:                /*内部空地*/
				printf("  ");
				break;
			case 3:
				SelectColor(11);    /*目的地*/
				printf("○");
				break;
			case 4:                /*箱子*/
				SelectColor(11);
				printf("●");
				break;
			case 5:                /*箱子推到目的地后显示*/
				iCount++;
				SelectColor(9);
				printf("☆");
				break;
			case 6:                /*小人*/
				SelectColor(10);
				printf("♀");
				break;
			}
		}
		printf("\n");
	}
	SelectColor(14);
	printf("\n");
	printf("\tYou are in Level %d!\t\t\n", iImp);
	printf("\tPress arrow keys to play the game!\t\n");
	printf("\tpress N to the next level!\t\n");
	printf("\tpress Q to return the home page!\t\n");
	return iCount; /*返回值表示以正确放入的箱子数*/
}

/*第一关*/
void  GetLevel1()  {
	int  aiMap2[14][16];/*表示原始地图*/
	int  i, j, iSum = 0; /*iSum表示箱子的数量*/

	/*地图形状
	1代表墙,2代表空地,3代表未放箱子的目标,4代表箱子,5代表以放箱子的目标,6代表小人
	*/
	int aiMap[14][16] = {
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 3, 4, 2, 1, 1, 2, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 3, 4, 6, 4, 2, 2, 3, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 3, 2, 4, 2, 4, 3, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	};
	for (i = 0; i<14; i++)
	for (j = 0; j<16; j++){
		aiMap2[i][j] = aiMap[i][j];
		if (aiMap[i][j] == TARGET || aiMap[i][j] == TARGET_IN)/*记录箱子个数*/
			iSum++;
	}

	/*PlayGame函数返回值为4的情况代表键盘输入Q返回到主界面,
	其他情况(过关,进入下一关)执行GetLevel2函数,进入第二关
	*/
	if (PlayGame(aiMap, aiMap2, iSum, 1) != KEY_RETURN)
		GetLevel2();
}

/*第二关*/
void  GetLevel2()  {
	int  aiMap2[14][16];/*表示原始地图*/
	int  i, j, iSum = 0; /*iSum表示箱子的数量*/

	/*地图形状
	1代表墙,2代表空地,3代表未放箱子的目标,4代表箱子,5代表以放箱子的目标,6代表小人
	*/
	int aiMap[14][16] = {
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 2, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 2, 2, 4, 2, 2, 2, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 2, 1, 1, 1, 2, 4, 1, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 1, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0 },
		{ 0, 0, 1, 1, 2, 1, 3, 3, 1, 1, 2, 1, 1, 0, 0, 0 },
		{ 0, 0, 1, 2, 4, 2, 2, 4, 2, 2, 4, 2, 1, 0, 0, 0 },
		{ 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 6, 2, 1, 0, 0, 0 },
		{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	};

	for (i = 0; i<14; i++)
	for (j = 0; j<16; j++){
		aiMap2[i][j] = aiMap[i][j];
		if (aiMap[i][j] == TARGET || aiMap[i][j] == TARGET_IN)/*记录箱子个数*/
			iSum++;
	}

	/*PlayGame函数返回值为4的情况代表键盘输入Q返回到主界面,
	其他情况(过关,进入下一关)执行GetLevel3函数,进入第三关
	*/
	if (PlayGame(aiMap, aiMap2, iSum, 2) != KEY_RETURN)
		GetLevel3();
}

/*第三关*/
void  GetLevel3()  {
	int  aiMap2[14][16];/*表示原始地图*/
	int  i, j, iSum = 0;/*iSum表示箱子的数量*/

	/*地图形状
	1代表墙,2代表空地,3代表未放箱子的目标,4代表箱子,5代表以放箱子的目标,6代表小人
	*/
	int aiMap[14][16] = {
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0 },
		{ 0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 0, 0 },
		{ 0, 0, 1, 2, 4, 2, 1, 1, 1, 1, 4, 2, 2, 1, 0, 0 },
		{ 0, 0, 1, 2, 2, 4, 3, 3, 3, 3, 2, 4, 2, 1, 0, 0 },
		{ 0, 0, 1, 1, 2, 2, 2, 2, 1, 2, 6, 2, 1, 1, 0, 0 },
		{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	};

	for (i = 0; i<14; i++)
	for (j = 0; j<16; j++){
		aiMap2[i][j] = aiMap[i][j];
		if (aiMap[i][j] == TARGET || aiMap[i][j] == TARGET_IN)/*记录箱子个数*/
			iSum++;
	}

	/*PlayGame函数返回值为4的情况代表键盘输入Q返回到主界面,
	其他情况(过关,进入下一关)执行GetLevel5函数,进入第五关
	*/
	if (PlayGame(aiMap, aiMap2, iSum, 3) != KEY_RETURN)
		GetLevel4();
}

/*第四关*/
void  GetLevel4()  {
	int  aiMap2[14][16];/*表示原始地图*/
	int  i, j, iSum = 0;/*iSum表示箱子的数量*/

	/*地图形状
	1代表墙,2代表空地,3代表未放箱子的目标,4代表箱子,5代表以放箱子的目标,6代表小人
	*/
	int aiMap[14][16] = {
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 3, 2, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 1, 1, 2, 2, 4, 3, 3, 3, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 1, 2, 2, 4, 2, 1, 5, 3, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 2, 1, 1, 4, 1, 2, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 2, 2, 4, 2, 2, 4, 2, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 0, 0, 0 },
		{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 6, 2, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	};
	for (i = 0; i<14; i++)
	for (j = 0; j<16; j++){
		aiMap2[i][j] = aiMap[i][j];
		if (aiMap[i][j] == TARGET || aiMap[i][j] == TARGET_IN)/*记录箱子个数*/
			iSum++;
	}
	/*PlayGame函数返回值为4的情况代表键盘输入Q返回到主界面,
	其他情况(过关,进入下一关)执行GetLevel7函数,进入第七关
	*/
	PlayGame(aiMap, aiMap2, iSum, 4);
}

/*游戏操作函数*/
int PlayGame(int aiMap[][16], int aiMap2[][16], int iSum, int iImp)/*iSum代表箱子个数*/
{
	int i, j;
	int iPlayerX, iPlayerY;        /*人的位置x,y坐标*/
	char cOp;                    /*所按下的方向键*/
	int iNum = 0;               /*箱子推到目的地的个数*/

	while (1)
	{
		for (i = 0; i < 14; i++)
		{
			for (j = 0; j < 16; j++) /*循环遍历寻找人的位置*/
			{
				if (aiMap[i][j] == PERSON)    /*6代表人的位置*/
					break;
			}
			if (j < 16)
				break;
		}

		iPlayerX = i;           /*将二维数组中的人的x,y坐标赋值给iPlayerX和iPlayerY*/
		iPlayerY = j;
		system("cls");
		iNum = PrintMap(aiMap, iImp);
		if (iNum == iSum)
		{           /*将所有箱子都推到目的地*/
			printf(" Congratulations!\n");
			Sleep(3000);
			return 0;
		}
		else
		{                       /*还有箱子没有推到目的地*/
			cOp = getch();          /*捕获用户键盘输入*/
			if ((cOp == 'n') || (cOp == 'N'))/*输入N进入下一关*/
				return KEY_NEXT;
			else if ((cOp == 'q') || (cOp == 'Q'))/*输入Q返回主界面*/
				return KEY_RETURN;
		}
		switch (cOp)
		{          /*用户输入方向键*/
		case KEY_UP:        /*上箭头*/
			MoveBox(aiMap, iPlayerX, iPlayerY, 1, aiMap2);
			break;
		case KEY_LEFT:        /*左箭头*/
			MoveBox(aiMap, iPlayerX, iPlayerY, 2, aiMap2);
			break;
		case KEY_RIGHT:        /*右箭头*/
			MoveBox(aiMap, iPlayerX, iPlayerY, 3, aiMap2);
			break;
		case KEY_DOWN:        /*下箭头*/
			MoveBox(aiMap, iPlayerX, iPlayerY, 4, aiMap2);
			break;
		default:
			break;
		}
	}
}

/*方向移动函数*/
void MoveBox(int aiMap[][16], int iPlayerX, int iPlayerY, int iSelect, int aiMap2[][16]) {
	int iPlayerX1, iPlayerY1;        /*小人下一个要走的位置坐标*/
	int iPlayerX2, iPlayerY2;        /*小人下下一个要走的位置坐标*/
	switch (iSelect) {
	case 1:        /*向上移动*/
		iPlayerX1 = iPlayerX - 1;
		iPlayerY1 = iPlayerY;
		iPlayerX2 = iPlayerX - 2;
		iPlayerY2 = iPlayerY;
		break;
	case 2:        /*向左移动*/
		iPlayerX1 = iPlayerX;
		iPlayerY1 = iPlayerY - 1;
		iPlayerX2 = iPlayerX;
		iPlayerY2 = iPlayerY - 2;
		break;

	case 3:        /*向右移动*/
		iPlayerX1 = iPlayerX;
		iPlayerY1 = iPlayerY + 1;
		iPlayerX2 = iPlayerX;
		iPlayerY2 = iPlayerY + 2;
		break;

	case 4:        /*向下移动*/
		iPlayerX1 = iPlayerX + 1;
		iPlayerY1 = iPlayerY;
		iPlayerX2 = iPlayerX + 2;
		iPlayerY2 = iPlayerY;
		break;
	default:
		break;
	}

	/*对地图的操作*/
	switch (aiMap[iPlayerX1][iPlayerY1])/*判断小人下一步要走的位置*/
	{
	case WALL:      /*下一位置是墙,不能移动*/
		break;
	case SPACE:     /*下一位置为墙内空地和下一位置为空目的地的情况相同处理*/
	case TARGET: 
		aiMap[iPlayerX1][iPlayerY1] = PERSON;/*小人移动到下一位置*/
		if (aiMap2[iPlayerX][iPlayerY] == TARGET || aiMap2[iPlayerX][iPlayerY] == TARGET_IN)
			/*小人所在位置初始为空目的地或满目的地,小人移动后此处恢复为空目的地*/
			aiMap[iPlayerX][iPlayerY] = TARGET;
		else
			/*小人所在位置初始为墙内空地、箱子或者小人,小人移动后此处恢复为墙内空地*/
			aiMap[iPlayerX][iPlayerY] = SPACE;
		break;
	case BOX: /*下一位置是箱子和下一位置是已放箱子目的地的情况相同处理*/		
	case TARGET_IN:
		if (aiMap[iPlayerX2][iPlayerY2] == TARGET)
		{
			/*下下位置为空目的地,箱子和小人一起移动,箱子落入目的地*/
			aiMap[iPlayerX2][iPlayerY2] = TARGET_IN;
			aiMap[iPlayerX1][iPlayerY1] = PERSON;
		}
		else if (aiMap[iPlayerX2][iPlayerY2] == SPACE)
		{
			/*下下位置为空地,箱子和小人一起移动,箱子落入空地*/
			aiMap[iPlayerX2][iPlayerY2] = BOX;
			aiMap[iPlayerX1][iPlayerY1] = PERSON;
		}
		else/*下下位置为墙、箱子或者满目的地,不能移动,直接退出*/
			break;
		if (aiMap2[iPlayerX][iPlayerY] == TARGET || aiMap2[iPlayerX][iPlayerY] == TARGET_IN)
			/*小人所在位置初始为空目的地或满目的地,小人移动后此处恢复为空目的地*/
			aiMap[iPlayerX][iPlayerY] = TARGET;
		else/*小人所在位置初始为墙内空地、箱子或者小人,小人移动后此处恢复为墙内空地*/
			aiMap[iPlayerX][iPlayerY] = SPACE;
		break;
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾亿-唯一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值