c/c++1000行代码实现俄罗斯方块

运行效果
在这里插入图片描述
在这里插入图片描述
代码

//游戏相关的数据
/*
	1.地图数据-哪些位置有方块、哪些位置是空的
	2.浮动的大方块


*/
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <time.h>
#include <mmsystem.h>
#include <iostream>
using namespace std;

#pragma comment(lib,"Winmm.lib")



#define BLOCK_COUNT 7
#define DIRECTION_COUNT 4
#define BLOCK_WIDTH 4
#define BLOCK_HEIGHT 4
#define GRID_WIDTH 12 //网格宽带
#define GRID_HIGHT 24 //网格高度 实际高度20 留有4行作为临时区域
#define SLIDER_PX 30//边长30 单位像素
#define WAIT_DELAY 400//等待延时,100毫秒,浮动矩阵向下移动一行
#define SINGLE_DELAY 80//单次延时
#define INFO_WINDOW_WIDTH 200//信息窗体宽度


enum BlockType //方块类型
{
	Block_None = -1,	//没有方块
	Block_0 = 0,	//正方形
	Block_1 = 1,	//直线型
	Block_2 = 2,	//反L形
	Block_3 = 3,	//山字形
	Block_4 = 4,	//反Z形
	Block_5 = 5,	//正Z形
	Block_6 = 6,	//正L形

};

const bool bBlockData[BLOCK_COUNT][DIRECTION_COUNT][BLOCK_WIDTH][BLOCK_HEIGHT] =
{
	//第一个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第三个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,true,true,false},
			{ false,false,false,false}

		}
	},
	
	//第二个形状
	{
		//第一个角度
		{
			{ false,false,true,false},
			{false,false,true,false},
			{ false,false,true,false},
			{ false,false,true,false}

		},
		//第二个角度
		{
			{ false,false,false,false},
			{false,false,false,false},
			{ true,true,true,true},
			{ false,false,false,false}

		},
		//第三个角度
		{
			{ false,true,false,false},
			{false,true,false,false},
			{ false,true,false,false},
			{ false,true,false,false}

		},
		//第四个角度
		{
			{ false,false,false,false},
			{true,true,true,true},
			{ false,false,false,false},
			{ false,false,false,false}

		}
	},

	//第三个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,true,false,false},
			{ false,true,true,true},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,true,false,false},
			{ false,true,false,false}

		},
		//第三个角度
		{
			{ false,false,false,false},
			{true,true,true,false},
			{ false,false,true,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,true,false},
			{false,false,true,false},
			{ false,true,true,false},
			{ false,false,false,false}

		}
	},


	//第四个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,true,false,false},
			{ true,true,true,false},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,true,false,false},
			{false,true,true,false},
			{ false,true,false,false},
			{ false,false,false,false}

		},
		//第三个角度
		{
			{ false,false,false,false},
			{false,true,true,true},
			{ false,false,true,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,false,false},
			{false,false,true,false},
			{ false,true,true,false},
			{ false,false,true,false}

		}
	},

	//第五个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ true,true,false,false},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,true,false,false},
			{false,true,true,false},
			{ false,false,true,false},
			{ false,false,false,false}

		},
		//第三个角度
		{
			{ false,false,false,false},
			{false,false,true,true},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,false,false},
			{false,true,false,false},
			{ false,true,true,false},
			{ false,false,true,false}

		}
	},
	
	//第六个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,false,true,true},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,false,false,false},
			{false,false,true,false},
			{ false,true,true,false},
			{ false,true,false,false}

		},
		//第三个角度
		{
			{ false,false,false,false},
			{true,true,false,false},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,true,false},
			{false,true,true,false},
			{ false,true,false,false},
			{ false,false,false,false}

		}
	},
	
	//第七个形状
	{
		//第一个角度
		{
			{ false,false,false,false},
			{false,false,true,false},
			{ true,true,true,false},
			{ false,false,false,false}

		},
		//第二个角度
		{
			{ false,true,false,false},
			{false,true,false,false},
			{ false,true,true,false},
			{ false,false,false,false}

		},
		//第三个角度

		{
			{ false,false,false,false},
			{false,true,true,true},
			{ false,true,false,false},
			{ false,false,false,false}

		},
		//第四个角度
		{
			{ false,false,false,false},
			{false,true,true,false},
			{ false,false,true,false},
			{ false,false,true,false}

		}
	}
	
};

const int iBlockMinRow[BLOCK_COUNT][DIRECTION_COUNT] = {
	{
		1,1,1,1
	},
	{
		0,2,3,1
	},
	{
		1,1,1,0
	},
	{
		1,0,1,1
	},
	{
		1,0,1,1
	},
	{
		1,1,1,0
	},
	{
		1,0,1,1
	}
};

const int iBlockMinCol[BLOCK_COUNT][DIRECTION_COUNT] = {
	{
		1,1,1,1
	},
	{
		2,0,1,0
	},
	{
		1,1,0,1
	},
	{
		0,1,1,1
	},
	{
		0,1,1,1
	},
	{
		1,1,0,1
	},
	{
		0,1,1,1
	}
};

const int iBlockMaxRow[BLOCK_COUNT][DIRECTION_COUNT] = {
	{
		2,2,2,2
	},
	{
		3,2,3,1
	},
	{
		2,3,2,2
	},
	{
		2,2,2,3
	},
	{
		2,2,2,3
	},
	{
		2,3,2,2
	},
	{
		2,2,2,3
	}
};

const int iBlockMaxCol[BLOCK_COUNT][DIRECTION_COUNT] = {
	{
		2,2,2,2
	},
	{
		2,3,1,3
	},
	{
		3,2,2,2
	},
	{
		2,2,3,2
	},
	{
		2,2,3,2
	},
	{
		3,2,2,2
	},
	{
		2,2,3,2
	}
};

int iGrid[GRID_HIGHT][GRID_WIDTH];
int iFloatBlock[BLOCK_HEIGHT][BLOCK_WIDTH];
int iNextBlock = 0;//下一个方块
int iNextBlockDirection = 0;//下一个方块的方向
int iWaitTime = 0;//每次等待时间,浮动矩阵下降一行
int iFloatBlockRow = 0;//浮动方块开始的行
int iFloatBlockCol = 0;//浮动方块开始的列
int iCurrentBlock = 0;//当前方块的形状
int iCurrentBlockDirection = 0;//当前方块的方向
int iScore = 0; //游戏的分数
int iLastScore = 0;//上次得分
int iMaxScore = 0;//最高得分



/*
	接口说明:初始化棋盘
	参数说明:无
	返回值说明:无
*/
int InitGrid()
{
	for (int iRow = 0; iRow < GRID_HIGHT; iRow++)
	{
		for (int iCol = 0; iCol < GRID_WIDTH; iCol++)
		{
			iGrid[iRow][iCol] = BlockType::Block_None;
		}
	}
	return 0;
}

/*
	接口说明:清空完整行
	参数说明:无
	返回值说明:无
*/
int ClearLine()
{
	int iClearLineCount = 0;//消除的总共行数
	int iStartRow = iFloatBlockRow + iBlockMaxRow[iCurrentBlock][iCurrentBlockDirection];
	int iEndRow = iFloatBlockRow + iBlockMinRow[iCurrentBlock][iCurrentBlockDirection];
	
	for (int iRow = iStartRow; iRow >= iEndRow; iRow--)
	{
		bool bClear = true;
		for (int iCol = 0; iCol < GRID_WIDTH; iCol++)
		{
			if (iGrid[iRow][iCol] == BlockType::Block_None)
			{
				bClear = false;
				break;
			}
		}
		if (bClear)//是否需要消行
		{
			for (int iTempRow = iRow; iTempRow >=4; iTempRow--)
			{
				for (int iTempCol = 0; iTempCol < GRID_WIDTH; iTempCol++)
				{
					iGrid[iTempRow][iTempCol] = iGrid[iTempRow - 1][iTempCol];
				}
			}
			iRow++;
			//iEndRow++;
			iClearLineCount++;
		}
	}
	//奖励机制
	switch (iClearLineCount)
	{
		case 1:
		{
			iScore += 10;//无额外加分,基础十分
			break;
		}
		case 2:
		{
			iScore += 25;//额外加5分
			break;
		}
		case 3:
		{
			iScore += 45;//额外加15分
			break;
		}
		case 4:
		{
			iScore += 70;//额外加30分
			break;
		}
		defalult:
		{
			break;//不加分
		}

	}

	return 0;
}

int DrawFloatBlock()
{
	//设置线条颜色
	setlinecolor(RGB(255, 255, 255));
	switch (iCurrentBlock)
	{
	case BlockType::Block_0:
	{
		setfillcolor(RGB(255, 0, 0));
		break;
	}
	case BlockType::Block_1:
	{
		setfillcolor(RGB(89, 176, 189));
		break;
	}
	case BlockType::Block_2:
	{
		setfillcolor(RGB(20, 101, 165));
		break;
	}
	case BlockType::Block_3:
	{
		setfillcolor(RGB(235, 213, 0));
		break;
	}
	case BlockType::Block_4:
	{
		setfillcolor(RGB(137, 64, 134));
		break;
	}
	case BlockType::Block_5:
	{
		setfillcolor(RGB(218, 132, 0));
		break;
	}
	case BlockType::Block_6:
	{
		setfillcolor(RGB(54, 154, 49));
		break;
	}
	default:
	{
		setfillcolor(RGB(0, 0, 0));
		break;
	}
	}

	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++) {
		for (int iCol = 0; iCol < BLOCK_WIDTH; iCol++) {
			if(iFloatBlock[iRow][iCol]!=BlockType::Block_None)
			fillrectangle((iFloatBlockCol + iCol)* SLIDER_PX, (iFloatBlockRow+iRow - 4)* SLIDER_PX, (iFloatBlockCol +iCol + 1)* SLIDER_PX, (iFloatBlockRow+iRow - 3)* SLIDER_PX);

		}
	}
	return 0;

}

/*
	接口说明:初始化浮动的方块
	参数说明:无
	返回值说明:无
*/
int InitFloatBlock()
{
	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++) {
		for (int iCol = 0; iCol < BLOCK_WIDTH; iCol++) {
			iFloatBlock[iRow][iCol] = BlockType::Block_None;
		}
	}
	return 0;
}

/*
	接口说明:生成下一个方块
	参数说明:无
	返回值说明:无
*/
int GenerateNextBlock()
{
	iCurrentBlock = iNextBlock;
	iCurrentBlockDirection = iNextBlockDirection;
	iNextBlock = rand() % 7 ;
	iNextBlockDirection = rand() % DIRECTION_COUNT;
	return 0;
}

/*
	接口说明:加载得分
	参数说明:无
	返回值说明:无
*/
int LoadScore()
{
	FILE* fp = NULL;
	fopen_s(&fp, "Score.txt", "r");
	if (fp == NULL)
	{
		return -1;
	}
	fscanf_s(fp, "%d", &iLastScore);
	fscanf_s(fp, "%d", &iMaxScore);
	fclose(fp);
	return 0;
}

/*
	接口说明:保存得分
	参数说明:无
	返回值说明:无
*/
int SaveScore()
{
	FILE* fp = NULL;
	fopen_s(&fp, "Score.txt", "w");
	if (fp == NULL)
	{
		return -1;
	}

	if (iScore > iMaxScore)
	{
		iMaxScore = iScore;
	}

	fprintf_s(fp, "%d\n", iScore);
	fprintf_s(fp, "%d\n", iMaxScore);
	fclose(fp);
	return 0;
}

/*
	接口说明:绘画游戏信息
	参数说明:无
	返回值说明:无
*/
int DrwaInfo()
{
	int iStartX = GRID_WIDTH * SLIDER_PX;
	settextcolor(RGB(255, 255, 255));//设置字体颜色
	settextstyle(24, 0, L"楷体");//设置字体样式
	WCHAR score[100];
	swprintf_s(score, 100, L"分数:%d", iScore);
	outtextxy(iStartX+20,20,score);

	outtextxy(iStartX + 20, 60, L"下一个方块:");
	setlinecolor(RGB(255, 255, 255));//设置线条颜色
	rectangle(iStartX + 20, 90, iStartX + 20 + SLIDER_PX * BLOCK_WIDTH,90+SLIDER_PX*BLOCK_HEIGHT);
	
	switch (iNextBlock)
	{
	case BlockType::Block_0:
	{
		setfillcolor(RGB(255, 0, 0));
		break;
	}
	case BlockType::Block_1:
	{
		setfillcolor(RGB(89, 176, 189));
		break;
	}
	case BlockType::Block_2:
	{
		setfillcolor(RGB(20, 101, 165));
		break;
	}
	case BlockType::Block_3:
	{
		setfillcolor(RGB(235, 213, 0));
		break;
	}
	case BlockType::Block_4:
	{
		setfillcolor(RGB(137, 64, 134));
		break;
	}
	case BlockType::Block_5:
	{
		setfillcolor(RGB(218, 132, 0));
		break;
	}
	case BlockType::Block_6:
	{
		setfillcolor(RGB(54, 154, 49));
		break;
	}
	default:
	{
		setfillcolor(RGB(0, 0, 0));
		break;
	}
	
	}
	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++)
	{
		for (int iCol = 0; iCol < BLOCK_HEIGHT; iCol++)
		{
			if (bBlockData[iNextBlock][iNextBlockDirection][iRow][iCol])
			{
				fillrectangle(iStartX + 20 + iCol* SLIDER_PX, 90 + iRow * SLIDER_PX, iStartX + 20 + (iCol + 1) * SLIDER_PX, 90 + (iRow + 1) * SLIDER_PX);
			}
		}
	}
	swprintf_s(score, 100, L"%d", iLastScore);
	swprintf_s(score, 100, L"%d", iMaxScore);
	outtextxy(iStartX + 20, 240, L"上次得分:");
	outtextxy(iStartX + 20, 270, score);
	outtextxy(iStartX + 20, 310, L"最高得分:");
	outtextxy(iStartX + 20, 330, score);

	return 0;
}

/*
	接口说明:初始化浮动方块的开始行列
	参数说明:无
	返回值说明:无
*/
int InitFloatBlockStarRC()
{
	iFloatBlockCol = 4;
	iFloatBlockRow=BLOCK_HEIGHT -iBlockMaxRow[iNextBlock][iNextBlockDirection]-1;

	return  0;
}

/*
	接口说明:获取浮动方块
	参数说明:无
	返回值说明:无
*/
int GetFloatBlock()
{
	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++) {
		for (int iCol = 0; iCol < BLOCK_WIDTH; iCol++) {
			if (bBlockData[iCurrentBlock][iCurrentBlockDirection][iRow][iCol])
			{
				iFloatBlock[iRow][iCol] = iCurrentBlock;
			}
			else
			{
				iFloatBlock[iRow][iCol] = BlockType::Block_None;
			}
		}
			
	}
	return 0;
}

/*
	接口说明:尝试移动
	参数说明:iBlockType 方块的类型
			  iBlockDirection 方块的方向
			  iStarRow 方块矩阵开始的行
			  iStarCol 方块矩阵开始的列
	返回值说明: true 可以移动  false 不能移动
*/
bool TryMove(int iBlockType,int iBlockDirection,int iStartRow,int iStartCol)
{
	if (iStartRow + iBlockMaxRow[iBlockType][iBlockDirection] < 0 || iStartRow + iBlockMaxRow[iBlockType][iBlockDirection] >= GRID_HIGHT)
	{
		return false;
	}
	if (iStartCol + iBlockMinCol[iBlockType][iBlockDirection] < 0 || iStartCol + iBlockMaxCol[iBlockType][iBlockDirection] >= GRID_WIDTH)
	{
		return false;
	}

	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++)
	{
		for (int iCol = 0; iCol < BLOCK_WIDTH; iCol++)
		{
			if (iStartRow + iRow >= 4 && iStartRow + iRow < GRID_HIGHT && iStartCol + iCol >= 0 && iStartCol + iCol < GRID_WIDTH)
			{
				//确保测试是否重合的点在网格内
				if (iFloatBlock[iRow][iCol] != BlockType::Block_None && iGrid[iStartRow + iRow][iStartCol + iCol] != BlockType::Block_None)
				{
					return false;
				}
			}
			
		}
	}
	return true;
}

/*
	接口说明:捕获浮动方块,将浮动方块嵌入到网格中
	参数说明:无
	返回值说明:无
*/
int CaptureFloatBlock()
{
	for (int iRow = 0; iRow < BLOCK_HEIGHT; iRow++)
	{
		for (int iCol = 0; iCol < BLOCK_WIDTH; iCol++)
		{
			if (iFloatBlock[iRow][iCol] != BlockType::Block_None)
			{
				iGrid[iFloatBlockRow + iRow][iFloatBlockCol + iCol] = iFloatBlock[iRow][iCol];

			}

		}
	}

	return 0;
}

/*
	接口说明:绘画棋盘
	参数说明:无
	返回值说明:无
*/
int DrawGrid()
{

	IMAGE imgBg;
	loadimage(&imgBg, L".\\背景.jpg");
	putimage(0, 0, &imgBg);
	setbkcolor(RGB(237,145,33));
	//设置线条颜色
	setlinecolor(RGB(255, 255, 255));
	for (int iRow = 4; iRow < GRID_HIGHT; iRow++) {
		for (int iCol = 0; iCol < GRID_WIDTH; iCol++)
		{
			
			switch (iGrid[iRow][iCol])
			{
			case BlockType::Block_0:
			{
				setfillcolor(RGB(255, 0, 0));
				break;
			}
			case BlockType::Block_1:
			{
				setfillcolor(RGB(89, 176, 189));
				break;
			}
			case BlockType::Block_2:
			{
				setfillcolor(RGB(20, 101, 165));
				break;
			}
			case BlockType::Block_3:
			{
				setfillcolor(RGB(235, 213, 0));
				break;
			}
			case BlockType::Block_4:
			{
				setfillcolor(RGB(137, 64, 134));
				break;
			}
			case BlockType::Block_5:
			{
				setfillcolor(RGB(218, 132, 0));
				break;
			}
			case BlockType::Block_6:
			{
				setfillcolor(RGB(54, 154, 49));
				break;
			}
			default:
			{
				setfillcolor(RGB(0, 0, 0));
				break;
			}
			}

			fillrectangle(iCol * SLIDER_PX, (iRow - 4) * SLIDER_PX, (iCol + 1) * SLIDER_PX, (iRow - 3) * SLIDER_PX);
			
			
			
		}
	}
	return 0;
}

int main()
{
	LoadScore();//游戏开始,加载分数


	srand((unsigned int)time(NULL));
	InitGrid();
	InitFloatBlock();
	GenerateNextBlock();//生成第一个方块
	GenerateNextBlock();//生成第二个方块
	InitFloatBlockStarRC();
	GetFloatBlock();
	

	//创建窗口
	initgraph(GRID_WIDTH * SLIDER_PX+INFO_WINDOW_WIDTH, (GRID_HIGHT - 4) * SLIDER_PX);
	
	BeginBatchDraw();

	

	mciSendStringW(L"open .\\企鹅峰待机.mp3 alias bgm", NULL, 0, NULL);
	mciSendStringW(L"play bgm repeat", NULL, 0, NULL);


	while (1)
	{
		if (GetAsyncKeyState(VK_UP))//获取用户的输入
		{   
			int iTempDirection = (iCurrentBlockDirection+1)%DIRECTION_COUNT;
			if (TryMove(iCurrentBlock, iTempDirection, iFloatBlockRow, iFloatBlockCol - 1))
			{
				iCurrentBlockDirection = iTempDirection;
				GetFloatBlock();
				
			}
		}
		else if(GetAsyncKeyState(VK_LEFT))
		{
			if (TryMove(iCurrentBlock, iCurrentBlockDirection, iFloatBlockRow , iFloatBlockCol-1))
			{
				iFloatBlockCol--;
			}
		}
		else if (GetAsyncKeyState(VK_RIGHT))
		{
			if (TryMove(iCurrentBlock, iCurrentBlockDirection, iFloatBlockRow , iFloatBlockCol+1))
			{
				iFloatBlockCol++;
			}
		}
		else if (GetAsyncKeyState(VK_DOWN))
		{
			if (TryMove(iCurrentBlock, iCurrentBlockDirection, iFloatBlockRow + 1, iFloatBlockCol))
			{
				iFloatBlockRow++;
			}
			else //不能往下落时就嵌入它
			{
				if (iFloatBlockRow + iBlockMaxRow[iCurrentBlock][iCurrentBlockDirection] <= 4)
				{
					//游戏结束
					break;
				}
				CaptureFloatBlock();
				ClearLine();
				GenerateNextBlock();
				InitFloatBlockStarRC();
				GetFloatBlock();
				
			}
			iWaitTime = 0;
		}

		if (iWaitTime >= WAIT_DELAY)
		{
			if (TryMove(iCurrentBlock, iCurrentBlockDirection, iFloatBlockRow + 1, iFloatBlockCol))
			{
				iFloatBlockRow++;
			}
			else //不能往下落时就嵌入它
			{
				if (iFloatBlockRow + iBlockMaxRow[iCurrentBlock][iCurrentBlockDirection] <= 4)
				{
					//游戏结束
					break;
				}
				CaptureFloatBlock();
				ClearLine();
				DrwaInfo();
				GenerateNextBlock();
				InitFloatBlockStarRC();
				GetFloatBlock();

			}
			
			iWaitTime = 0;
		}

		cleardevice();
		DrawGrid();//绘画网格
		DrawFloatBlock();//绘画浮动方块
		DrwaInfo();
		FlushBatchDraw();
		Sleep(SINGLE_DELAY);
		iWaitTime += SINGLE_DELAY;
	}

	mciSendStringW(L"close bgm", NULL, 0, NULL);
	SaveScore();//游戏结束,保存成绩

	cleardevice();
	int iStartX = (GRID_WIDTH * SLIDER_PX + INFO_WINDOW_WIDTH - 150) / 2;
	int iStartY = ((GRID_HIGHT - 4) * SLIDER_PX-70)/2;
	settextstyle(36, 0, L"幼圆");
	outtextxy(iStartX, iStartY,L"游戏结束");
	settextstyle(24, 0, L"幼圆");
	outtextxy(iStartX, iStartY+40,L"按任意键退出");
	EndBatchDraw();
	
	int iRet=getchar();
	closegraph();
	return 0;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戴戴.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值