C/C++项目实战-推箱子小游戏

打印 上一主题 下一主题

主题 523|帖子 523|积分 1569

  1. #include <graphics.h>
  2. #include <iostream>
  3. #include <Windows.h>
  4. #include <string>
  5. #include <conio.h>
  6. using namespace std;
  7. #define LINE 9 //行数
  8. #define COLUMN 12 //列数
  9. #define RATIO 61 //图片大小
  10. #define START_X 64  //行偏移量
  11. #define START_Y 60 //列偏移量
  12. #define SCREEN_WIDTH 860 //屏幕的宽
  13. #define SCREEN_HEIGHT 668 //屏幕的高
  14. #define isValid(pos) pos.x>=0 && pos.x<LINE && pos.y>=0 && pos.y < COLUMN
  15. //控制键 上下左右控制方向 按‘q’退出
  16. #define KEY_UP 'W'
  17. #define KEY_DOWN 'S'
  18. #define KEY_LEFT 'A'
  19. #define KEY_RIGHT 'D'
  20. #define KEY_QUIT 'Q'
  21. /*游戏地图*/
  22. //墙: 0,地板: 1,箱子目的地: 2, 小人: 3, 箱子: 4, 箱子命中目标: 5
  23. int map[LINE][COLUMN] = {
  24. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  25. { 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
  26. { 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
  27. { 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
  28. { 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
  29. { 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
  30. { 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
  31. { 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
  32. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  33. };
  34. struct _POS {
  35.     int x;            //小人所在二维数组的行
  36.     int y;            //小人所在二维数组的列
  37. };
  38. enum _PROPS { //枚举常量 道具
  39.     WALL,//墙
  40.     FLOOR,//地板
  41.     BOX_DES,//箱子目的地
  42.     MAN,//人
  43.     BOX,//箱子
  44.     HIT,//箱子命中目标
  45.     ALL
  46. };
  47. enum _DIRECTION { //游戏方向控制
  48.     UP,
  49.     DOWN,
  50.     LEFT,
  51.     RIGHT
  52. };
  53. IMAGE images[ALL];
  54. struct _POS man;
  55. struct _POS box_des1;//临时的箱子目的地存放点
  56. struct _POS box_des2;
  57. void changeMap(struct _POS *man, enum _PROPS prop) {
  58.     map[man->x][man->y] = prop;
  59.     putimage(START_X + man->y * RATIO, START_Y + man->x * RATIO, &images[prop]);
  60. }
  61. /**********************************************
  62. *实现游戏四个方向(上、下、左、右)的控制
  63. * 输入:
  64. * direct - 人前进方向
  65. * 输出: 无
  66. **********************************************/
  67. void gameControl(enum _DIRECTION direct) {
  68.     struct _POS next_pos = man;
  69.     struct _POS next_next_pos = man;
  70.     switch (direct)
  71.     {
  72.     case UP:
  73.         next_pos.x--;
  74.         next_next_pos.x -= 2;
  75.         break;
  76.     case DOWN:
  77.         next_pos.x++;
  78.         next_next_pos.x += 2;
  79.         break;
  80.     case LEFT:
  81.         next_pos.y--;
  82.         next_next_pos.y -= 2;
  83.         break;
  84.     case RIGHT:
  85.         next_pos.y++;
  86.         next_next_pos.y += 2;
  87.         break;
  88.     }
  89.     if (isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR) {//人的前方是地板
  90.         if (map[man.x][man.y] == map[box_des1.x][box_des1.y] || map[man.x][man.y] == map[box_des2.x][box_des2.y]) { //如果人所在的位置是箱子目的地
  91.             changeMap(&next_pos, MAN);
  92.             changeMap(&man, BOX_DES);
  93.             man = next_pos;
  94.         }
  95.         else {
  96.             changeMap(&next_pos, MAN); //小人前进一格
  97.             changeMap(&man, FLOOR);
  98.             man = next_pos;
  99.         }
  100.     }
  101.     else if (map[next_pos.x][next_pos.y] == BOX_DES) {//如果人的前方是箱子目的地
  102.         box_des1.x = next_pos.x;
  103.         box_des1.y = next_pos.y;
  104.         changeMap(&next_pos, MAN);
  105.         changeMap(&man, FLOOR);
  106.         man = next_pos;
  107.     }
  108.     else if (map[next_pos.x][next_pos.y] == HIT) {//如果人的前方是HIT
  109.         changeMap(&next_next_pos, BOX);
  110.         changeMap(&next_pos, MAN); //小人前进一格
  111.         changeMap(&man, FLOOR);
  112.         man = next_pos;
  113.         box_des2.x = next_pos.x;
  114.         box_des2.y = next_pos.y;
  115.     }
  116.     else if (map[next_pos.x][next_pos.y] == BOX) {//人的前方是箱子
  117.         //两种情况,箱子前面是地板或者是箱子目的地
  118.         if (map[next_next_pos.x][next_next_pos.y] == FLOOR) {
  119.             changeMap(&next_next_pos, BOX);
  120.             changeMap(&next_pos, MAN); //小人前进一格
  121.             changeMap(&man, FLOOR);
  122.             man = next_pos;
  123.         }
  124.         else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) {
  125.             
  126.             changeMap(&next_next_pos, HIT);
  127.             changeMap(&next_pos, MAN); //小人前进一格
  128.             changeMap(&man, FLOOR);
  129.             man = next_pos;
  130.         }
  131.     }
  132. }
  133. /**********************************************
  134. * *游戏结束场景,在玩家通关后显示
  135. *输入:
  136. * bg - 背景图片变量的指针
  137. *返回值: 无
  138. **********************************************/
  139. void gameOverScene(IMAGE* bg) {
  140.     putimage(0, 0, bg);
  141.     settextcolor(WHITE);
  142.     RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
  143.     settextstyle(20, 0, _T("宋体"));
  144.     drawtext(_T("恭喜您~ \n 您终于成为了一个合格的搬箱子老司机!"),
  145.         &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  146. }
  147. void isGameFailed(IMAGE* bg) {
  148.     putimage(0, 0, bg);
  149.     settextcolor(WHITE);
  150.     RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
  151.     settextstyle(20, 0, _T("宋体"));
  152.     drawtext(_T("GameOver!你这个小垃圾哈哈哈哈!"),
  153.         &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  154. }
  155. /**********************************************
  156. *判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束
  157. *输入: 无
  158. *返回值:
  159. * true - 游戏结束 false - 游戏继续
  160. **********************************************/
  161. bool isGameOver() {
  162.     for (int i = 0; i < LINE; i++) {
  163.         for (int j = 0; j < COLUMN; j++) {
  164.             if (map[i][j] == BOX_DES) return false;
  165.         }
  166.     }
  167.     return true;
  168. }
  169. int main() {
  170.     IMAGE bg_img; //背景图片
  171.     int num = 0;//统计步数
  172.     initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
  173.     loadimage(&bg_img,_T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT,true);
  174.     putimage(0, 0, &bg_img);
  175.     //加载道具图标
  176.     loadimage(&images[WALL], _T("wall_right.bmp"), RATIO, RATIO, true);
  177.     loadimage(&images[FLOOR], _T("floor.bmp"), RATIO, RATIO, true);
  178.     loadimage(&images[BOX_DES], _T("des.bmp"), RATIO, RATIO, true);
  179.     loadimage(&images[MAN], _T("man.bmp"), RATIO, RATIO, true);
  180.     loadimage(&images[BOX], _T("box.bmp"), RATIO, RATIO, true);
  181.     loadimage(&images[HIT], _T("box.bmp"), RATIO, RATIO, true);
  182.     for (int i = 0; i < LINE; i++) {
  183.         for (int j = 0; j < COLUMN; j++) {
  184.             if (map[i][j] == 3) {
  185.                 man.x = i;
  186.                 man.y = j;
  187.             }
  188.             putimage(START_X + j * RATIO, START_Y + i * RATIO,
  189.                 &images[map[i][j]]);
  190.         }
  191.     }
  192.     //游戏开始环节
  193.     bool isQuit = false;
  194.     ExMessage msg;
  195.     do {
  196.         //if (_kbhit()) {//如果玩家点击键盘 //win11用不了此操作
  197.         //    char ch = _getch();
  198.         //    switch (ch)
  199.         //    {
  200.         //    case KEY_UP:
  201.         //        gameControl(UP);
  202.         //    case KEY_DOWN:
  203.         //        gameControl(DOWN);
  204.         //    case KEY_LEFT:
  205.         //        gameControl(LEFT);
  206.         //    case KEY_RIGHT:
  207.         //        gameControl(RIGHT);
  208.         //    case KEY_QUIT:
  209.         //        isQuit = true;
  210.         //    if (isGameOver()) {
  211.         //        gameOverScene(&bg_img);
  212.         //        isQuit = true;
  213.         //    }
  214.         //    }
  215.         //    Sleep(100);
  216.         //}
  217.         //WM_LBUTTONDOWN 鼠标左键按下
  218.         //WM_KEYDOWN 键盘按键按下
  219.         if (peekmessage(&msg) && msg.message == WM_KEYDOWN)
  220.         {
  221.             char ch = msg.vkcode;
  222.             num++;
  223.             switch (ch)
  224.             {
  225.             case KEY_UP:
  226.                 gameControl(UP);
  227.                 break;
  228.             case KEY_DOWN:
  229.                 gameControl(DOWN);
  230.                 break;
  231.             case KEY_LEFT:
  232.                 gameControl(LEFT);
  233.                 break;
  234.             case KEY_RIGHT:
  235.                 gameControl(RIGHT);
  236.                 break;
  237.             case KEY_QUIT:
  238.                 if (isGameOver()) {
  239.                     gameOverScene(&bg_img);
  240.                     isQuit = true;
  241.                 }
  242.                 break;
  243.             }
  244.             Sleep(100);
  245.             if (num > 80) {
  246.                 isGameFailed(&bg_img);
  247.                 isQuit = true;
  248.             }
  249.             if (isGameOver()) {
  250.                 gameOverScene(&bg_img);
  251.                 isQuit = true;
  252.             }
  253.         }
  254.     } while (!isQuit);
  255.     system("pause");
  256.     return 0;
  257. }
复制代码




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表