[C/C++]程序员入门实战必学小游戏设计思想

目录

 一.游戏设计目的

二.学习内容

三.游戏的玩法 

四.游戏的设计思路

 五.游戏的界面图

​编辑​编辑

 六.游戏代码


  • 个人主页:北·海
  •  CSDN新晋作者
  •  欢迎 点赞✍评论⭐收藏
  • ✨收录专栏:C/C++
  • 希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!

 一.游戏设计目的

  • 学习实战思维
  • 学习基本语法在项目中的灵活使用
  • 学习如何从零到一的项目设计
  • 了解函数在项目中的重要性
  • 如何优化代码

二.学习内容

  • 宏的使用 : #define
  • 结构体 : struct
  • 枚举 : 一般用在固定的数量上,枚举的首元素为0,可以指定某元素的值,目的时为了增强程序的可读性
  • 布尔类型的灵活使用 : 可以使用布尔类型的返回值判断执行是否成功,取代常用的void类型
  • easyx图形库中的基本函数: 游戏窗口的创建,图片的加载(loadimage)与渲染(putimage),文字的设计(RECT)  文本颜色(settextcolor),文本样式(settextstyle),文本的宽度高度可以自定义,用RECT变量创建,用drawtext进行渲染
  • 防御式编程 : 例如在一个函数里面用传进来的指针的时候,判断指针是否为空,或者是否可用,可以增强代码的健壮性
  • 热键 : 判断是否有按下键盘,_kbhit()函数,如果有使用,则返回值为true,可以用_getch()函数接收按下的字符,进行按键控制

三.游戏的玩法 

  • 小人将所有的箱子在规定的步数内都推在目的地时候为胜利
  • 无效的走,不增加步数,比如撞墙
  • 小人可以从目的地上走过,也可也将箱子从目的地上推出
  • 如果小人前面是箱子的话,只有前面是空地或者目的地时候才能走
  • 如果小人前面是空地则可以走

四.游戏的设计思路

  • 根据游戏的玩法设计思路
  • 先将资源加载进来,在进行创建游戏的界面,拿到游戏界面,首先应该可以使游戏里面的小人能进行移动,在main函数里面进行热键控制,从而控制小人移动,再判断什么时候人可以前进,什么时候游戏可以结束,从而合理设计出各函数,将一些可以改动的数字,可以定义为宏,不仅增强程序的可读性,还增强程序的健壮性,将各功能封装为函数进行调用
  •  main函数 -> gameControl(方向)进行控制小人移动的方向
  • gameControl(方向) -> changeMap() 人移动后改变游戏的数据,在将游戏界面重新渲染
  • main() - > isGameover() 判断游戏是否在规定的步数内结束
  • main() -> isFail() 判断游戏是否失败
  • gameOversence()函数用于在游戏结束的时候向背景图上渲染文字

 五.游戏的界面图

[C/C++]程序员入门实战必学小游戏设计思想_第1张图片[C/C++]程序员入门实战必学小游戏设计思想_第2张图片

[C/C++]程序员入门实战必学小游戏设计思想_第3张图片

 六.游戏代码

#include
#include 
#include 
#include 

#define RATIO 61

#define SCREEN_WIDTH  960
#define SCREEN_HEIGHT 768

#define LINE 9
#define COLUMN 12

#define START_X 100
#define START_Y 150

#define KEY_UP    'w'
#define KEY_DOWN  's'
#define KEY_LEFT  'a'
#define KEY_RIGHT 'd'
#define KEY_QUIT  'q'

#define STEP_MAX 10

#define isVald(pos)  pos.x >= 0 && pos.x < LINE && pos.y >= 0 && pos.y < COLUMN

using namespace std;

// 墙 : 0     地板 ; 1    箱子目的地 : 2    小人 : 3
//箱子 : 4     箱子命中目标 : 5

enum _PROPS{
	WALL,
	FLOOR,
	BOX_DES,
	MAN,
	BOX,
	HIT,	//箱子命中目标
	PER_BOX_DES,//人在目的地上

	ALL		//上面不设定值,这个刚好为道具的数量 为6
};

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

struct _POS {
	//人所在的位置
	int x;
	int y;
}man;


int step_count = 0;//统计走的步数


IMAGE images[ALL];

//地图
int map[LINE][COLUMN] = {

	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
	{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
	{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
	{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
	{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
	{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
	{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};

void gameOverSence(IMAGE* bg,char* text =nullptr) {

	putimage(0, 0, bg);
	settextcolor(WHITE);
	RECT rec = { 0,0,SCREEN_WIDTH,SCREEN_HEIGHT };
	settextstyle(20, 0, "宋体");
	drawtext(text, &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

}

//判断游戏是否正常结束
bool isGameover() {
	//判断地图中是否还有2
	for (int i = 0; i < LINE; i++) {
		for (int j = 0; j < COLUMN; j++) {
			if (map[i][j] == BOX) return false;
		}
	}
	return true;
}

//判断游戏是否失败结束

bool isFail() {
	//判断步数是否超过,超过则结束
	if (step_count > STEP_MAX) {
		return true;
	}

	return false;
}

void changeMap(struct _POS* pos,enum _PROPS prop) {
	//prop -   道具的类型
	map[pos->x][pos->y] = prop;
	putimage(START_X + pos->y * RATIO, START_Y + pos->x * RATIO, &images[prop]);
}

void gameControl(enum _DIRECTION direct) {

	struct _POS next_pos = man;
	struct _POS next_next_pos = man;
	switch (direct) {
	case UP:
		next_pos.x--;
		next_next_pos.x-=2;
		break;
	case DOWN:
		next_pos.x++;
		next_next_pos.x+=2;
		break;
	case LEFT:
		next_pos.y--;
		next_next_pos.y-=2;
		break;
	case RIGHT:
		next_pos.y++;
		next_next_pos.y+=2;
		break;
	}


	//人可以从箱子目的地上走过去
	if (isVald(next_pos) && map[next_pos.x][next_pos.y] == FLOOR ) { //前面是空地
		//优化为指针,可以节约内存  
		if (map[man.x][man.y] == PER_BOX_DES) {
			changeMap(&next_pos, MAN);
			changeMap(&man, BOX_DES);
			man = next_pos;
		}
		else {
			changeMap(&next_pos, MAN);//人的下一格
			changeMap(&man, FLOOR);//人的位置设置为地板或者目的地
			man = next_pos;
		}
		step_count++;
	}
	else if (isVald(next_pos) && map[next_pos.x][next_pos.y] == BOX) {  //前面是箱子
		//人的前面是箱子
		//箱子的地方是人,人的地方是地板
		//箱子的前面是箱子
		if (map[next_next_pos.x][next_next_pos.y] == FLOOR) { //箱子前面是空地
			//箱子前面是地板
			changeMap(&next_next_pos, BOX);
			changeMap(&next_pos, MAN);
			changeMap(&man, FLOOR);
			man = next_pos;
		}
		else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) { //箱子前面是目的地
			//箱子前面是目的地
			changeMap(&next_next_pos, HIT);
			changeMap(&next_pos, MAN);
			changeMap(&man, FLOOR);
			man = next_pos;
		}
		step_count++;
	}
	else if (isVald(next_pos) && map[next_pos.x][next_pos.y] == BOX_DES) {
		//人的前面是目的地,将目的地改为人,将人的地方改为空地
		changeMap(&next_pos, PER_BOX_DES);

		changeMap(&man, FLOOR);

		man = next_pos;
		step_count++;
	}
	else if (isVald(next_pos) && map[next_pos.x][next_pos.y] == HIT) {
		//前面是箱子在目的地上,目的地前面是箱子/空地
		if (map[next_next_pos.x][next_next_pos.y] == FLOOR) {
			//前面的前面是空地
			changeMap(&next_next_pos, BOX);
			changeMap(&next_pos, PER_BOX_DES);
			changeMap(&man,FLOOR);
			man = next_pos;
			step_count++;
		}
		//非空地不做处理
	}

	//扩展项 :
	//人的前面是目的地,将目的地改为人,将人的地方改为空地,
	//人的当前位置是目的地,前面是空地时候,将人前面的位置改为人,将目的地位置改为目的地
	//人可以将箱子从箱子目的地上推开
	//统计人走的步数,可以指定步数,如果超过该步数,则显示失败,否则显示成功

}

int main() {

	//搭建游戏台
	IMAGE bg_img;
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT,1);
	loadimage(&bg_img, "blackground.bmp", SCREEN_WIDTH, SCREEN_HEIGHT,true);
	putimage(0, 0, &bg_img);

	//加载道具图标
	loadimage(&images[WALL], "wall_right.bmp", RATIO, RATIO, true);
	loadimage(&images[FLOOR], "floor.bmp", RATIO, RATIO, true);
	loadimage(&images[BOX_DES], "des.bmp", RATIO, RATIO, true);
	loadimage(&images[MAN], "man.bmp", RATIO, RATIO, true);
	loadimage(&images[BOX], "box.bmp", RATIO, RATIO, true);
	loadimage(&images[HIT], "box.bmp", RATIO, RATIO, true);
	loadimage(&images[PER_BOX_DES], "man.bmp", RATIO, RATIO, true);

	//渲染道具
	for (int i = 0; i < LINE; i++) {
		for (int j = 0; j < COLUMN; j++) {
			if (map[i][j] == MAN) {
				man.x = i;
				man.y = j;
			}
			putimage(START_X +j * RATIO, START_Y +i * RATIO, &images[map[i][j]]);
		}
	}

	//热键控制
	bool quit = false;

	do {
		//keyboardhit 如果有敲击键盘则返回true
		if (_kbhit()) {

			char ch;
			ch = _getch();
			if (ch == KEY_UP) {
				gameControl(UP);
			}
			else if (ch == KEY_DOWN) {
				gameControl(DOWN);
			}
			else if (ch == KEY_LEFT) {
				gameControl(LEFT);
			}
			else if (ch == KEY_RIGHT) {
				gameControl(RIGHT);
			}
			else if (ch == KEY_QUIT) {
				quit = true;
			}

			if (isFail()) {
				//是否失败结束
				gameOverSence(&bg_img, (char*)"很遗憾,没能通过此关卡");
				quit = true;
			}
			if (isGameover()) {
				//正常结束
				gameOverSence(&bg_img, (char*)"恭喜你~,成为一名合格的搬箱子老司机");
				quit = true;
			}

			Sleep(100);
		}

	} while (quit == false);

	system("pause");
	//游戏结束,释放资源
	closegraph();
	return 0;

}

[C/C++]程序员入门实战必学小游戏设计思想_第4张图片

你可能感兴趣的:(C++,C语言,c++,c语言,开发语言)