C/C++ 手写“90坦克大战游戏”

8 篇文章 2 订阅

今天给大家分享使用C语言配合easy-x图形库开发的一款控制台桌面小游戏。(IDE:请使用vs2010或者vs2019)

资源下载链接:

百度网盘
链接:https://pan.baidu.com/s/1KYtZDYwbR_X62k_Swl3anQ
提取码:8qa4

或者点击这里!!!

相信不管是80后还是90后,更或者是00后,应该都玩过“09坦克大战”这款经典的FP游戏吧,现在,给大家分享这款游戏的运行代码。(个人观点)

程序还有许多地方需要去优化的,有兴趣的小伙伴可以下载回去自己琢磨琢磨,修改完善。

当然,地图也是只有一份,有兴趣的小伙伴,可以自行下载资源回去,对地图进行增加。

由于代码量有点大,在这里就不一一讲解了。

当然本款小游戏也是在腾讯课堂骑牛学院martin老师的指点下完成的,有兴趣学习C/C++语言的小伙伴可以去腾讯课堂官网搜索骑牛学院!

废话不多说,先上游戏截图:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

好了,游戏的效果图已经展现给大家看了,那么下面请看代码:

#include <graphics.h>
#include <conio.h>
#include <Windows.h>
#include <time.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")	// 导入声音库

#define ENEMY_NUM 10

enum DIRECTION {
	UP,
	DOWN,
	LEFT,
	RIGHT
};

// 坦克结构体
struct tank_s {
	int x;	// 坦克在地图数组中所在的列
	int y;	// 坦克在地图数组中所在的行
	DIRECTION direction;	// 坦克的方向,上、下、左、右
	int live;	// 坦克是否生存  1 -- 活着   0 -- 死了
};

// 子弹结构体
struct bullet_s {
	int pos_x;		// 子弹再窗口上的横坐标
	int pos_y;		// 子弹再窗口上的纵坐标
	DIRECTION direction;	// 子弹方向
	int status;		// 子弹的状态
};


// 定义地图数组
int map[26][26] = { 
	{ 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, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1 },
	{ 2, 2, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 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, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

void set_prop_map(int x, int y, int value) {
	map[y][x] = value;
	map[y][x + 1] = value;
	map[y + 1][x] = value;
	map[y + 1][x + 1] = value;
}

void menu() {
	// 显示logo
	IMAGE logo_img;
	loadimage(&logo_img, _T("logo.bmp"), 433, 174);	// 将图片加载进logo_img变量中
	putimage(110, 20, &logo_img);

	// 实现导航按钮
	setlinecolor(WHITE);
	setfillcolor(BLACK);

	fillrectangle(230, 200, 310, 240);
	settextstyle(25, 0, _T("宋体"));
	outtextxy(240, 210, _T("说 明"));

	fillrectangle(350, 200, 430, 240);
	outtextxy(360, 210, _T("开 始"));

	MOUSEMSG mouse;	// 定义鼠标
	IMAGE illustrate_img;
	loadimage(&illustrate_img, _T("illustrate.jpg"), 300, 300);

	while (1) {
		mouse = GetMouseMsg();	// 获取鼠标消息

		switch (mouse.uMsg) {
		case WM_MOUSEMOVE:	// 鼠标移动事件
			if ((mouse.x > 230 && mouse.x < 310) && (mouse.y > 200 && mouse.y < 240)) {
				putimage(150, 250, &illustrate_img);
			}
			else {
				solidrectangle(150, 250, 450, 550);	// 绘制一个无边框的矩形
			}
			break;
		case WM_LBUTTONDOWN:	// 鼠标左键点击事件
			if ((mouse.x > 350 && mouse.x < 430) && (mouse.y > 200 && mouse.y < 240)) {
				cleardevice();
				return;
			}
		}
	}
}

// 初始化地图
// 可消除的墙1;不可消除的墙2;碉堡(3,4)
void initMap(int *map, int rows, int cols) {

	IMAGE img_home, img_wall_1, img_wall_2;
	loadimage(&img_home, _T("home.jpg"), 50, 50);		// 碉堡
	loadimage(&img_wall_1, _T("wall1.jpg"), 25, 25);	// 不可消除的墙
	loadimage(&img_wall_2, _T("wall2.jpg"), 25, 25);	// 可消除的墙


	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			if (*(map + cols * i + j) == 1) {
				putimage(25 * j, 25 * i, &img_wall_2);
			} else if (*(map + cols * i + j) == 2) {
				putimage(25 * j, 25 * i, &img_wall_1);
			} else if (*(map + cols * i + j) == 3) {
				putimage(25 * j, 25 * i, &img_home);

				set_prop_map(j, i, 4);
			}
		}
	}
}

// 控制坦克按相应的位置前进一步
// 成功返回1;失败返回0
int do_tank_walk(tank_s *tank, DIRECTION direction, IMAGE *img, int step) {

	int new_x = tank->x;
	int new_y = tank->y;

	int old_prop = map[tank->y][tank->x];

	if (step) {
		if (direction == UP) {
			new_y -= 1;
		} else if (direction == DOWN) {
			new_y += 1;
		} else if (direction == LEFT) {
			new_x -= 1;
		} else if (direction == RIGHT) {
			new_x += 1;
		} else {
			return 0;	// 无效方向
		}

		set_prop_map(tank->x, tank->y, 0);
	}
	

	setfillcolor(BLACK);
	solidrectangle(tank->x * 25, tank->y * 25, tank->x * 25 + 50, tank->y * 25 + 50);
	
	if (step) {
		set_prop_map(new_x, new_y, old_prop);

		tank->x = new_x;
		tank->y = new_y;
	}
	
	putimage(tank->x * 25, tank->y * 25, img);

	return 1;
}

// 实现子弹运行和碰撞检测,并反馈游戏结果
// 返回:1 - 表示游戏失败  0 - 继续游戏
int bullet_ation(bullet_s *bullet, tank_s *enemy_tank) {
	int x, y, x1, y1;	// 子弹目前所在的二维数组的坐标

	x = bullet->pos_x / 25;
	y = bullet->pos_y / 25;



	// 1.擦除上一次绘制的子弹
	setfillcolor(BLACK);
	solidrectangle(bullet->pos_x, bullet->pos_y, bullet->pos_x + 3, bullet->pos_y + 3);

	// 2.根据方向计算子弹在地图上的坐标
	if (bullet->direction == UP) {
		bullet->pos_y -= 2;
		x1 = x + 1;
		y1 = y;
	} else if (bullet->direction == DOWN) {
		bullet->pos_y += 2;
		x1 = x + 1;
		y1 = y;
	} else if (bullet->direction == LEFT) {
		bullet->pos_x -= 2;
		x1 = x;
		y1 = y + 1;
	} else if (bullet->direction == RIGHT) {
		bullet->pos_x += 2;
		x1 = x;
		y1 = y + 1;
	} else {
		return 0;
	}


	if (bullet->pos_x < 0 || bullet->pos_x > 650 || bullet->pos_y < 0 || bullet->pos_y > 650) {
		bullet->status = 0;
		return 0;
	}

	// 碰撞检查
	if (map[y][x] == 4 || map[y1][x1] == 4) {	// 子弹击中碉堡
		//bullet->status = 0;
		return 1;
	} 

	if (map[y][x] == 200 || map[y1][x1] == 200) {	// 击中我方坦克
		return 1;
	}

	if ((map[y][x] >= 100 && map[y][x] <= 109) || (map[y1][x1] >= 100 && map[y1][x1] <= 109)) {
		tank_s *tank = NULL;
		bullet->status = 0;

		if (map[y][x] >= 100 && map[y][x] <= 109) {
			tank = enemy_tank + (map[y][x] - 100);
		} else {
			tank = enemy_tank + (map[y1][x1] - 100);
		}

		tank->live = 0;
		set_prop_map(tank->x, tank->y, 0);
		setfillcolor(BLACK);
		solidrectangle(tank->x * 25, tank->y * 25, tank->x * 25 + 50, tank->y * 25 + 50);
	}

	if (map[y][x] == 1) {	// 子弹击中可消除的墙
		map[y][x] = 0;
		bullet->status = 0;
		setfillcolor(BLACK);
		solidrectangle(x * 25, y * 25, x * 25 + 25, y * 25 + 25);
	} else if (map[y][x] == 2) { // 不可消除的墙
		//PlaySound(_T("hit.wav"), NULL, SND_FILENAME | SND_ASYNC);
		bullet->status = 0;
	}

	if (map[y1][x1] == 1) {	// 子弹击中可消除的墙
		map[y1][x1] = 0;
		bullet->status = 0;
		setfillcolor(BLACK);
		solidrectangle(x1 * 25, y1 * 25, x1 * 25 + 25, y1 * 25 + 25);
	} else if (map[y1][x1] == 2) { // 不可消除的墙
		bullet->status = 0;
	}



	// 3.重新绘制子弹
	if (bullet->status == 1) {
		setfillcolor(WHITE);
		solidrectangle(bullet->pos_x, bullet->pos_y, bullet->pos_x + 3, bullet->pos_y + 3);
	}

	return 0;
	
}


// 坦克前进一步
void tank_walk(tank_s *tank, DIRECTION direction, IMAGE *img) {
	switch (direction) {
		case UP:	// 上					
			if (tank->direction == UP && (tank->y - 1) >= 0 && map[tank->y - 1][tank->x] == 0 && map[tank->y - 1][tank->x + 1] == 0) {
				do_tank_walk(tank, UP, img, 1);
			}
			else if (tank->direction != UP) {
				tank->direction = UP;
				do_tank_walk(tank, UP, img, 0);
			} 
			break;
		case DOWN:	// 下
			if (tank->direction == DOWN && (tank->y + 2) <= 25 && map[tank->y + 2][tank->x] == 0 && map[tank->y + 2][tank->x + 1] == 0) {
				do_tank_walk(tank, DOWN, img, 1);
			}
			else if (tank->direction != DOWN) {
				tank->direction = DOWN;
				do_tank_walk(tank, DOWN, img, 0);
			}
			break;
		case LEFT:	// 左
			if (tank->direction == LEFT && (tank->x - 1) >= 0 && map[tank->y][tank->x - 1] == 0 && map[tank->y + 1][tank->x - 1] == 0) {
				do_tank_walk(tank, LEFT, img, 1);
			}
			else if (tank->direction != LEFT) {
				tank->direction = LEFT;
				do_tank_walk(tank, LEFT, img, 0);
			}
			break;
		case RIGHT:	// 右
			if (tank->direction == RIGHT && (tank->x + 2) <= 25 && map[tank->y][tank->x + 2] == 0 && map[tank->y + 1][tank->x + 2] == 0) {
				do_tank_walk(tank, RIGHT, img, 1);
			}
			else if (tank->direction != RIGHT) {
				tank->direction = RIGHT;
				do_tank_walk(tank, RIGHT, img, 0);
			}
			break;
		default:	// 其他键无需操作
			break;
	}

}

// 根据目标位置,调整敌方坦克的方向
DIRECTION enemy_direction(tank_s *tank, int x, int y) {
	int r = rand() % 100;

	if (tank->x > x) {	// 目标再左边
		if (tank->y > y) {	// 目标在左上方
			if (r <= 50) return UP;
			return LEFT;
		} else {	// 目标在左下方
			if (r <= 50) return DOWN;
			return LEFT;
		}
	} else {	// 目标再右边
		if (tank->y > y) {	// 目标在右上方
			if (r <= 50) return UP;
			return RIGHT;
		} else {	// 目标在右下方
			if (r <= 50) return DOWN;
			return RIGHT;
		}
	}
}

// 坦克开火
void tank_fire(tank_s *tank, bullet_s *bullet, int need_sound) {
	if (bullet->status == 0) {
		if (need_sound) {
			PlaySound(_T("fire.wav"), NULL, SND_FILENAME | SND_ASYNC);
		}
		if (tank->direction == UP) {
			bullet->pos_x = tank->x * 25 + 23;
			bullet->pos_y = tank->y * 25 - 3;
		}
		else if (tank->direction == DOWN) {
			bullet->pos_x = tank->x * 25 + 23;
			bullet->pos_y = tank->y * 25 + 53;
		}
		else if (tank->direction == LEFT) {
			bullet->pos_x = tank->x * 25 - 3;
			bullet->pos_y = tank->y * 25 + 23;
		}
		else if (tank->direction == RIGHT) {
			bullet->pos_x = tank->x * 25 + 53;
			bullet->pos_y = tank->y * 25 + 23;
		}

		bullet->direction = tank->direction;
		bullet->status = 1;
	}
}




/****************************************
* 实现游戏场景
*****************************************/
int play() {
	tank_s my_tank;		// 我方坦克
	bullet_s my_bullet;	// 我方坦克发射的子弹

	tank_s enemy_tank[ENEMY_NUM];		// 敌方坦克
	bullet_s enemy_bullet[ENEMY_NUM];	// 敌方坦克发射的子弹


	IMAGE my_tank_img[4];	// 我方坦克的显示图片
	IMAGE enemy_tank_img[4];// 地方坦克的显示图片
	int key;
	int times = 0;	// 记录当前程序的休眠次数,每次10ms
	int enemy_total = 0;

	// 初始化随机种子
	srand(time(NULL));

	// 游戏背景音乐
	mciSendString(_T("play background.wav"), 0, 0, 0);


	// 加载我方坦克的图片
	loadimage(&my_tank_img[UP], _T("tank_up.jpg"), 50, 50);
	loadimage(&my_tank_img[DOWN], _T("tank_down.jpg"), 50, 50);
	loadimage(&my_tank_img[LEFT], _T("tank_left.jpg"), 50, 50);
	loadimage(&my_tank_img[RIGHT], _T("tank_right.jpg"), 50, 50);

	// 加载地方坦克的图片
	loadimage(&enemy_tank_img[UP], _T("enemy_tank_up.jpg"), 50, 50);
	loadimage(&enemy_tank_img[DOWN], _T("enemy_tank_down.jpg"), 50, 50);
	loadimage(&enemy_tank_img[LEFT], _T("enemy_tank_left.jpg"), 50, 50);
	loadimage(&enemy_tank_img[RIGHT], _T("enemy_tank_right.jpg"), 50, 50);

	// 1 :子弹存在   0 : 子弹不存在
	my_bullet.status = 0;

	// 我方坦克出现的位置
	my_tank.x = 8;
	my_tank.y = 24;
	my_tank.live = 1;
	my_tank.direction = UP;

	// 敌方坦克出现的位置
	for (int i = 0; i < ENEMY_NUM; i++) {
		if (i % 3 == 0) {
			enemy_tank[i].x = 0;
		}
		else if (i % 3 == 1) {
			enemy_tank[i].x = 12;
		}
		else if (i % 3 == 2) {
			enemy_tank[i].x = 24;
		}

		enemy_tank[i].direction = DOWN;
		enemy_tank[i].y = 0;
		enemy_tank[i].live = 1;
		//set_prop_map(enemy_tank[i].x, enemy_tank[i].y, 100 + i);
		enemy_bullet[i].status = 0;
	}

	// 前三辆坦克出现
	do_tank_walk(&enemy_tank[0], DOWN, &enemy_tank_img[DOWN], 0);
	set_prop_map(enemy_tank[0].x, enemy_tank[0].y, 100);
	do_tank_walk(&enemy_tank[1], DOWN, &enemy_tank_img[DOWN], 0);
	set_prop_map(enemy_tank[1].x, enemy_tank[1].y, 101);
	do_tank_walk(&enemy_tank[2], DOWN, &enemy_tank_img[DOWN], 0);
	set_prop_map(enemy_tank[2].x, enemy_tank[2].y, 102);
	enemy_total = 3;


	set_prop_map(my_tank.x, my_tank.y, 200);

	// 显示我方坦克
	putimage(25 * my_tank.x, 25 * my_tank.y, &my_tank_img[my_tank.direction]);


	while (1) {
		if (times > 0 && times % 1000 == 0 && enemy_total < ENEMY_NUM) {
			set_prop_map(enemy_tank[enemy_total].x, enemy_tank[enemy_total].y, 100 + enemy_total);
			enemy_total++;
		}

		if (times % 100 == 0) {
			for (int i = 0; i < enemy_total; i++) {
				if (enemy_tank[i].live == 0) continue;

				if (i % 2 == 0) {	// 双数攻击我方老鹰
					DIRECTION d = enemy_direction(&enemy_tank[i], 12, 24);
					tank_walk(&enemy_tank[i], d, &enemy_tank_img[d]);
				} else {	// 单数攻击我方坦克
					DIRECTION d = enemy_direction(&enemy_tank[i], my_tank.x, my_tank.y);
					tank_walk(&enemy_tank[i], d, &enemy_tank_img[d]);
				}

				tank_fire(&enemy_tank[i], &enemy_bullet[i], 0);
			}
		} else if (times % 100 == 0) {	// 敌方坦克还生存
				for (int i = 0; i < enemy_total; i++) {
					if (enemy_tank[i].live) {
						tank_walk(&enemy_tank[i], enemy_tank[i].direction, &enemy_tank_img[enemy_tank->direction]);
					}
				}
		}


		if (_kbhit()) {
			key = _getch();

			switch (key) {
				case 'w':	// 上					
					tank_walk(&my_tank, UP, &my_tank_img[UP]);
					break;
				case 's':	// 下
					tank_walk(&my_tank, DOWN, &my_tank_img[DOWN]);
					break;
				case 'a':	// 左
					tank_walk(&my_tank, LEFT, &my_tank_img[LEFT]);
					break;
				case 'd':	// 右
					tank_walk(&my_tank, RIGHT, &my_tank_img[RIGHT]);
					break;
				case 'j':	// 开火
					tank_fire(&my_tank, &my_bullet, 1);					
					break;
				case 'p':	// 暂停
					system("pause");
					break;
				default:	// 其他键无需操作
					break;
			}
		}
		if (my_bullet.status == 1) {
			if (bullet_ation(&my_bullet, enemy_tank)) {
				return 1;
			}
		}

		for (int i = 0; i < ENEMY_NUM; i++) {
			if (enemy_bullet[i].status == 1) {
				if (bullet_ation(&enemy_bullet[i], enemy_tank)) {
					return 1;
				}
			}
		}

		// 判断敌方坦克是否全部被消灭
		int isWin = 1;
		for (int i = 0; i < ENEMY_NUM; i++) {
			if (enemy_tank[i].live == 1) {
				isWin = 0;
				break;
			}
		}
		if (isWin) return 0;

		Sleep(5);
		times++;
	}
}

void game_voer(int result) {
	IMAGE img;

	if (result == 1) {	// 等于1表示失败
		loadimage(&img, _T("failure.jpg"), 500, 250);
		putimage(80, 200, &img);
	} else if (result == 0) {	// 等于0表示成功
		loadimage(&img, _T("success.jpg"), 500, 250);
		putimage(80, 200, &img);
	}

	_getch();
}




int main(void) {
	int result = 0;
	initgraph(650, 650);

	// 开始场景,显示菜单
	menu();
	
	// 初始化地图
	initMap(*map, 26, 26);

	result = play();

	// 显示游戏结果
	game_voer(result);

	system("pause");
	closegraph();
	return 0;
}

最后祝csdn的各位,五一快乐!

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cpp_learners

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

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

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

打赏作者

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

抵扣说明:

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

余额充值