Jicehel

Metabomber (temp version)

Sep 23rd, 2018
203
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.    作者:LHW-HWT
  3.    发现BUG或者想完善游戏可以发送邮件到1281702594@qq.com
  4.    本作品使用CC协议 可以用作教育用途 禁止 盈利性用途
  5.   您可以自由地:
  6.   共享 — 在任何媒介以任何形式复制、发行本作品
  7.   演绎 — 修改、转换或以本作品为基础进行创作
  8.   只要你遵守许可协议条款,许可人就无法收回你的这些权利。
  9.   署名 — 您必须给出适当的署名,提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示许可人为您或您的使用背书。
  10.   非商业性使用 — 您不得将本作品用于商业目的。包括直接拿去参加比赛
  11.   相同方式共享 — 如果您再混合、转换或者基于本作品进行创作,您必须基于与原先许可协议相同的许可协议 分发您贡献的作品。
  12.   没有附加限制 — 您不得适用法律术语或者 技术措施 从而限制其他人做许可协议允许的事情。
  13. */
  14.  
  15. /*
  16.      0  1  2  3  4  5
  17.      ↑  ↓  ←  →  A  B
  18. */
  19. #include <Gamebuino-Meta.h>
  20.  
  21. /*=========================================================
  22.                       Graphismes
  23.   =========================================================*/
  24.  
  25. /*   Animation du personnage    */
  26. const uint8_t Man_L_1[] PROGMEM = {8, 8, 0x7d, 0x2e, 0x7d, 0x3c, 0x56, 0x6a, 0x3c, 0x28};
  27. const uint8_t Man_L_2[] PROGMEM = {8, 8, 0x7d, 0x2e, 0x7d, 0x3c, 0x56, 0x2a, 0x3c, 0x28};
  28. const uint8_t Man_L_3[] PROGMEM = {8, 8, 0x7d, 0x2e, 0x7d, 0x3c, 0x54, 0x6a, 0x3c, 0x28};
  29. const uint8_t Man_R_1[] PROGMEM = {8, 8, 0xbe, 0x74, 0xbe, 0x3c, 0x56, 0x6a, 0x3c, 0x14};
  30. const uint8_t Man_R_2[] PROGMEM = {8, 8, 0xbe, 0x74, 0xbe, 0x3c, 0x56, 0x2a, 0x3c, 0x14};
  31. const uint8_t Man_R_3[] PROGMEM = {8, 8, 0xbe, 0x74, 0xbe, 0x3c, 0x54, 0x6a, 0x3c, 0x14};
  32. const uint8_t Man_U_1[] PROGMEM = {8, 8, 0x3c, 0x3c, 0x3c, 0x3c, 0x56, 0x6a, 0x3c, 0x28};
  33. const uint8_t Man_U_2[] PROGMEM = {8, 8, 0x3c, 0x3c, 0x3c, 0x3c, 0x56, 0x2a, 0x3c, 0x28};
  34. const uint8_t Man_U_3[] PROGMEM = {8, 8, 0x3c, 0x3c, 0x3c, 0x3c, 0x54, 0x6a, 0x3c, 0x28};
  35. const uint8_t Man_D_1[] PROGMEM = {8, 8, 0x3c, 0x28, 0x3c, 0x3c, 0x56, 0x6a, 0x3c, 0x28};
  36. const uint8_t Man_D_2[] PROGMEM = {8, 8, 0x3c, 0x28, 0x3c, 0x3c, 0x56, 0x2a, 0x3c, 0x28};
  37. const uint8_t Man_D_3[] PROGMEM = {8, 8, 0x3c, 0x28, 0x3c, 0x3c, 0x54, 0x6a, 0x3c, 0x28};
  38. const unsigned char *Man_table[] = { Man_U_1, Man_U_2, Man_U_3, Man_R_1, Man_R_2, Man_R_3, Man_D_1, Man_D_2, Man_D_3, Man_L_1, Man_L_2, Man_L_3};
  39.  
  40. /*    Monstre    */
  41. const uint8_t M_L[] PROGMEM = {8, 8, 0x3c, 0x42, 0xa9, 0xa9, 0x81, 0x81, 0x7e, 0x18};
  42. const uint8_t M_R[] PROGMEM = {8, 8, 0x3c, 0x42, 0x95, 0x95, 0x81, 0x81, 0x7e, 0x18};
  43. const uint8_t M_U[] PROGMEM = {8, 8, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x7e, 0x18};
  44. const uint8_t M_D[] PROGMEM = {8, 8, 0x3c, 0x42, 0xa5, 0xa5, 0x81, 0x81, 0x7e, 0x18};
  45. const unsigned char *M_table[] = {M_U, M_R, M_D, M_L};
  46.  
  47. /*   Bombe    */
  48. const uint8_t BOOM_1[] PROGMEM = {8, 8, 0x00, 0x10, 0x2c, 0x3a, 0x5c, 0x34, 0x08, 0x00};
  49. const uint8_t BOOM_2[] PROGMEM = {8, 8, 0x00, 0x52, 0x2c, 0x22, 0x44, 0x34, 0x4a, 0x00};
  50. const uint8_t BOOM_3[] PROGMEM = {8, 8, 0x50, 0x21, 0x0a, 0x21, 0x98, 0x40, 0x84, 0x0a};
  51. const unsigned char *BOOM_table[] = {BOOM_1, BOOM_2, BOOM_3};
  52.  
  53. /*   Autre graphismes  */
  54. const uint8_t WALL_1[] PROGMEM = {8, 8, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xff};
  55. const uint8_t WALL_2[] PROGMEM = {8, 8, 0x80, 0xff, 0x30, 0x20, 0xff, 0x06, 0x04, 0xff};
  56. const uint8_t TNT_1[] PROGMEM = {8, 8, 0x0c, 0x12, 0x78, 0xdc, 0xbc, 0xbc, 0xfc, 0x78};
  57. const uint8_t TNT_2[] PROGMEM = {8, 8, 0x0d, 0x12, 0x79, 0xdc, 0xbc, 0xbc, 0xfc, 0x78};
  58. const uint8_t DOOR[] PROGMEM = {8, 8, 0x6e, 0xef, 0xef, 0xab, 0xab, 0xef, 0xef, 0x6e};
  59. const uint8_t LOVE[] PROGMEM = {8, 8, 0x00, 0x66, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x18};
  60. const uint8_t START_TITLE[] PROGMEM = {87, 39, 0xff, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x87, 0x8f, 0xfe, 0x3f, 0x0f, 0x8f, 0x3f, 0xf0, 0xf8, 0xfc, 0xc1, 0x87, 0x8f, 0xfe, 0x3f, 0x0f, 0x8f, 0x3f, 0xf0, 0xf8, 0xfc, 0xff, 0x1c, 0xce, 0x67, 0x33, 0x99, 0xce, 0x33, 0x19, 0x8c, 0xc6, 0xff, 0x1c, 0xce, 0x67, 0x33, 0x99, 0xce, 0x33, 0x19, 0x8c, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x9f, 0xcc, 0x33, 0x18, 0x7c, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x98, 0x0c, 0x33, 0x18, 0xcc, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x98, 0x0c, 0x33, 0x18, 0xcc, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x98, 0x0c, 0x33, 0x19, 0x8c, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x98, 0x0c, 0x33, 0x19, 0x8c, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x99, 0xcc, 0x33, 0x19, 0x8c, 0xc6, 0xc1, 0x9c, 0xce, 0x67, 0x33, 0x99, 0xcc, 0x33, 0x19, 0x8c, 0xc6, 0xff, 0x07, 0x8e, 0x67, 0x3f, 0x0f, 0x8c, 0x33, 0x18, 0xfc, 0xc6, 0xff, 0x07, 0x8e, 0x67, 0x3f, 0x0f, 0x8c, 0x33, 0x18, 0xfc, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x02, 0x8a, 0x02, 0x0a, 0x0a, 0x88, 0x02, 0x08, 0x88, 0x82, 0x55, 0x05, 0x04, 0x45, 0x15, 0x05, 0x04, 0x11, 0x10, 0x54, 0x44, 0x80, 0x88, 0x8a, 0x22, 0x22, 0x88, 0x88, 0x22, 0x08, 0x88, 0x82, 0x41, 0x14, 0x44, 0x45, 0x11, 0x11, 0x44, 0x11, 0x11, 0x04, 0x44, 0x80, 0x88, 0x88, 0x20, 0x20, 0x88, 0x08, 0x20, 0x08, 0x88, 0x80, 0x41, 0x14, 0x44, 0x45, 0x11, 0x10, 0x04, 0x11, 0x11, 0x04, 0x44, 0x80, 0x88, 0x8a, 0x22, 0x22, 0x88, 0x08, 0x22, 0x08, 0x88, 0x82, 0x41, 0x14, 0x44, 0x45, 0x11, 0x10, 0x04, 0x11, 0x10, 0x44, 0x44, 0x80, 0x88, 0x8a, 0x02, 0x02, 0x8a, 0x88, 0x02, 0x08, 0x08, 0x82, 0x55, 0x14, 0x44, 0x45, 0x11, 0x11, 0x44, 0x11, 0x11, 0x04, 0x44, 0xaa, 0x08, 0x8a, 0x22, 0x22, 0x88, 0x8a, 0x22, 0x08, 0x88, 0x82, 0x41, 0x05, 0x05, 0x54, 0x15, 0x05, 0x05, 0x15, 0x50, 0x50, 0x54, 0x80, 0x80, 0x88, 0xa8, 0x28, 0x08, 0x88, 0x28, 0xa0, 0xa8, 0xa8, 0x41, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  61. const uint8_t TITLE_TNT[] PROGMEM = {37, 41, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x05, 0x53, 0xf8, 0x00, 0x00, 0x2e, 0xaa, 0xa8, 0x00, 0x00, 0x55, 0x00, 0x38, 0x00, 0x00, 0x31, 0xa2, 0xa0, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x01, 0xe0, 0xaa, 0xa0, 0x00, 0x01, 0x41, 0x00, 0x30, 0x00, 0x1b, 0xa3, 0xaa, 0xf8, 0x00, 0x15, 0x40, 0x13, 0x00, 0x00, 0x0f, 0xe0, 0x0a, 0x00, 0x00, 0x55, 0x50, 0x0a, 0x00, 0x01, 0xbb, 0xba, 0x04, 0x00, 0x05, 0x55, 0x55, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x15, 0x55, 0x55, 0x40, 0x00, 0x1b, 0xbb, 0xbb, 0x80, 0x00, 0x15, 0x55, 0x55, 0x40, 0x00, 0x6f, 0xef, 0xef, 0xe0, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0x3b, 0xbb, 0xbb, 0xb0, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0xbb, 0xbb, 0xbb, 0xb8, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0xef, 0xef, 0xef, 0xe8, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0x3b, 0xbb, 0xbb, 0xb0, 0x00, 0x55, 0x55, 0x55, 0x50, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x15, 0x55, 0x55, 0x40, 0x00, 0x3b, 0xbb, 0xbb, 0x80, 0x00, 0x15, 0x55, 0x55, 0x40, 0x00, 0x0f, 0xef, 0xef, 0x80, 0x00, 0x05, 0x55, 0x55, 0x00, 0x00, 0x01, 0xbb, 0xb8, 0x00, 0x00, 0x00, 0x55, 0x50, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00};
  62. const uint8_t LHW[] PROGMEM = {39, 5, 0x72, 0x25, 0x10, 0x94, 0x5e, 0x8a, 0x25, 0x16, 0x94, 0x48, 0xaa, 0x3d, 0x56, 0xf5, 0x48, 0x8a, 0x25, 0x50, 0x95, 0x48, 0x73, 0xa4, 0xa0, 0x92, 0x88};
  63. const unsigned char *TNT_table[] = {TNT_1, TNT_2};
  64.  
  65.  
  66. /*=========================================================
  67.              Déclaration des vaiables
  68.   =========================================================*/
  69. byte LIFE;     // Nombre de vies
  70. byte LEVEL;    // Niveau actuel
  71. byte MAP[31][15];     // Carte du niveau
  72. byte monster[10][2];  // 格式 怪物编号 坐标
  73. byte MLRUD[10]; //怪物方向 0为左 1为右 2为上 3为下 255为怪物已经死亡
  74. byte PX, PY, PP, PS; // Position en X, Y, Direction,
  75. bool PMove = false;
  76. bool MMMod; //怪物移动模式 false 为顺时针 true为逆时针
  77. bool BMove; //判断是否有障碍物的全局返回值
  78. char CSX, CSY; //坐标轴画布移位值 0-7
  79. byte SBDPL[] = {1, 2, 3}; //障碍物列表
  80. byte TntList[10][2];  //TNT坐标
  81. byte TNTN; //TNT个数
  82. unsigned long TntTime[10]; // Temps des bombes
  83. unsigned long MMTime;      // Stock les millisecondes à chaque déplacement des montres
  84. unsigned long PIT; //玩家无敌时间
  85. byte TNTS; //TNT动态效果
  86. bool PWIN;
  87. #define BOOMTime 3000 //TNT爆炸需要等待的时间
  88. #define MMTimeOut 100 // Temps en ms entre 2 mouvements des monstres
  89. #define Invincible_Time 5000 // Temps d'invincibilité à l'apparition du joueur
  90. /*====================================================================
  91.                              软重启函数
  92.   ====================================================================*/
  93. void(* resetFunc) (void) = 0; //制造重启命令
  94. /*=========================================================
  95.                      只循环一次
  96.   =========================================================*/
  97. void setup() {
  98.   gb.begin();
  99.   MENU();
  100.   LEVEL = 1;
  101.   ShowLevel();
  102.   BuildMap();
  103. }
  104. /*=========================================================
  105.                      不停循环
  106.   =========================================================*/
  107. void loop() {
  108.   if (!gb.update()) return;
  109.   if (LIFE == 0) FAIL();
  110.   Draw();
  111.   logic();
  112. }
  113.  
  114.  
  115. /*=========================================================
  116.   Création de la carte
  117.   =========================================================*/
  118. void BuildMap() {
  119.   /* Liste des états possibles de la carte
  120.      0  Vide
  121.      1  Mur 1
  122.      2  Mur 2
  123.      3  TNT
  124.      4  Bombe 3
  125.      5  Bombe 2
  126.      6  Bombe 1
  127.   */
  128.   // Iinitialisation du niveau
  129.   LIFE = 3; // Initalise le nombre de vies
  130.   byte MN = 0; // Compteur de monstres
  131.   PP = 2; // Direction vers le bas par défaut
  132.  
  133.   // Boucle d'effacement des bombes
  134.   for (byte n = 0; n < 10; n++) {
  135.     TntTime[n] = 0;  // Remise à 0 de l'tat des bombes
  136.     MLRUD[n] = 255;
  137.   }
  138.  
  139.   // Boucle de création du niveau
  140.   for (byte y = 0; y < 15; y++) {
  141.     for (byte x = 0; x < 31; x++) {
  142.       // Dessine des murs sur la première et la dernière ligne
  143.       if (y == 0 || y == 14) {
  144.         MAP[x][y] = 1;
  145.         // Dessine des murs sur la première et la dernière colonne
  146.       } else if (x == 0 || x == 30) {
  147.         MAP[x][y] = 1;
  148.       } else {
  149.         // Mets un mur toutes les 2 cases
  150.         if (x % 2 == 0 && y % 2 == 0) {
  151.           MAP[x][y] = 1;
  152.         } else if (random(0, 4) == 0) {
  153.           MAP[x][y] = 2;
  154.         } else if (random(0, 28) == 0) {
  155.           // Mémorisation du monstre s'il en reste à ajouter pour le niveau
  156.           if (MN < LEVEL) {
  157.             monster[MN][0] = x;
  158.             monster[MN][1] = y;
  159.             MLRUD[MN] = 2; //设置怪物方向为头朝下
  160.             MN++;  // incrémente le compteur de monstres
  161.           }
  162.         } else MAP[x][y] = 0; // vide si le nombe de monstres à placer a déjà était atteint
  163.       }
  164.     }
  165.   }
  166.   //设置玩家出生点
  167.   for (byte py = 0; py < 3; py++) {
  168.     for (byte px = 0; px < 3; px++) {
  169.       //清空出生点附近的普通墙和怪物,确保出生点安全
  170.       MAP[15 - 1 + px][7 - 1 + py] = 0;
  171.     }
  172.   }
  173.   PX = 15;
  174.   PY = 7;
  175.   PIT = millis();
  176. }
  177.  
  178. /*====================================================================
  179.             Dessine les éléments à l'écran
  180.   ====================================================================*/
  181. void Draw() {
  182.   DrawMap();    // Dessine la carte
  183.   DrawEntity(); // Dessine les éléments actifs (joueur, monstres, ..)
  184.   gb.display.setColor(BLACK);
  185.   gb.display.fillRect(0, 56, 128, 8);
  186.   for (byte ni = 0; ni < LIFE; ni++) {
  187.     gb.display.setColor(RED);
  188.     gb.display.drawBitmap(ni * 9, 56, LOVE); // Dessine les vies restantes
  189.   }
  190. }
  191.  
  192. /*====================================================================
  193.                   Dessine la carte
  194.   ====================================================================*/
  195. void DrawMap() {
  196.   gb.display.setColor(BLACK);
  197.   gb.display.fillRect(0, 0, 128, 64);
  198.   gb.display.setColor(WHITE);
  199.   for (char y = PY - 4; y < PY + 5; y++) {
  200.     for (char x = PX - 8; x < PX + 10; x++) {
  201.       if (x >= 0 && y >= 0 && x <= 30 && y <= 14) {
  202.         switch (MAP[x][y]) {
  203.           case 1:
  204.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, WALL_1);
  205.             break;
  206.           case 2:
  207.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, WALL_2);
  208.             break;
  209.           case 3:
  210.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, TNT_table[TNTS]);
  211.             break;
  212.           case 4:
  213.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, BOOM_1);
  214.             break;
  215.           case 5:
  216.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, BOOM_2);
  217.             break;
  218.           case 6:
  219.             gb.display.drawBitmap(x * 8 - (PX - 15) * 8 - 64 + CSX, y * 8 - (PY - 7) * 8 - 32 + CSY, BOOM_3);
  220.             break;
  221.         }
  222.       }
  223.     }
  224.   }
  225.   TNTS++;
  226.   if (TNTS >= 2) TNTS = 0;
  227. }
  228. /*====================================================================
  229.                              渲染实体
  230.   ====================================================================*/
  231. void DrawEntity() {
  232.   gb.display.setColor(WHITE);
  233.   if (LIFE > 0) {
  234.     //渲染怪物
  235.     for (byte n = 0; n < 10; n++) {
  236.       if (MLRUD[n] != 255) gb.display.drawBitmap(monster[n][0] * 8 - (PX - 15) * 8 - 64 + CSX, monster[n][1] * 8  - (PY - 7) * 8 - 32 + CSY, M_table[byte(MLRUD[n])]);
  237.     }
  238.     //渲染玩家
  239.     if (millis() >= PIT + Invincible_Time) {
  240.       gb.display.drawBitmap(56, 24, Man_table[PP * 3 + PS] ); //玩家图像为方向*3+动画帧
  241.     } else if (PS == 0) gb.display.drawBitmap(56, 24, Man_table[PP * 3 + PS]); //无敌模式的时候闪烁效果
  242.     if (PMove == true || millis() < PIT + Invincible_Time) { //只有在玩家移动的时候或者无敌模式 才会有移动动画
  243.       PS++;
  244.       if (PS > 2) PS = 0;
  245.     } else PS = 0;
  246.   }
  247. }
  248.  
  249. /*====================================================================
  250.                               障碍物判断
  251.   ====================================================================*/
  252. void SBDP(byte SBP, byte sx, byte sy) {
  253.   BMove = true;
  254.   char SX, SY;
  255.   switch (SBP) {
  256.     case 3:
  257.       SX = -1;
  258.       SY = 0;
  259.       break;
  260.     case 1:
  261.       SX = +1;
  262.       SY = 0;
  263.       break;
  264.     case 0:
  265.       SX = 0;
  266.       SY = -1;
  267.       break;
  268.     case 2:
  269.       SX = 0;
  270.       SY = +1;
  271.       break;
  272.   }
  273.   byte length = sizeof(SBDPL) / sizeof(SBDPL[0]);
  274.   for (byte i = 0; i < length; i++) {
  275.     if (MAP[sx + SX][sy + SY] == SBDPL[i]) BMove = false;
  276.  
  277.   }
  278. }
  279.  
  280. /*=========================================================
  281.   逻辑
  282.   =========================================================*/
  283. void logic() {
  284.   /*
  285.      怪物AI
  286.   */
  287.   if (LIFE > 0) {
  288.     if (millis() >= MMTime + MMTimeOut) {
  289.  
  290.       MMTime = millis();
  291.       for (byte n = 0; n < 10; n++) {
  292.         if (MLRUD[n] != 255) {
  293.  
  294.           SBDP(MLRUD[n], monster[n][0], monster[n][1]); //通过怪物方向 坐标调用障碍物判断函数
  295.           if (BMove == true) {
  296.             //移动合法
  297.             switch (MLRUD[n]) {
  298.               case 0:
  299.                 monster[n][1]--;
  300.                 break;
  301.               case 1:
  302.                 monster[n][0]++;
  303.                 break;
  304.               case 2:
  305.                 monster[n][1]++;
  306.                 break;
  307.               case 3:
  308.                 monster[n][0]--;
  309.                 break;
  310.             }
  311.           } else MLRUD[n] = random(0, 4);
  312.         }
  313.       }
  314.     }
  315.   }
  316.   /*
  317.      判断是否通关
  318.   */
  319.   PWIN = true;
  320.   for (byte n = 0; n < 10; n++) {
  321.     if (MLRUD[n] != 255) PWIN = false;
  322.   }
  323.   if (PWIN == true) WIN();
  324.   /*
  325.      遍历地图 刷新数据
  326.   */
  327.   for (byte y = 0; y < 15; y++) {
  328.     for (byte x = 0; x < 31; x++) {
  329.       if (MAP[x][y] == 4) MAP[x][y] = 5; else if (MAP[x][y] == 5) MAP[x][y] = 6; else if (MAP[x][y] == 6) MAP[x][y] = 0; //让爆炸切换下一帧
  330.     }
  331.   }
  332.   if (LIFE > 0) {
  333.     for (byte i = 0; i < 10; i++) {
  334.       if (MAP[monster[i][0]][monster[i][1]] >= 4 && MLRUD[i] != 255) { //怪物脚下是爆炸并且怪物不能为死的状态
  335.         //怪物脚下是爆炸
  336.         MLRUD[i] = 255; //设置怪物已经死亡
  337.       }
  338.       if (millis() >= PIT + Invincible_Time) { //玩家不在无敌状态
  339.         if (PX == monster[i][0] && PY == monster[i][1] || MAP[PX][PY] >= 4) { //怪物伤害 或者 TNT伤害
  340.           LIFE--;
  341.           PIT = millis();
  342.         }
  343.       }
  344.     }
  345.     /*
  346.       控制移动 以及移动相关动画
  347.     */
  348.     if (gb.buttons.pressed(BUTTON_UP)) {
  349.       PP = 0;
  350.       SBDP(PP, PX, PY);
  351.       if (PY > 1 && BMove == true) {
  352.         PMove = true;
  353.         for (CSY = 1; CSY <= 7; CSY += 3) Draw();
  354.         PY--;
  355.       }
  356.     }
  357.  
  358.     if (gb.buttons.pressed(BUTTON_DOWN)) {
  359.       PP = 2;
  360.       SBDP(PP, PX, PY);
  361.       if (PY < 13 && BMove == true) {
  362.         PMove = true;
  363.         for (CSY = -1; CSY >= -7; CSY -= 3) Draw();
  364.         PY++;
  365.       }
  366.     }
  367.  
  368.     if (gb.buttons.pressed(BUTTON_LEFT)) {
  369.       PP = 3;
  370.       SBDP(PP, PX, PY);
  371.       if (PX > 1 && BMove == true) {
  372.         PMove = true;
  373.         for (CSX = 1; CSX <= 7; CSX += 3) Draw();
  374.         PX--;
  375.       }
  376.     }
  377.  
  378.     if (gb.buttons.pressed(BUTTON_RIGHT)) {
  379.       PP = 1;
  380.       SBDP(PP, PX, PY);
  381.       if (PX < 29 && BMove == true) {
  382.         PMove = true;
  383.         for (CSX = -1; CSX >= -7; CSX -= 3) Draw();
  384.         PX++;
  385.       }
  386.     }
  387.  
  388.     if (gb.buttons.pressed(BUTTON_A)) {
  389.       //放TNT
  390.       if (TNTN < 10 && MAP[PX][PY] != 3) {
  391.         //注意0为没有TNT 范围1-10
  392.         TNTN++;
  393.         TntList[TNTN - 1][0] = PX;
  394.         TntList[TNTN - 1][1] = PY;
  395.         MAP[PX][PY] = 3;
  396.         TntTime[TNTN - 1] = millis();
  397.       }
  398.     }
  399.  
  400.  
  401.     if (PMove == true) {
  402.       CSX = 0;
  403.       CSY = 0;
  404.       PMove = false;
  405.     }
  406.     /*
  407.        计算TNT爆炸
  408.     */
  409.     if (TNTN != 0) {
  410.       //存在炸弹
  411.       if (millis() >= TntTime[0] + BOOMTime) {  //检查最近一个TNT是否到起爆时间
  412.         MAP[TntList[0][0]][TntList[0][1]] = 4; //引爆
  413.         //摧毁附近的非坚固实体或者方块
  414.         for (byte BOOMx = 0; BOOMx < 3; BOOMx++) {
  415.           if (MAP[TntList[0][0] - 1 + BOOMx][TntList[0][1]] != 1 && MAP[TntList[0][0] - 1 + BOOMx][TntList[0][1]] != 3) {
  416.             MAP[TntList[0][0] - 1 + BOOMx][TntList[0][1]] = 4;
  417.           }
  418.         }
  419.         for (byte BOOMy = 0; BOOMy < 3; BOOMy++) {
  420.           if (MAP[TntList[0][0]][TntList[0][1] - 1 + BOOMy] != 1 && MAP[TntList[0][0] - 1 + BOOMy][TntList[0][1]] != 3) {
  421.             MAP[TntList[0][0]][TntList[0][1] - 1 + BOOMy] = 4;
  422.           }
  423.         }
  424.         //让TNT列表向前移位
  425.         TNTN--; //减少一枚TNT
  426.         for (byte TNTi = 0; TNTi < TNTN; TNTi++) {
  427.           TntList[TNTi][0] = TntList[TNTi + 1][0];
  428.           TntList[TNTi][1] = TntList[TNTi + 1][1];
  429.           TntTime[TNTi] = TntTime[TNTi + 1];
  430.         }
  431.  
  432.       }
  433.     }
  434.   }
  435. }
  436. /*=========================================================
  437.                      通关
  438.   =========================================================*/
  439. void WIN() {
  440.   if (LEVEL == 10) {
  441.     gb.display.clear();
  442.     gb.display.setCursor(16, 0);
  443.     gb.display.println("CONGRATULATIONS");
  444.     gb.display.println(" BOMBER MAN BECOMES");
  445.     gb.display.println("       RUNNER");
  446.     gb.display.println("SEE YOU AGAIN IN LODE");
  447.     gb.display.println("       RUNNER");
  448.     gb.display.setColor(BLACK);
  449.     gb.display.drawBitmap(56, 48, Man_table[3]);
  450.     gb.display.fillRect(0, 56, 128, 8);
  451.     gb.display.setColor(WHITE);
  452.     for (byte x = 0; x < 128; x += 8) {
  453.       gb.display.drawBitmap(x, 56, WALL_2);
  454.     }
  455.     while (1) {}
  456.   } else {
  457.     LEVEL++;   //关卡+1
  458.     ShowLevel(); //显示第几关
  459.     BuildMap();  //构建地图
  460.   }
  461. }
  462. /*=========================================================
  463.                      显示关卡
  464.   =========================================================*/
  465. void ShowLevel() {
  466.   gb.display.clear();
  467.   gb.display.setCursor(52, 16);
  468.   gb.display.println("LEVEL");
  469.   gb.display.setCursor(64, 32);
  470.   gb.display.println(LEVEL);
  471.   delay(1000);
  472. }
  473. /*=========================================================
  474.                      玩家死亡
  475.   =========================================================*/
  476. void FAIL() {
  477.   for (byte y = 0; y < 15; y++) {
  478.     for (byte x = 0; x < 31; x++) {
  479.       MAP[x][y] = 4;
  480.     }
  481.   }
  482.   while (MAP[0][0] >= 3) {
  483.     Draw();
  484.     logic();
  485.     delay(500);
  486.   }
  487.   Draw();
  488.   gb.display.setColor(WHITE);
  489.   gb.display.drawBitmap(56, 24, Man_table[3]);
  490.   delay(5000);
  491.   resetFunc(); //重启游戏
  492. }
  493. /*=========================================================
  494.                      Menu de démrrage
  495.   =========================================================*/
  496. void MENU() {
  497.   gb.display.clear();
  498.   gb.display.setCursor(0, 0);
  499.   gb.display.println(" >About");
  500.   gb.display.println("");
  501.   gb.display.println("LHW programming");
  502.   gb.display.println("LHW Art");
  503.   gb.display.println("E-mail");
  504.   gb.display.println("1281702594@qq.com");
  505.   delay(2000);
  506.   gb.display.clear();
  507.   gb.display.setColor(BLACK);
  508.   gb.display.drawBitmap(39, 1, START_TITLE);  //大标题
  509.   gb.display.drawBitmap(0, 23, TITLE_TNT);    //TNT图标
  510.   gb.display.drawBitmap(65, 58, LHW);          //作者信息
  511.   gb.display.setCursor(70, 39);
  512.   gb.display.println("PLAY");
  513.   gb.display.setCursor(70, 47);
  514.   gb.display.println("ABOUT");
  515.   if (gb.buttons.pressed(BUTTON_B)) gb.display.setCursor(62, 39); else gb.display.setCursor(62, 47);
  516.   gb.display.println("*");
  517. }
RAW Paste Data