c语言/c++大作业基于easyx图形库自制RPG类型小游戏代码(附源码)

本文介绍了一款使用EasyX库开发的小游戏,涉及透明人物图片的加载、地图通过链表结构管理以及角色移动和碰撞检测的详细代码。作者分享了关键部分的实现细节,并附带了资源下载链接。

目录

一、游戏玩法

二、完整代码

三、部分细节

透明化人物背景

关于easyx库中怎样贴出透明图片

地图的链表实现

移动检测

 碰撞检测

总结


前言:

花两天边看easyx文档边学边写的期末小作业。

学校挂c++的课教c语言入门:)

时间仓促没优化啥,摆了不找了。欢迎大佬帮忙指出不足。

欢迎c+v应付作业

有小小的bug,开局时切换为英文输入法,开局时切换为英文输入法,开局时切换为英文输入法

需要配合地图素材  素材和exe文件的打包下载在结尾。


一、游戏玩法

该游戏将操作主角完成一些小小的任务以脱离密闭的房间。

W  A S D移动开局时切换为英文输入法

玩家将借助游戏中的门进出不同的房间

完成推箱子小游戏关后,玩家可从出口处出门完成游戏全部流程。

卧室

50e0a58268bb4c8e9c504005142824bf.png

 客厅

6c4100adc1a54edbace1a385baa3db28.jpeg

小游戏关

9790fb9492194a18904137918a58fbbe.jpeg

出口

aca5cd5df50642d6bb4f2c7a792ffe0f.jpeg

二、完整代码

#include <easyx.h>
#include <conio.h>
#include<Windows.h>
#include<iostream>
using namespace std;

//设置房间链表的节点
typedef struct map {
	int number;
	struct map* up;
	struct map* down;
	struct map*	left;
	struct map* right;
	struct map* next;
	char* src;
}mapnode;

void rungame();

mapnode* createmaplist();//创建地图函数
void showmainmenu();//展示主菜单函数
int peng(int x, int y, mapnode* nowroom, int xpx[], int xpy[]);//碰撞检测函数
int ifwin( int* xpx,int* xpy);//游戏胜负条件检测函数

int main()
{	
	showmainmenu();
	_getch();		
	closegraph();			
	return 0;
	}

//创建地图函数
mapnode* createmaplist() {
	mapnode* head = (mapnode*)malloc(sizeof(mapnode));
	mapnode* p, * tail = head;
	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 1;
	p->down = NULL;
	p->up = NULL;
	p->right = NULL;
	p->left = NULL;
	p->src = (char*)"./MAP001.jpg";
	tail->next = p;
	tail = tail->next;

	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 2;
	p->down = NULL;
	p->up = tail;
	p->right = NULL;
	p->left = NULL;
	p->src = (char*)"./MAP002.jpg";
	tail->down = p;
	tail = tail->down;
	
	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 3;
	p->down = NULL;
	p->up = NULL;
	p->right = tail;
	p->left = NULL;
	p->src = (char*)"./MAP003.jpg";
	tail->left = p;

	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 4;
	p->down = NULL;
	p->up = NULL;
	p->right = NULL;
	p->left = tail;
	p->src = (char*)"./MAP004.jpg";
	tail->right = p;

	return head;
}

//展示主菜单函数
void showmainmenu() {

	//初始化窗口
	initgraph(528, 528);
	setbkcolor(WHITE);
	cleardevice();

	//初始化标题字体
	settextcolor(BLACK);
	settextstyle(80, 0, "楷体");
	setbkmode(TRANSPARENT);
	char* arr = (char*)"李华传";
	int x, y;
	x=264-textwidth(arr)/2;
	y=100-textheight(arr)/2;
	outtextxy(x,y,arr);
    //加了层阴影
	settextcolor(RGB(154, 167, 177));
	outtextxy(x+5, y+5, arr);
	settextcolor(BLACK);
	//开始游戏按钮和字体初始化
	setfillcolor(WHITE);
	setlinecolor(BLACK);
	setlinestyle(PS_SOLID);
	arr= (char*)"开始游戏";
	settextstyle(40, 0, "微软雅黑");
	x = 264 - textwidth(arr) / 2;
	y = 250 - textheight(arr) / 2;
	fillroundrect(x - 20, y - 20, x + textwidth(arr)+20, y + textheight(arr)+20, 20, 20);
	outtextxy(x,y,arr);
	
	arr = (char*)"version 0.1";
	settextstyle(20, 0, "微软雅黑");
	outtextxy(450, 500,arr);
	settextstyle(40, 0, "微软雅黑");
	arr = (char*)"开始游戏";
	//接收鼠标信息
	ExMessage msg;
	int flag = 0;
	while (1) {
		if (peekmessage(&msg, EM_MOUSE)) {
			switch (msg.message) {
			case WM_LBUTTONUP:
				if (msg.x >= x - 20 && msg.x <= x + textwidth(arr) + 20 && msg.y >= y - 20 && msg.y <= y + textheight(arr) + 20) {
					flag = 1;
					rungame();
					break;
				}
			case WM_MOUSEMOVE:
				if (msg.x >= x - 20 && msg.x <= x + textwidth(arr) + 20 && msg.y >= y - 20 && msg.y <= y + textheight(arr) + 20) {
					setfillcolor(RGB(154, 167, 177));
					fillroundrect(x - 20+1, y - 20+1, x + textwidth(arr) + 21, y + textheight(arr) + 21, 20, 20);
					outtextxy(x, y, arr);
				}
				else {
					setfillcolor(WHITE);
					fillroundrect(x - 20, y - 20, x + textwidth(arr) + 20, y + textheight(arr) + 20, 20, 20);
					outtextxy(x, y, arr);
				}
				break;
			}
		}
		if (flag == 0) {
		}
		else {
			break;
		}
	}
	
}
	
void rungame() {
	//初始化窗口
	clearrectangle(0, 0, 600, 600);
	setbkcolor(YELLOW);
	cleardevice();
	//初始化地图链表
	mapnode* head = createmaplist();
	mapnode* now = head->next;

	//初始化人物及背景对象
	IMAGE nowroombk;
	IMAGE xiang;
	loadimage(&nowroombk, now->src, 0, 0);


	IMAGE character1, character2, character3;
	loadimage(&character1, "./原.jpg", 48, 48);
	loadimage(&character2, "a.png", 48, 48);
	loadimage(&character3, "b.png", 48, 48);
	loadimage(&xiang, "xian.png", 48, 48);
	int x = 240, y = 240;
	ExMessage msg;
	int a;
	int xpx[3] = { 6 * 48 ,8 * 48, 6 * 48 };
	int xpy[3] = { 4 * 48 ,5 * 48 ,6 * 48 };


	//开始主循环
	while (1) {
		putimage(0, 0, &nowroombk);
		putimage(x, y, &character3, SRCAND);
		putimage(x, y, &character2, SRCPAINT);
		if (now->number == 3) {
			putimage(xpx[0], xpy[0], &xiang);
			putimage(xpx[1], xpy[1], &xiang);
			putimage(xpx[2], xpy[2], &xiang);
		}
		int i,win=0;
		//检测是否碰撞
		//这里会不好看  看我文章
		if (peekmessage(&msg, EM_KEY)) {
			switch (msg.message) {
			case WM_KEYDOWN:
				a = _getch();
				if (a == 'w' || a == 'W') {
					//SetWorkingImage(&character);
					i = peng(x, y - 48, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i], xpy[i] - 48, now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpy[0] -= 48;break;
								case 1:xpy[1] -= 48;break;
								case 2:xpy[2] -= 48;break;
								}
							}
						}
					}
					else {
						y -= 48;
					}
				}
				else if (a == 'a' || a == 'A') {
					i = peng(x - 48, y, now, xpx, xpy);
					if(i){
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i] - 48, xpy[i], now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpx[0] -= 48;break;
								case 1:xpx[1] -= 48;break;
								case 2:xpx[2] -= 48;break;
								}
							}
						}
					}
					
					else {
						x -= 48;
					}

				}
				else if (a == 's' || a == 'S') {
					i = peng(x, y + 48, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i], xpy[i] + 48, now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpy[0] += 48;break;
								case 1:xpy[1] += 48;break;
								case 2:xpy[2] += 48;break;
								}
							}
						}
					}
					
					else {
						y += 48;
					}

				}
				else if (a == 'd' || a == 'D') {
					i = peng(x + 48, y, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i] + 48, xpy[i], now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpx[0] += 48;break;
								case 1:xpx[1] += 48;break;
								case 2:xpx[2] += 48;break;
								}
							}
						}
					}
					else {
						x += 48;
					}

				}
				else if (a == 32) {
					//cleardevice();
				}


				cleardevice();
				break;

			}
		}



		//房间移动
		if (x >= 5 * 48 && x <= 6 * 48 && y >= 10 * 48 && y <= 11 * 48) {
			if (now->down) {
				now = now->down;
				x = 5 * 48;
				y = 2 * 48;
				loadimage(&nowroombk, now->src, 0, 0);
			}
		}
		if (x >= 5 * 48 && x <= 6 * 48 && y >= 0 * 48 && y < 1 * 48) {
			if (now->up) {
				now = now->up;
				x = 5 * 48;
				y = 9 * 48;
				loadimage(&nowroombk, now->src, 0, 0);
			}
		}
		if (x >= 0 * 48 && x <= 1 * 48 && y >= 5 * 48 && y <= 6 * 48) {
			if (now->left) {
				now = now->left;
				x = 9 * 48;
				y = 5 * 48;
				loadimage(&nowroombk, now->src, 0, 0);

			}
		}
		if (x >= 10 * 48 && x <= 11 * 48 && y >= 5 * 48 && y <= 6 * 48) {
			if (now->right) {
				now = now->right;
				x = 2 * 48;
				y = 5 * 48;
				loadimage(&nowroombk, now->src, 0, 0);

			}
		}

		if (ifwin(xpx, xpy)) {
			if (now->number == 4, x == 5 * 48, y == 1 * 48) {
				break;
			}
		}
	}
}
//碰撞检测函数
int peng(int x,int y,mapnode* nowroom,int xpx[],int xpy[]){
	int flag=0;
	int i = 0;
	if (x<0||y<0||x>10*48||y>10*48) {
		flag = 1;
	}
	if (nowroom->number == 1) {
		if (y <= 3 * 48 && x <= 10 * 48 || y == 6 * 48 && x == 2 * 48 || y == 4 * 48 && x == 9 * 48) {
			flag = 1;
		}
	}
	if (nowroom->number == 2) {
		if (y <= 1 * 48 && x <= 4 * 48|| y <= 1 * 48 && x >= 6 * 48&& x <= 10 * 48){
			flag = 1;
		}
	}
	if (nowroom->number == 3) {
		if (y==0||y==10 * 48 ||x==0||x<=3 * 48 &&y<=3 * 48 ||x<=3 * 48 &&y>=7 * 48 ||x>=7 * 48 &&y<=4 * 48 ||x>=7 * 48 &&y>=6 * 48) {
			flag = 1;
		}
		for (i=0;i < 3;i++) {
			if (x == xpx[i] && y == xpy[i]) {
				flag = i+10;
			}
		}
	}
	if (nowroom->number == 4) {
		if (y <= 1 * 48 && x <= 4 * 48 || y <= 1 * 48 && x >= 6 * 48 && x <= 10 * 48) {
			flag = 1;
		}
	}
	return flag;
}
//游戏胜负条件检测函数
int ifwin( int* xpx, int* xpy) {
	int i = 0;
	if (6*48 == xpx[0] && 1 * 48 == xpy[0]&& 1 * 48 == xpx[1] && 5 * 48 == xpy[1] && 6 * 48 == xpx[2] && 9 * 48 == xpy[2]) {
		return 1;
	}
	return 0;
}


三、部分细节

透明化人物背景

IMAGE character1, character2, character3;
	loadimage(&character1, "./原.jpg", 48, 48);
	loadimage(&character2, "a.png", 48, 48);
	loadimage(&character3, "b.png", 48, 48);
	loadimage(&xiang, "xian.png", 48, 48);

关于easyx库中怎样贴出透明图片

原文链接:https://blog.youkuaiyun.com/weixin_45848751/article/details/106983700

地图的链表实现

mapnode* createmaplist() {
	mapnode* head = (mapnode*)malloc(sizeof(mapnode));
	mapnode* p, * tail = head;
	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 1;
	p->down = NULL;
	p->up = NULL;
	p->right = NULL;
	p->left = NULL;
	p->src = (char*)"./MAP001.jpg";
	tail->next = p;
	tail = tail->next;

	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 2;
	p->down = NULL;
	p->up = tail;
	p->right = NULL;
	p->left = NULL;
	p->src = (char*)"./MAP002.jpg";
	tail->down = p;
	tail = tail->down;
	
	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 3;
	p->down = NULL;
	p->up = NULL;
	p->right = tail;
	p->left = NULL;
	p->src = (char*)"./MAP003.jpg";
	tail->left = p;

	p = (mapnode*)malloc(sizeof(mapnode));
	p->number = 4;
	p->down = NULL;
	p->up = NULL;
	p->right = NULL;
	p->left = tail;
	p->src = (char*)"./MAP004.jpg";
	tail->right = p;

	return head;
}

没啥好说的src存放地图位置

移动检测

        利用了easyx中的ExMessage对象 

        由于每次循环初都会重新绘制画面上所有东西,所以在循环尾只需要对坐标做处理就会改变下次图形的位置。

	if (peekmessage(&msg, EM_KEY)) {
			switch (msg.message) {
			case WM_KEYDOWN:
				a = _getch();
				if (a == 'w' || a == 'W') {
					//SetWorkingImage(&character);
					i = peng(x, y - 48, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i], xpy[i] - 48, now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpy[0] -= 48;break;
								case 1:xpy[1] -= 48;break;
								case 2:xpy[2] -= 48;break;
								}
							}
						}
					}
					else {
						y -= 48;
					}
				}
				else if (a == 'a' || a == 'A') {
					i = peng(x - 48, y, now, xpx, xpy);
					if(i){
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i] - 48, xpy[i], now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpx[0] -= 48;break;
								case 1:xpx[1] -= 48;break;
								case 2:xpx[2] -= 48;break;
								}
							}
						}
					}
					
					else {
						x -= 48;
					}

				}
				else if (a == 's' || a == 'S') {
					i = peng(x, y + 48, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i], xpy[i] + 48, now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpy[0] += 48;break;
								case 1:xpy[1] += 48;break;
								case 2:xpy[2] += 48;break;
								}
							}
						}
					}
					
					else {
						y += 48;
					}

				}
				else if (a == 'd' || a == 'D') {
					i = peng(x + 48, y, now, xpx, xpy);
					if (i) {
						if (i > 5) {
							i = i - 10;
							if (peng(xpx[i] + 48, xpy[i], now, xpx, xpy)) {
							}
							else {
								switch (i) {
								case 0:xpx[0] += 48;break;
								case 1:xpx[1] += 48;break;
								case 2:xpx[2] += 48;break;
								}
							}
						}
					}
					else {
						x += 48;
					}

				}
				else if (a == 32) {
					//cleardevice();
				}

 碰撞检测

int peng(int x,int y,mapnode* nowroom,int xpx[],int xpy[]){
	int flag=0;
	int i = 0;
	if (x<0||y<0||x>10*48||y>10*48) {
		flag = 1;
	}
	if (nowroom->number == 1) {
		if (y <= 3 * 48 && x <= 10 * 48 || y == 6 * 48 && x == 2 * 48 || y == 4 * 48 && x == 9 * 48) {
			flag = 1;
		}
	}
	if (nowroom->number == 2) {
		if (y <= 1 * 48 && x <= 4 * 48|| y <= 1 * 48 && x >= 6 * 48&& x <= 10 * 48){
			flag = 1;
		}
	}
	if (nowroom->number == 3) {
		if (y==0||y==10 * 48 ||x==0||x<=3 * 48 &&y<=3 * 48 ||x<=3 * 48 &&y>=7 * 48 ||x>=7 * 48 &&y<=4 * 48 ||x>=7 * 48 &&y>=6 * 48) {
			flag = 1;
		}
		for (i=0;i < 3;i++) {
			if (x == xpx[i] && y == xpy[i]) {
				flag = i+10;
			}
		}
	}
	if (nowroom->number == 4) {
		if (y <= 1 * 48 && x <= 4 * 48 || y <= 1 * 48 && x >= 6 * 48 && x <= 10 * 48) {
			flag = 1;
		}
	}
	return flag;
}

这段先调用了一次碰撞检测函数peng()将人物是否碰上设定的物体或箱子返回,由于无法返回是哪个箱子,就自作聪明,将返回值改为对应的箱子号+10,这样在上一层函数中-10就能知道是哪个箱子。又调用了一次peng()函数判断箱子是否碰到物体或其他箱子,只要会碰上就不移动。这次返回0以外的其他数就没有什么区别了。

按理说这里应该再写个函数,使代码没那么臃肿,但是我感觉代码量应该不会差太多,加上赶时间。

资源

链接: https://pan.baidu.com/s/1mQCH5MHm24O-P5tuU1Od8g?pwd=58w6 提取码: 58w6 复制这段内容后打开百度网盘手机App,操作更方便哦

站内资源easyx图形库自制RPG类型小游戏配套资源-其他文档类资源-优快云下载


总结

部分资源使用了rpgmaker的免费素材

评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值