目录
一、游戏玩法
二、完整代码
三、部分细节
透明化人物背景
关于easyx库中怎样贴出透明图片
地图的链表实现
移动检测
碰撞检测
总结
前言:
花两天边看easyx文档边学边写的期末小作业。
学校挂c++的课教c语言入门:)
时间仓促没优化啥,摆了不找了。欢迎大佬帮忙指出不足。
欢迎c+v应付作业
有小小的bug,开局时切换为英文输入法,开局时切换为英文输入法,开局时切换为英文输入法
需要配合地图素材 素材和exe文件的打包下载在结尾。
一、游戏玩法
该游戏将操作主角完成一些小小的任务以脱离密闭的房间。
W A S D移动开局时切换为英文输入法
玩家将借助游戏中的门进出不同的房间
完成推箱子小游戏关后,玩家可从出口处出门完成游戏全部流程。
卧室
客厅小游戏关
出口
二、完整代码
#include三、部分细节 透明化人物背景#include #include #include 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.csdn.net/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,操作更方便哦
站内资源稍后补上
总结
部分资源使用了rpgmaker的免费素材



