当前位置:   article > 正文

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

用c和easyx实现游戏代码

目录

一、游戏玩法

二、完整代码

三、部分细节

透明化人物背景

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

地图的链表实现

移动检测

 碰撞检测

总结


前言:

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

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

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

欢迎c+v应付作业

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

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


一、游戏玩法

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

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

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

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

卧室

50e0a58268bb4c8e9c504005142824bf.png

 客厅

6c4100adc1a54edbace1a385baa3db28.jpeg

小游戏关

9790fb9492194a18904137918a58fbbe.jpeg

出口

aca5cd5df50642d6bb4f2c7a792ffe0f.jpeg

二、完整代码

  1. #include <easyx.h>
  2. #include <conio.h>
  3. #include<Windows.h>
  4. #include<iostream>
  5. using namespace std;
  6. //设置房间链表的节点
  7. typedef struct map {
  8. int number;
  9. struct map* up;
  10. struct map* down;
  11. struct map* left;
  12. struct map* right;
  13. struct map* next;
  14. char* src;
  15. }mapnode;
  16. void rungame();
  17. mapnode* createmaplist();//创建地图函数
  18. void showmainmenu();//展示主菜单函数
  19. int peng(int x, int y, mapnode* nowroom, int xpx[], int xpy[]);//碰撞检测函数
  20. int ifwin( int* xpx,int* xpy);//游戏胜负条件检测函数
  21. int main()
  22. {
  23. showmainmenu();
  24. _getch();
  25. closegraph();
  26. return 0;
  27. }
  28. //创建地图函数
  29. mapnode* createmaplist() {
  30. mapnode* head = (mapnode*)malloc(sizeof(mapnode));
  31. mapnode* p, * tail = head;
  32. p = (mapnode*)malloc(sizeof(mapnode));
  33. p->number = 1;
  34. p->down = NULL;
  35. p->up = NULL;
  36. p->right = NULL;
  37. p->left = NULL;
  38. p->src = (char*)"./MAP001.jpg";
  39. tail->next = p;
  40. tail = tail->next;
  41. p = (mapnode*)malloc(sizeof(mapnode));
  42. p->number = 2;
  43. p->down = NULL;
  44. p->up = tail;
  45. p->right = NULL;
  46. p->left = NULL;
  47. p->src = (char*)"./MAP002.jpg";
  48. tail->down = p;
  49. tail = tail->down;
  50. p = (mapnode*)malloc(sizeof(mapnode));
  51. p->number = 3;
  52. p->down = NULL;
  53. p->up = NULL;
  54. p->right = tail;
  55. p->left = NULL;
  56. p->src = (char*)"./MAP003.jpg";
  57. tail->left = p;
  58. p = (mapnode*)malloc(sizeof(mapnode));
  59. p->number = 4;
  60. p->down = NULL;
  61. p->up = NULL;
  62. p->right = NULL;
  63. p->left = tail;
  64. p->src = (char*)"./MAP004.jpg";
  65. tail->right = p;
  66. return head;
  67. }
  68. //展示主菜单函数
  69. void showmainmenu() {
  70. //初始化窗口
  71. initgraph(528, 528);
  72. setbkcolor(WHITE);
  73. cleardevice();
  74. //初始化标题字体
  75. settextcolor(BLACK);
  76. settextstyle(80, 0, "楷体");
  77. setbkmode(TRANSPARENT);
  78. char* arr = (char*)"李华传";
  79. int x, y;
  80. x=264-textwidth(arr)/2;
  81. y=100-textheight(arr)/2;
  82. outtextxy(x,y,arr);
  83. //加了层阴影
  84. settextcolor(RGB(154, 167, 177));
  85. outtextxy(x+5, y+5, arr);
  86. settextcolor(BLACK);
  87. //开始游戏按钮和字体初始化
  88. setfillcolor(WHITE);
  89. setlinecolor(BLACK);
  90. setlinestyle(PS_SOLID);
  91. arr= (char*)"开始游戏";
  92. settextstyle(40, 0, "微软雅黑");
  93. x = 264 - textwidth(arr) / 2;
  94. y = 250 - textheight(arr) / 2;
  95. fillroundrect(x - 20, y - 20, x + textwidth(arr)+20, y + textheight(arr)+20, 20, 20);
  96. outtextxy(x,y,arr);
  97. arr = (char*)"version 0.1";
  98. settextstyle(20, 0, "微软雅黑");
  99. outtextxy(450, 500,arr);
  100. settextstyle(40, 0, "微软雅黑");
  101. arr = (char*)"开始游戏";
  102. //接收鼠标信息
  103. ExMessage msg;
  104. int flag = 0;
  105. while (1) {
  106. if (peekmessage(&msg, EM_MOUSE)) {
  107. switch (msg.message) {
  108. case WM_LBUTTONUP:
  109. if (msg.x >= x - 20 && msg.x <= x + textwidth(arr) + 20 && msg.y >= y - 20 && msg.y <= y + textheight(arr) + 20) {
  110. flag = 1;
  111. rungame();
  112. break;
  113. }
  114. case WM_MOUSEMOVE:
  115. if (msg.x >= x - 20 && msg.x <= x + textwidth(arr) + 20 && msg.y >= y - 20 && msg.y <= y + textheight(arr) + 20) {
  116. setfillcolor(RGB(154, 167, 177));
  117. fillroundrect(x - 20+1, y - 20+1, x + textwidth(arr) + 21, y + textheight(arr) + 21, 20, 20);
  118. outtextxy(x, y, arr);
  119. }
  120. else {
  121. setfillcolor(WHITE);
  122. fillroundrect(x - 20, y - 20, x + textwidth(arr) + 20, y + textheight(arr) + 20, 20, 20);
  123. outtextxy(x, y, arr);
  124. }
  125. break;
  126. }
  127. }
  128. if (flag == 0) {
  129. }
  130. else {
  131. break;
  132. }
  133. }
  134. }
  135. void rungame() {
  136. //初始化窗口
  137. clearrectangle(0, 0, 600, 600);
  138. setbkcolor(YELLOW);
  139. cleardevice();
  140. //初始化地图链表
  141. mapnode* head = createmaplist();
  142. mapnode* now = head->next;
  143. //初始化人物及背景对象
  144. IMAGE nowroombk;
  145. IMAGE xiang;
  146. loadimage(&nowroombk, now->src, 0, 0);
  147. IMAGE character1, character2, character3;
  148. loadimage(&character1, "./原.jpg", 48, 48);
  149. loadimage(&character2, "a.png", 48, 48);
  150. loadimage(&character3, "b.png", 48, 48);
  151. loadimage(&xiang, "xian.png", 48, 48);
  152. int x = 240, y = 240;
  153. ExMessage msg;
  154. int a;
  155. int xpx[3] = { 6 * 48 ,8 * 48, 6 * 48 };
  156. int xpy[3] = { 4 * 48 ,5 * 48 ,6 * 48 };
  157. //开始主循环
  158. while (1) {
  159. putimage(0, 0, &nowroombk);
  160. putimage(x, y, &character3, SRCAND);
  161. putimage(x, y, &character2, SRCPAINT);
  162. if (now->number == 3) {
  163. putimage(xpx[0], xpy[0], &xiang);
  164. putimage(xpx[1], xpy[1], &xiang);
  165. putimage(xpx[2], xpy[2], &xiang);
  166. }
  167. int i,win=0;
  168. //检测是否碰撞
  169. //这里会不好看 看我文章
  170. if (peekmessage(&msg, EM_KEY)) {
  171. switch (msg.message) {
  172. case WM_KEYDOWN:
  173. a = _getch();
  174. if (a == 'w' || a == 'W') {
  175. //SetWorkingImage(&character);
  176. i = peng(x, y - 48, now, xpx, xpy);
  177. if (i) {
  178. if (i > 5) {
  179. i = i - 10;
  180. if (peng(xpx[i], xpy[i] - 48, now, xpx, xpy)) {
  181. }
  182. else {
  183. switch (i) {
  184. case 0:xpy[0] -= 48;break;
  185. case 1:xpy[1] -= 48;break;
  186. case 2:xpy[2] -= 48;break;
  187. }
  188. }
  189. }
  190. }
  191. else {
  192. y -= 48;
  193. }
  194. }
  195. else if (a == 'a' || a == 'A') {
  196. i = peng(x - 48, y, now, xpx, xpy);
  197. if(i){
  198. if (i > 5) {
  199. i = i - 10;
  200. if (peng(xpx[i] - 48, xpy[i], now, xpx, xpy)) {
  201. }
  202. else {
  203. switch (i) {
  204. case 0:xpx[0] -= 48;break;
  205. case 1:xpx[1] -= 48;break;
  206. case 2:xpx[2] -= 48;break;
  207. }
  208. }
  209. }
  210. }
  211. else {
  212. x -= 48;
  213. }
  214. }
  215. else if (a == 's' || a == 'S') {
  216. i = peng(x, y + 48, now, xpx, xpy);
  217. if (i) {
  218. if (i > 5) {
  219. i = i - 10;
  220. if (peng(xpx[i], xpy[i] + 48, now, xpx, xpy)) {
  221. }
  222. else {
  223. switch (i) {
  224. case 0:xpy[0] += 48;break;
  225. case 1:xpy[1] += 48;break;
  226. case 2:xpy[2] += 48;break;
  227. }
  228. }
  229. }
  230. }
  231. else {
  232. y += 48;
  233. }
  234. }
  235. else if (a == 'd' || a == 'D') {
  236. i = peng(x + 48, y, now, xpx, xpy);
  237. if (i) {
  238. if (i > 5) {
  239. i = i - 10;
  240. if (peng(xpx[i] + 48, xpy[i], now, xpx, xpy)) {
  241. }
  242. else {
  243. switch (i) {
  244. case 0:xpx[0] += 48;break;
  245. case 1:xpx[1] += 48;break;
  246. case 2:xpx[2] += 48;break;
  247. }
  248. }
  249. }
  250. }
  251. else {
  252. x += 48;
  253. }
  254. }
  255. else if (a == 32) {
  256. //cleardevice();
  257. }
  258. cleardevice();
  259. break;
  260. }
  261. }
  262. //房间移动
  263. if (x >= 5 * 48 && x <= 6 * 48 && y >= 10 * 48 && y <= 11 * 48) {
  264. if (now->down) {
  265. now = now->down;
  266. x = 5 * 48;
  267. y = 2 * 48;
  268. loadimage(&nowroombk, now->src, 0, 0);
  269. }
  270. }
  271. if (x >= 5 * 48 && x <= 6 * 48 && y >= 0 * 48 && y < 1 * 48) {
  272. if (now->up) {
  273. now = now->up;
  274. x = 5 * 48;
  275. y = 9 * 48;
  276. loadimage(&nowroombk, now->src, 0, 0);
  277. }
  278. }
  279. if (x >= 0 * 48 && x <= 1 * 48 && y >= 5 * 48 && y <= 6 * 48) {
  280. if (now->left) {
  281. now = now->left;
  282. x = 9 * 48;
  283. y = 5 * 48;
  284. loadimage(&nowroombk, now->src, 0, 0);
  285. }
  286. }
  287. if (x >= 10 * 48 && x <= 11 * 48 && y >= 5 * 48 && y <= 6 * 48) {
  288. if (now->right) {
  289. now = now->right;
  290. x = 2 * 48;
  291. y = 5 * 48;
  292. loadimage(&nowroombk, now->src, 0, 0);
  293. }
  294. }
  295. if (ifwin(xpx, xpy)) {
  296. if (now->number == 4, x == 5 * 48, y == 1 * 48) {
  297. break;
  298. }
  299. }
  300. }
  301. }
  302. //碰撞检测函数
  303. int peng(int x,int y,mapnode* nowroom,int xpx[],int xpy[]){
  304. int flag=0;
  305. int i = 0;
  306. if (x<0||y<0||x>10*48||y>10*48) {
  307. flag = 1;
  308. }
  309. if (nowroom->number == 1) {
  310. if (y <= 3 * 48 && x <= 10 * 48 || y == 6 * 48 && x == 2 * 48 || y == 4 * 48 && x == 9 * 48) {
  311. flag = 1;
  312. }
  313. }
  314. if (nowroom->number == 2) {
  315. if (y <= 1 * 48 && x <= 4 * 48|| y <= 1 * 48 && x >= 6 * 48&& x <= 10 * 48){
  316. flag = 1;
  317. }
  318. }
  319. if (nowroom->number == 3) {
  320. 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) {
  321. flag = 1;
  322. }
  323. for (i=0;i < 3;i++) {
  324. if (x == xpx[i] && y == xpy[i]) {
  325. flag = i+10;
  326. }
  327. }
  328. }
  329. if (nowroom->number == 4) {
  330. if (y <= 1 * 48 && x <= 4 * 48 || y <= 1 * 48 && x >= 6 * 48 && x <= 10 * 48) {
  331. flag = 1;
  332. }
  333. }
  334. return flag;
  335. }
  336. //游戏胜负条件检测函数
  337. int ifwin( int* xpx, int* xpy) {
  338. int i = 0;
  339. 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]) {
  340. return 1;
  341. }
  342. return 0;
  343. }

三、部分细节

透明化人物背景

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

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

原文链接:https://blog.csdn.net/weixin_45848751/article/details/106983700

地图的链表实现

  1. mapnode* createmaplist() {
  2. mapnode* head = (mapnode*)malloc(sizeof(mapnode));
  3. mapnode* p, * tail = head;
  4. p = (mapnode*)malloc(sizeof(mapnode));
  5. p->number = 1;
  6. p->down = NULL;
  7. p->up = NULL;
  8. p->right = NULL;
  9. p->left = NULL;
  10. p->src = (char*)"./MAP001.jpg";
  11. tail->next = p;
  12. tail = tail->next;
  13. p = (mapnode*)malloc(sizeof(mapnode));
  14. p->number = 2;
  15. p->down = NULL;
  16. p->up = tail;
  17. p->right = NULL;
  18. p->left = NULL;
  19. p->src = (char*)"./MAP002.jpg";
  20. tail->down = p;
  21. tail = tail->down;
  22. p = (mapnode*)malloc(sizeof(mapnode));
  23. p->number = 3;
  24. p->down = NULL;
  25. p->up = NULL;
  26. p->right = tail;
  27. p->left = NULL;
  28. p->src = (char*)"./MAP003.jpg";
  29. tail->left = p;
  30. p = (mapnode*)malloc(sizeof(mapnode));
  31. p->number = 4;
  32. p->down = NULL;
  33. p->up = NULL;
  34. p->right = NULL;
  35. p->left = tail;
  36. p->src = (char*)"./MAP004.jpg";
  37. tail->right = p;
  38. return head;
  39. }

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

移动检测

        利用了easyx中的ExMessage对象 

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

  1. if (peekmessage(&msg, EM_KEY)) {
  2. switch (msg.message) {
  3. case WM_KEYDOWN:
  4. a = _getch();
  5. if (a == 'w' || a == 'W') {
  6. //SetWorkingImage(&character);
  7. i = peng(x, y - 48, now, xpx, xpy);
  8. if (i) {
  9. if (i > 5) {
  10. i = i - 10;
  11. if (peng(xpx[i], xpy[i] - 48, now, xpx, xpy)) {
  12. }
  13. else {
  14. switch (i) {
  15. case 0:xpy[0] -= 48;break;
  16. case 1:xpy[1] -= 48;break;
  17. case 2:xpy[2] -= 48;break;
  18. }
  19. }
  20. }
  21. }
  22. else {
  23. y -= 48;
  24. }
  25. }
  26. else if (a == 'a' || a == 'A') {
  27. i = peng(x - 48, y, now, xpx, xpy);
  28. if(i){
  29. if (i > 5) {
  30. i = i - 10;
  31. if (peng(xpx[i] - 48, xpy[i], now, xpx, xpy)) {
  32. }
  33. else {
  34. switch (i) {
  35. case 0:xpx[0] -= 48;break;
  36. case 1:xpx[1] -= 48;break;
  37. case 2:xpx[2] -= 48;break;
  38. }
  39. }
  40. }
  41. }
  42. else {
  43. x -= 48;
  44. }
  45. }
  46. else if (a == 's' || a == 'S') {
  47. i = peng(x, y + 48, now, xpx, xpy);
  48. if (i) {
  49. if (i > 5) {
  50. i = i - 10;
  51. if (peng(xpx[i], xpy[i] + 48, now, xpx, xpy)) {
  52. }
  53. else {
  54. switch (i) {
  55. case 0:xpy[0] += 48;break;
  56. case 1:xpy[1] += 48;break;
  57. case 2:xpy[2] += 48;break;
  58. }
  59. }
  60. }
  61. }
  62. else {
  63. y += 48;
  64. }
  65. }
  66. else if (a == 'd' || a == 'D') {
  67. i = peng(x + 48, y, now, xpx, xpy);
  68. if (i) {
  69. if (i > 5) {
  70. i = i - 10;
  71. if (peng(xpx[i] + 48, xpy[i], now, xpx, xpy)) {
  72. }
  73. else {
  74. switch (i) {
  75. case 0:xpx[0] += 48;break;
  76. case 1:xpx[1] += 48;break;
  77. case 2:xpx[2] += 48;break;
  78. }
  79. }
  80. }
  81. }
  82. else {
  83. x += 48;
  84. }
  85. }
  86. else if (a == 32) {
  87. //cleardevice();
  88. }

 碰撞检测

  1. int peng(int x,int y,mapnode* nowroom,int xpx[],int xpy[]){
  2. int flag=0;
  3. int i = 0;
  4. if (x<0||y<0||x>10*48||y>10*48) {
  5. flag = 1;
  6. }
  7. if (nowroom->number == 1) {
  8. if (y <= 3 * 48 && x <= 10 * 48 || y == 6 * 48 && x == 2 * 48 || y == 4 * 48 && x == 9 * 48) {
  9. flag = 1;
  10. }
  11. }
  12. if (nowroom->number == 2) {
  13. if (y <= 1 * 48 && x <= 4 * 48|| y <= 1 * 48 && x >= 6 * 48&& x <= 10 * 48){
  14. flag = 1;
  15. }
  16. }
  17. if (nowroom->number == 3) {
  18. 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) {
  19. flag = 1;
  20. }
  21. for (i=0;i < 3;i++) {
  22. if (x == xpx[i] && y == xpy[i]) {
  23. flag = i+10;
  24. }
  25. }
  26. }
  27. if (nowroom->number == 4) {
  28. if (y <= 1 * 48 && x <= 4 * 48 || y <= 1 * 48 && x >= 6 * 48 && x <= 10 * 48) {
  29. flag = 1;
  30. }
  31. }
  32. return flag;
  33. }

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

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

资源

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

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


总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/358876
推荐阅读
相关标签
  

闽ICP备14008679号