找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7515|回复: 10
打印 上一主题 下一主题
收起左侧

坦克大战游戏的C++语言程序实现

  [复制链接]
跳转到指定楼层
楼主
ID:367557 发表于 2018-7-8 22:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、游戏内容及特点描述
游戏内容:玩家自己控制一辆黄色的坦克,而敌方坦克为白色,一秒发射一颗炮弹,玩家通过键盘的方向键来控制黄色坦克的前进方向,空格键来控制发射炮弹,当炮弹与白色的敌方坦克相撞时,白色坦克与炮弹一起消失,玩家积十分,当所有白色坦克被消灭时,玩家进入下一关,当白色坦克发射的炮弹与玩家控制的黄色坦克累积相撞三次时,黄色坦克与炮弹一起消失,游戏结束,玩家获得最终分数。
特点描述:1*玩家可自主控制坦克进行游戏,规避敌人子弹。
         2*白色的敌方坦克方向随机变动。
         3*玩家压Q键时可以向四面发射密集的炮弹。
         4*游戏实行关卡制,当所有白色坦克都被消灭时,游戏进入下一关。
         5*玩家有三次被地方坦克击中而不结束游戏的机会。
         6*游戏采用分数积分制,使游戏更富有挑战性。

C++语言源程序如下:
  1. Bomb.cpp
  2. #include "Bomb.h"

  3. Bomb::Bomb()
  4. {
  5.         this->m_bDisappear = false;
  6.         this->m_color = YELLOW;
  7.         this->m_dir = UP;
  8. }

  9. Bomb::Bomb(Point pos, BombType type) : Bomb()
  10. {
  11.         this->m_pos = pos;
  12.         this->m_type = type;

  13.         switch (m_type)
  14.         {
  15.         case LARGE:
  16.                 m_timer = 8;
  17.                 break;
  18.         case SMALL:
  19.                 m_timer = 4;
  20.                 break;
  21.         default:
  22.                 break;
  23.         }
  24. }
  25. Bomb.h
  26. void Bomb::Display()
  27. {
  28.         COLORREF fill_color_save = getfillcolor();
  29.         COLORREF color_save = getcolor();

  30.         setfillcolor(m_color);
  31.         setcolor(RED);

  32.         fillcircle(m_pos.GetX(), m_pos.GetY(), 8 - m_timer);

  33.         setcolor(color_save);
  34.         setfillcolor(fill_color_save);
  35. }

  36. void Bomb::Move()
  37. {
  38.         m_timer -= 2;

  39.         if (m_timer < 0)
  40.         {
  41.                 m_bDisappear = true;
  42.         }

  43. }

  44. bool Bomb::IsDisappear()
  45. {
  46.         return m_bDisappear;
  47. }

  48. void Bomb::Boom(list<Object*>& lstBombs)
  49. {
  50.         // Do nothing
  51. }

  52. void Bomb::CalculateSphere()
  53. {
  54.         // Do nothing
  55. }

  56. #ifndef __BOMB_H__
  57. #define __BOMB_H__

  58. #include "Object.h"

  59. enum BombType
  60. {
  61.         LARGE,
  62.         SMALL
  63. };

  64. class Bomb : public Object
  65. {
  66. public:
  67.         Bomb();
  68.         Bomb(Point pos, BombType type);
  69.         ~Bomb(){}

  70.         void Display();

  71.         void Move();

  72.         void Boom(list<Object*>& lstBombs);
  73.         
  74.         bool IsDisappear();
  75.         void SetDisappear(){}

  76.         Rect GetSphere()
  77.         {
  78.                 return m_rectSphere;
  79.         }

  80. protected:
  81.         void CalculateSphere();
  82.         
  83.         BombType m_type;
  84.         int m_timer;
  85. };

  86. #endif
  87. Bullet.cpp
  88. #include "Bullet.h"

  89. #include "Bomb.h"

  90. Bullet::Bullet()
  91. {
  92. }

  93. Bullet::Bullet(Point pos, Dir dir, COLORREF color)
  94. {
  95.         m_pos = pos;
  96.         m_dir = dir;
  97.         m_color = color;

  98.         m_step = 6;

  99.         m_bDisappear = false;

  100.         CalculateSphere();
  101. }

  102. Bullet::~Bullet()
  103. {

  104. }


  105. // 绘图
  106. void Bullet::Display()
  107. {
  108.         COLORREF fill_color_save = getfillcolor();
  109.         COLORREF color_save = getcolor();

  110.         setfillcolor(m_color);
  111.         setcolor(m_color);

  112.         fillcircle(m_pos.GetX(), m_pos.GetY(), 4);
  113.                
  114.         setcolor(color_save);
  115.         setfillcolor(fill_color_save);
  116. }

  117. // 移动
  118. void Bullet::Move()
  119. {
  120.         switch (m_dir)
  121.         {
  122.         case UP:
  123.                 m_pos.SetY(m_pos.GetY() - m_step);
  124.                 CalculateSphere();
  125.                 if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
  126.                 {
  127.                         m_pos.SetY(Graphic::GetBattleGround().GetStartPoint().GetY());
  128.                         m_bDisappear = true;
  129.                 }
  130.                 break;
  131.         case DOWN:
  132.                 m_pos.SetY(m_pos.GetY() + m_step);
  133.                 CalculateSphere();
  134.                 if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
  135.                 {
  136.                         m_pos.SetY(Graphic::GetBattleGround().GetEndPoint().GetY());
  137.                         m_bDisappear = true;
  138.                 }
  139.                 break;
  140.         case LEFT:
  141.                 m_pos.SetX(m_pos.GetX() - m_step);
  142.                 CalculateSphere();
  143.                 if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
  144.                 {
  145.                         m_pos.SetX(Graphic::GetBattleGround().GetStartPoint().GetX());
  146.                         m_bDisappear = true;
  147.                 }
  148.                 break;
  149.         case RIGHT:
  150.                 m_pos.SetX(m_pos.GetX() + m_step);
  151.                 CalculateSphere();
  152.                 if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
  153.                 {
  154.                         m_pos.SetX(Graphic::GetBattleGround().GetEndPoint().GetX());
  155.                         m_bDisappear = true;
  156.                 }
  157.                 break;
  158.         default:
  159.                 break;
  160.         }        
  161. }

  162. void Bullet::Boom(list<Object*>& lstBombs)
  163. {
  164.         lstBombs.push_back(new Bomb(m_pos, SMALL));
  165. }

  166. void Bullet::CalculateSphere()
  167. {
  168.         m_rectSphere.Set(m_pos.GetX() - 2, m_pos.GetY() - 2, m_pos.GetX() + 2, m_pos.GetY() + 2);
  169. }
  170. Bullet.h
  171. #ifndef __BULLET_H__
  172. #define __BULLET_H__

  173. #include "Object.h"

  174. class Bullet : public Object
  175. {
  176. public:
  177.         Bullet();
  178.         Bullet(Point pos, Dir dir, COLORREF color);
  179.         ~Bullet();

  180.         void Display();

  181.         void Move();

  182.         void Boom(list<Object*>& lstBombs);

  183.         bool IsDisappear()
  184.         {
  185.                 return m_bDisappear;
  186.         }

  187.         Rect GetSphere()
  188.         {
  189.                 return m_rectSphere;
  190.         }

  191.         void SetStep(int nStep)
  192.         {
  193.                 m_step = nStep;
  194.         }

  195.         void SetDisappear()
  196.         {
  197.                 m_bDisappear = true;
  198.         }

  199. protected:
  200.         void CalculateSphere();
  201. };

  202. #endif
  203. EnemyTank.cpp
  204. #include "EnemyTank.h"

  205. #include "Bullet.h"

  206. void EnemyTank::RandomTank()
  207. {
  208.         m_pos.SetX(rand() % (Graphic::GetBattleGround().GetWidth() - 30) + 15);
  209.         m_pos.SetY(rand() % (Graphic::GetBattleGround().GetHeight() - 30) + 15);
  210.         m_color = WHITE;
  211.         m_dir = (Dir)(Dir::UP + (rand() % 4));
  212.         m_step = 1;
  213.         m_stepCnt = rand();
  214. }

  215. void EnemyTank::RandomDir(int type)
  216. {
  217.         if (type == 1)
  218.         {
  219.                 Dir dir;
  220.                 while ((dir = (Dir)(Dir::UP + (rand() % 4))) == m_dir)
  221.                 {
  222.                         // Do nothing
  223.                 }

  224.                 m_dir = dir;
  225.         }
  226.         else
  227.         {
  228.                 m_dir = (Dir)(Dir::UP + (rand() % 4));
  229.         }
  230. }

  231. void EnemyTank::Display()
  232. {
  233.         COLORREF fill_color_save = getfillcolor();
  234.         COLORREF color_save = getcolor();

  235.         setfillcolor(m_color);
  236.         setcolor(m_color);
  237.         
  238.         fillrectangle(m_pos.GetX() - 6, m_pos.GetY() - 6, m_pos.GetX() + 6, m_pos.GetY() + 6);

  239.         fillrectangle(m_rectSphere.GetStartPoint().GetX(), m_rectSphere.GetStartPoint().GetY(),
  240.                 m_rectSphere.GetStartPoint().GetX() + 4, m_rectSphere.GetStartPoint().GetY() + 4);
  241.         fillrectangle(m_rectSphere.GetEndPoint().GetX() - 4, m_rectSphere.GetStartPoint().GetY(),
  242.                 m_rectSphere.GetEndPoint().GetX(), m_rectSphere.GetStartPoint().GetY() + 4);

  243.         fillrectangle(m_rectSphere.GetStartPoint().GetX(), m_rectSphere.GetEndPoint().GetY() - 4,
  244.                 m_rectSphere.GetStartPoint().GetX() + 4, m_rectSphere.GetEndPoint().GetY());
  245.         fillrectangle(m_rectSphere.GetEndPoint().GetX() - 4, m_rectSphere.GetEndPoint().GetY() - 4,
  246.                 m_rectSphere.GetEndPoint().GetX(), m_rectSphere.GetEndPoint().GetY());
  247.         
  248.         switch (m_dir)
  249.         {
  250.         case UP:
  251.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX(), m_pos.GetY() - 15);
  252.                 break;
  253.         case DOWN:
  254.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX(), m_pos.GetY() + 15);
  255.                 break;
  256.         case LEFT:
  257.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX() - 15, m_pos.GetY());
  258.                 break;
  259.         case RIGHT:
  260.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX() + 15, m_pos.GetY());
  261.                 break;
  262.         default:
  263.                 break;
  264.         }

  265.         setcolor(color_save);
  266.         setfillcolor(fill_color_save);
  267. }

  268. void EnemyTank::Move()
  269. {
  270.         switch (m_dir)
  271.         {
  272.         case UP:
  273.                 m_pos.SetY(m_pos.GetY() - m_step);
  274.                 if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
  275.                 {
  276.                         m_pos.SetY(m_pos.GetY() + m_step);
  277.                         this->RandomDir(1);
  278.                 }
  279.                 break;
  280.         case DOWN:
  281.                 m_pos.SetY(m_pos.GetY() + m_step);
  282.                 if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
  283.                 {
  284.                         m_pos.SetY(m_pos.GetY() - m_step);
  285.                         this->RandomDir(1);
  286.                 }
  287.                 break;
  288.         case LEFT:
  289.                 m_pos.SetX(m_pos.GetX() - m_step);
  290.                 if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
  291.                 {
  292.                         m_pos.SetX(m_pos.GetX() + m_step);
  293.                         this->RandomDir(1);
  294.                 }
  295.                 break;
  296.         case RIGHT:
  297.                 m_pos.SetX(m_pos.GetX() + m_step);
  298.                 if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
  299.                 {
  300.                         m_pos.SetX(m_pos.GetX() - m_step);
  301.                         this->RandomDir(1);
  302.                 }
  303.                 break;
  304.         default:
  305.                 break;
  306.         }

  307.         CalculateSphere();

  308.         m_stepCnt++;
  309.         if (m_stepCnt % MAX_STEP_TURN == 0)
  310.         {
  311.                 //m_stepCnt = 0;
  312.                 this->RandomDir(0);
  313.         }

  314.         if (m_stepCnt % MAX_STEP_SHOOT == 0)
  315.         {
  316.                 m_bNeedShoot = true;
  317.         }
  318. }

  319. void EnemyTank::CalculateSphere()
  320. {
  321.         switch (m_dir)
  322.         {
  323.         case UP:
  324.         case DOWN:
  325.                 m_rectSphere.Set(m_pos.GetX() - 13, m_pos.GetY() - 10, m_pos.GetX() + 13, m_pos.GetY() + 10);
  326.                 break;
  327.         case LEFT:
  328.         case RIGHT:
  329.                 m_rectSphere.Set(m_pos.GetX() - 10, m_pos.GetY() - 13, m_pos.GetX() + 10, m_pos.GetY() + 13);
  330.                 break;
  331.         default:
  332.                 break;
  333.         }
  334. }

  335. void EnemyTank::Shoot(list<Object*>& lstBullets)
  336. {
  337.         Bullet* pBullet = new Bullet(m_pos, m_dir, m_color);

  338.         lstBullets.push_back(pBullet);

  339.         m_bNeedShoot = false;
  340. }
  341. EnemyTank.h
  342. #ifndef __ENEMY_TANK__
  343. #define __ENEMY_TANK__

  344. #include "Tank.h"

  345. #define MAX_STEP_TURN        20
  346. #define MAX_STEP_SHOOT        15

  347. class EnemyTank : public Tank
  348. {
  349. public:
  350.         EnemyTank()
  351.         {
  352.                 RandomTank();
  353.         }

  354.         ~EnemyTank(){}

  355.         void Display();
  356.         void Move();
  357.         void Shoot(list<Object*>& lstBullets);

  358. protected:
  359.         void CalculateSphere();
  360.         void RandomTank();
  361.         // 随机产生坦克方向 type: 1, 新方向必须与之前方向不同 2, 任意一个新方向
  362.         void RandomDir(int type);

  363.         int m_stepCnt;
  364. };

  365. #endif
  366. Graphic.h
  367. #ifndef __GRAPHIC_H__
  368. #define __GRAPHIC_H__

  369. #include <graphics.h>

  370. #include "model/Rect.h"

  371. #define SCREEN_WIDTH        1024
  372. #define SCREEN_HEIGHT        768

  373. #define BATTLE_GROUND_X1 5
  374. #define BATTLE_GROUND_Y1 5
  375. #define BATTLE_GROUND_X2 800
  376. #define BATTLE_GROUND_Y2 (SCREEN_HEIGHT - BATTLE_GROUND_Y1)

  377. class Graphic
  378. {
  379. public:
  380.         static void Create();
  381.         static void Destroy();

  382.         static void DrawBattleGround();

  383.         static int GetScreenWidth();
  384.         static int GetScreenHeight();

  385.         static Rect GetBattleGround();

  386.         static void ShowScore();
  387.         static void ShowGameLevel(int nLevel);

  388.         static void ShowGameOver();

  389. private:
  390.         static Rect m_rectScreen;
  391.         static Rect m_rectBattleGround;

  392.         static char m_pArray[100];
  393. };

  394. #endif
  395. Graphic.cpp
  396. #include "Graphic.h"

  397. #include "Setting.h"

  398. Rect Graphic::m_rectScreen;
  399. Rect Graphic::m_rectBattleGround;
  400. char Graphic::m_pArray[100];

  401. void Graphic::Create()
  402. {
  403.         m_rectScreen.Set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
  404.         initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
  405.         setbkcolor(DARKGRAY);

  406.         m_rectBattleGround.Set(BATTLE_GROUND_X1, BATTLE_GROUND_Y1, BATTLE_GROUND_X2, BATTLE_GROUND_Y2);
  407. }

  408. void Graphic::Destroy()
  409. {
  410.         closegraph();
  411. }

  412. void Graphic::DrawBattleGround()
  413. {
  414.         rectangle(m_rectBattleGround.GetStartPoint().GetX(), m_rectBattleGround.GetStartPoint().GetY(),
  415.                 m_rectBattleGround.GetEndPoint().GetX(), m_rectBattleGround.GetEndPoint().GetY());
  416. }

  417. int Graphic::GetScreenWidth()
  418. {
  419.         return SCREEN_WIDTH;
  420. }

  421. int Graphic::GetScreenHeight()
  422. {
  423.         return SCREEN_HEIGHT;
  424. }

  425. Rect Graphic::GetBattleGround()
  426. {
  427.         return m_rectBattleGround;
  428. }

  429. const int SCORE_LEFT = 810;
  430. const int SCORE_TOP = 5;

  431. void Graphic::ShowScore()
  432. {
  433.         COLORREF fill_color_save = getfillcolor();
  434.         COLORREF color_save = getcolor();

  435.         rectangle(SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40);


  436.         RECT r = { SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40 };
  437.         wsprintf((LPWSTR)m_pArray, _T("第 %d 关"), Setting::GetGameLevel());
  438.         drawtext((LPWSTR)m_pArray, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

  439.         r.top += 50;
  440.         r.bottom += 50;
  441.         wsprintf((LPWSTR)m_pArray, _T("分  数  :  %d"), Setting::GetSumScore());
  442.         drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);

  443.         r.top += 50;
  444.         r.bottom += 50;
  445.         wsprintf((LPWSTR)m_pArray, _T("级  别  :  %d"), Setting::GetTankLevel());
  446.         drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);

  447.         r.top += 50;
  448.         r.bottom += 50;
  449.         wsprintf((LPWSTR)m_pArray, _T("生  命  :  %d"), Setting::GetLife());
  450.         drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);

  451.         r.top += 50;
  452.         r.bottom += 50;
  453.         wsprintf((LPWSTR)m_pArray, _T("敌人数  :  %d"), Setting::GetTankNum());
  454.         drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);

  455.         r.top += 50;
  456.         r.bottom += 50;

  457.         line(SCORE_LEFT, r.bottom, SCREEN_WIDTH - 5, r.bottom);

  458.         r.top += 50;
  459.         r.bottom += 50;
  460.         wsprintf((LPWSTR)m_pArray, _T("共击毁敌人数  :  %d"), Setting::GetTankSum());
  461.         drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);


  462.         setcolor(color_save);
  463.         setfillcolor(fill_color_save);
  464. }

  465. void Graphic::ShowGameLevel(int nLevel)
  466. {
  467.         COLORREF fill_color_save = getfillcolor();
  468.         COLORREF color_save = getcolor();

  469.         rectangle(BATTLE_GROUND_X1 + 100, BATTLE_GROUND_Y1 + 200, BATTLE_GROUND_X1 + 700, BATTLE_GROUND_Y1 + 380);

  470.         LOGFONT fontBak;
  471.         gettextstyle(&fontBak);               // 获取当前字体设置

  472.         LOGFONT f = fontBak;
  473.         f.lfHeight = 48;                      // 设置字体高度为 48
  474.         _tcscpy_s(f.lfFaceName, _T("黑体"));  // 设置字体为“黑体”
  475.         f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
  476.         settextstyle(&f);                     // 设置字体样式
  477.         wsprintf((LPWSTR)m_pArray, _T("第 %d 关"), nLevel);
  478.         outtextxy(BATTLE_GROUND_X1 + 300, BATTLE_GROUND_Y1 + 250, (LPWSTR)m_pArray);

  479.         f.lfHeight = 18;
  480.         settextstyle(&f);
  481.         wsprintf((LPWSTR)m_pArray, _T("按 Enter 键开始"), nLevel);
  482.         outtextxy(BATTLE_GROUND_X1 + 550, BATTLE_GROUND_Y1 + 350, (LPWSTR)m_pArray);

  483.         settextstyle(&fontBak);

  484.         setcolor(color_save);
  485.         setfillcolor(fill_color_save);
  486. }

  487. void Graphic::ShowGameOver()
  488. {
  489.         COLORREF fill_color_save = getfillcolor();
  490.         COLORREF color_save = getcolor();

  491.         rectangle(BATTLE_GROUND_X1 + 100, BATTLE_GROUND_Y1 + 200, BATTLE_GROUND_X1 + 700, BATTLE_GROUND_Y1 + 380);

  492.         LOGFONT fontBak;
  493.         gettextstyle(&fontBak);               // 获取当前字体设置

  494.         LOGFONT f = fontBak;
  495.         f.lfHeight = 48;                      // 设置字体高度为 48
  496.         _tcscpy_s(f.lfFaceName, _T("黑体"));  // 设置字体为“黑体”
  497.         f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
  498.         settextstyle(&f);                     // 设置字体样式
  499.         wsprintf((LPWSTR)m_pArray, _T("GAME OVER"));
  500.         outtextxy(BATTLE_GROUND_X1 + 300, BATTLE_GROUND_Y1 + 250, (LPWSTR)m_pArray);

  501.         f.lfHeight = 18;
  502.         settextstyle(&f);
  503.         wsprintf((LPWSTR)m_pArray, _T("按 Enter 键退出"));
  504.         outtextxy(BATTLE_GROUND_X1 + 550, BATTLE_GROUND_Y1 + 350, (LPWSTR)m_pArray);

  505.         settextstyle(&fontBak);

  506.         setcolor(color_save);
  507.         setfillcolor(fill_color_save);
  508. }
  509. Main.cpp
  510. #pragma warning(disable:4996)

  511. #include <iostream>
  512. #include <conio.h>
  513. #include <time.h>

  514. #include <list>

  515. #include "Graphic.h"
  516. #include "MainTank.h"
  517. #include "EnemyTank.h"
  518. #include "Utils/Shape.h"
  519. #include "Setting.h"

  520. using namespace std;

  521. MainTank mainTank;

  522. // Bullet list
  523. list<Object*> lstMainTankBullets;
  524. list<Object*> lstBullets;

  525. // Bomb List
  526. list<Object*> lstBombs;

  527. // Tank list
  528. list<Tank*> lstTanks;

  529. void CheckCrash()
  530. {
  531.         // Check enermy tank damage
  532.         for (list<Object*>::iterator it = lstMainTankBullets.begin(); it != lstMainTankBullets.end(); it++)
  533.         {
  534.                 for (list<Tank*>::iterator itt = lstTanks.begin(); itt != lstTanks.end(); itt++)
  535.                 {
  536.                         if (Shape::CheckIntersect((*it)->GetSphere(), (*itt)->GetSphere()))
  537.                         {
  538.                                 (*itt)->SetDisappear();
  539.                                 (*it)->SetDisappear();
  540.                         }
  541.                 }
  542.         }

  543.         // Check main tank damage
  544.         for (list<Object*>::iterator it = lstBullets.begin(); it != lstBullets.end(); it++)
  545.         {
  546.                 if (Shape::CheckIntersect((*it)->GetSphere(), mainTank.GetSphere()))
  547.                 {
  548.                         Setting::Die();

  549.                         if (Setting::GetLife() > 0)
  550.                         {
  551.                                 (*it)->SetDisappear();
  552.                         }
  553.                         else
  554.                         {
  555.                                 mainTank.SetDisappear();
  556.                         }                        
  557.                 }
  558.         }
  559. }

  560. void Init()
  561. {
  562.         srand((unsigned)time(NULL));

  563.         Graphic::Create();
  564.         
  565.         lstMainTankBullets.clear();
  566.         lstBullets.clear();
  567.         lstBombs.clear();
  568.         lstTanks.clear();
  569. }

  570. void Dispose()
  571. {
  572.         for (list<Tank*>::iterator it = lstTanks.begin(); it != lstTanks.end(); it++)
  573.         {
  574.                 delete *it;
  575.         }
  576.         lstTanks.clear();

  577.         for (list<Object*>::iterator it = lstMainTankBullets.begin(); it != lstMainTankBullets.end(); it++)
  578.         {
  579.                 delete *it;
  580.         }

  581.         for (list<Object*>::iterator it = lstBullets.begin(); it != lstBullets.end(); it++)
  582.         {
  583.                 delete *it;
  584.         }
  585.         lstBullets.clear();

  586.         for (list<Object*>::iterator it = lstBombs.begin(); it != lstBombs.end(); it++)
  587.         {
  588.                 delete *it;
  589.         }
  590.         lstBombs.clear();

  591.         Graphic::Destroy();
  592. }

  593. void main()
  594. {
  595.         Init();

  596.         bool loop = true;
  597.         bool skip = false;
  598.         bool bGameOver = false;
  599.         while (loop)
  600.         {
  601.                 if (kbhit())
  602.                 {
  603.                          int key = getch();
  604.                         if (skip && key != 13)
  605.                         {
  606.                                 continue;
  607.                         }

  608.                         Dir dirBak;
  609.                         switch (key)
  610.                         {
  611.                         // Up
  612.                         case 72:
  613.                                 mainTank.SetDir(Dir::UP);
  614.                                 break;
  615.                         // Down
  616.                         case 80:
  617.                                 mainTank.SetDir(Dir::DOWN);
  618.                                 break;
  619.                         // Left
  620.                         case 75:
  621.                                 mainTank.SetDir(Dir::LEFT);
  622.                                 break;
  623.                         // Right
  624.                         case 77:
  625.                                 mainTank.SetDir(Dir::RIGHT);
  626.                                 break;
  627.                         case 224: // 方向键高8位
  628.                                 break;
  629.                         // Esc
  630.                         case 27:
  631.                                 loop = false;
  632.                                 break;
  633.                         // Space
  634.                         case 32:
  635.                                 mainTank.Shoot(lstMainTankBullets);
  636.                                 break;
  637.                         // Q
  638.                         case 113:
  639.                                 dirBak = mainTank.GetDir();
  640.                                 mainTank.SetDir(Dir::UP);
  641.                                 mainTank.Shoot(lstMainTankBullets);
  642.                                 mainTank.SetDir(Dir::DOWN);
  643.                                 mainTank.Shoot(lstMainTankBullets);
  644.                                 mainTank.SetDir(Dir::LEFT);
  645.                                 mainTank.Shoot(lstMainTankBullets);
  646.                                 mainTank.SetDir(Dir::RIGHT);
  647.                                 mainTank.Shoot(lstMainTankBullets);
  648.                                 mainTank.SetDir(dirBak);
  649.                                 break;
  650.                         // Enter
  651.                         case 13:
  652.                                 if (skip)
  653.                                         skip = false;
  654.                                 else
  655.                                         skip = true;
  656.                                 break;
  657.                         default:
  658.                                 break;
  659.                         }
  660.                 }
  661.                
  662.                 if (!skip)
  663.                 {
  664.                         if (bGameOver)
  665.                         {
  666.                                 break;
  667.                         }

  668.                         // Draw Background
  669.                         cleardevice();
  670.                         Graphic::DrawBattleGround();
  671.                         
  672.                         CheckCrash();

  673.                         Graphic::ShowScore();

  674.                         // New Game Level
  675.                         if (Setting::m_bNewLevel)
  676.                         {
  677.                                 Setting::m_bNewLevel = false;

  678.                                 Setting::NewGameLevel();

  679.                                 Graphic::ShowGameLevel(Setting::GetGameLevel());

  680.                                 for (int i = 0; i < Setting::GetTankNum(); i++)
  681.                                 {
  682.                                         EnemyTank* p = new EnemyTank();
  683.                                         lstTanks.push_back(p);
  684.                                 }

  685.                                 // 设置暂停,按Enter开始
  686.                                 skip = true;
  687.                                 continue;
  688.                         }
  689.                                        
  690.                         if (mainTank.IsDisappear())
  691.                         {
  692.                                 skip = true;
  693.                                 bGameOver = true;

  694.                                 Graphic::ShowGameOver();

  695.                                 continue;
  696.                         }

  697.                         mainTank.Move();
  698.                         mainTank.Display();

  699.                         /* Draw Tanks */
  700.                         for (list<Tank*>::iterator it = lstTanks.begin(); it != lstTanks.end();)
  701.                         {
  702.                                 (*it)->Move();

  703.                                 if ((*it)->IsDisappear())
  704.                                 {
  705.                                         Setting::TankDamaged();

  706.                                         // Add a bomb
  707.                                         (*it)->Boom(lstBombs);

  708.                                         // Delete the tank
  709.                                         delete *it;
  710.                                         it = lstTanks.erase(it);
  711.                                         continue;
  712.                                 }

  713.                                 (*it)->Display();

  714.                                 if ((*it)->NeedShoot())
  715.                                 {
  716.                                         EnemyTank* p = (EnemyTank*)*it;
  717.                                         p->Shoot(lstBullets);
  718.                                 }
  719.                                 it++;
  720.                         }

  721.                         /* Draw Bullets */
  722.                         for (list<Object*>::iterator it = lstMainTankBullets.begin(); it != lstMainTankBullets.end();)
  723.                         {
  724.                                 (*it)->Move();

  725.                                 if ((*it)->IsDisappear())
  726.                                 {
  727.                                         // Add a bomb
  728.                                         (*it)->Boom(lstBombs);

  729.                                         // Delete the bullet
  730.                                         delete *it;
  731.                                         it = lstMainTankBullets.erase(it);
  732.                                         continue;
  733.                                 }

  734.                                 (*it)->Display();
  735.                                 it++;
  736.                         }

  737.                         for (list<Object*>::iterator it = lstBullets.begin(); it != lstBullets.end();)
  738.                         {
  739.                                 (*it)->Move();
  740.                         
  741.                                 if ((*it)->IsDisappear())
  742.                                 {
  743.                                         // Add a bomb
  744.                                         (*it)->Boom(lstBombs);

  745.                                         // Delete the bullet
  746.                                         delete *it;
  747.                                         it = lstBullets.erase(it);
  748.                                         continue;
  749.                                 }

  750.                                 (*it)->Display();
  751.                                 it++;
  752.                         }

  753.                         /* Draw Bombs */
  754.                         for (list<Object*>::iterator it = lstBombs.begin(); it != lstBombs.end();)
  755.                         {
  756.                                 (*it)->Move();

  757.                                 if ((*it)->IsDisappear())
  758.                                 {
  759.                                         delete *it;
  760.                                         it = lstBombs.erase(it);
  761.                                         continue;
  762.                                 }
  763.                                 
  764.                                 (*it)->Display();
  765.                                 it++;
  766.                         }
  767.                 }

  768.                 Sleep(100);
  769.         }
  770.         
  771.         // Destroy
  772.         Dispose();
  773. }
  774. MainTank.h
  775. #ifndef __MAIN_TANK__
  776. #define __MAIN_TANK__

  777. #include "Tank.h"

  778. class MainTank : public Tank
  779. {
  780. public:
  781.         MainTank() : Tank()
  782.         {
  783.                 m_pos.Set(300, 300);

  784.                 this->CalculateSphere();

  785.                 m_color = YELLOW;
  786.                 m_dir = Dir::UP;
  787.                 m_step = 4;
  788.         }

  789.         ~MainTank(){}

  790.         void SetDir(Dir dir);
  791.         Dir GetDir()
  792.         {
  793.                 return m_dir;
  794.         }
  795.         void Display();
  796.         void Move();
  797.         void Shoot(list<Object*>& lstBullets);
  798.         void Boom(list<Object*>& lstBombs);

  799. protected:
  800.         void CalculateSphere();

  801.         // 绘制坦克主体
  802.         void DrawTankBody();
  803. };

  804. #endif
  805. MainTank.cpp
  806. #include "MainTank.h"

  807. #include "Bullet.h"

  808. void MainTank::SetDir(Dir dir)
  809. {
  810.         m_dir = dir;
  811. }

  812. void MainTank::DrawTankBody()
  813. {
  814.         fillrectangle(m_pos.GetX() - 6, m_pos.GetY() - 6, m_pos.GetX() + 6, m_pos.GetY() + 6);

  815.         switch (m_dir)
  816.         {
  817.         case UP:
  818.         case DOWN:
  819.                 fillrectangle(m_rectSphere.GetStartPoint().GetX(), m_rectSphere.GetStartPoint().GetY(),
  820.                         m_rectSphere.GetStartPoint().GetX() + 4, m_rectSphere.GetEndPoint().GetY());
  821.                 fillrectangle(m_rectSphere.GetEndPoint().GetX() - 4, m_rectSphere.GetStartPoint().GetY(),
  822.                         m_rectSphere.GetEndPoint().GetX(), m_rectSphere.GetEndPoint().GetY());
  823.                 break;
  824.         case LEFT:
  825.         case RIGHT:
  826.                 fillrectangle(m_rectSphere.GetStartPoint().GetX(), m_rectSphere.GetStartPoint().GetY(),
  827.                         m_rectSphere.GetEndPoint().GetX(), m_rectSphere.GetStartPoint().GetY() + 4);
  828.                 fillrectangle(m_rectSphere.GetStartPoint().GetX(), m_rectSphere.GetEndPoint().GetY() - 4,
  829.                         m_rectSphere.GetEndPoint().GetX(), m_rectSphere.GetEndPoint().GetY());
  830.                 break;
  831.         default:
  832.                 break;
  833.         }
  834. }

  835. void MainTank::Display()
  836. {
  837.         COLORREF fill_color_save = getfillcolor();
  838.         COLORREF color_save = getcolor();

  839.         setfillcolor(m_color);
  840.         setcolor(m_color);

  841.         DrawTankBody();

  842.         switch (m_dir)
  843.         {
  844.         case UP:
  845.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX(), m_pos.GetY() - 15);
  846.                 break;
  847.         case DOWN:
  848.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX(), m_pos.GetY() + 15);
  849.                 break;
  850.         case LEFT:
  851.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX() - 15, m_pos.GetY());
  852.                 break;
  853.         case RIGHT:
  854.                 line(m_pos.GetX(), m_pos.GetY(), m_pos.GetX() + 15, m_pos.GetY());
  855.                 break;
  856.         default:
  857.                 break;
  858.         }

  859.         setcolor(color_save);
  860.         setfillcolor(fill_color_save);
  861. }

  862. void MainTank::Move()
  863. {
  864.         switch (m_dir)
  865.         {
  866.         case UP:
  867.                 m_pos.SetY(m_pos.GetY() - m_step);
  868.                 if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
  869.                         m_pos.SetY(m_pos.GetY() + m_step);
  870.                 break;
  871.         case DOWN:
  872.                 m_pos.SetY(m_pos.GetY() + m_step);
  873.                 if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
  874.                         m_pos.SetY(m_pos.GetY() - m_step);
  875.                 break;
  876.         case LEFT:
  877.                 m_pos.SetX(m_pos.GetX() - m_step);
  878.                 if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
  879.                         m_pos.SetX(m_pos.GetX() + m_step);
  880.                 break;
  881.         case RIGHT:
  882.                 m_pos.SetX(m_pos.GetX() + m_step);
  883.                 if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
  884.                         m_pos.SetX(m_pos.GetX() - m_step);
  885.                 break;
  886.         default:
  887.                 break;
  888.         }

  889.         CalculateSphere();
  890. }

  891. void MainTank::CalculateSphere()
  892. {
  893.         switch (m_dir)
  894.         {
  895.         case UP:
  896.         case DOWN:
  897.                 m_rectSphere.Set(m_pos.GetX() - 13, m_pos.GetY() - 10, m_pos.GetX() + 13, m_pos.GetY() + 10);
  898.                 break;
  899.         case LEFT:
  900.         case RIGHT:
  901.                 m_rectSphere.Set(m_pos.GetX() - 10, m_pos.GetY() - 13, m_pos.GetX() + 10, m_pos.GetY() + 13);
  902.                 break;
  903.         default:
  904.                 break;
  905.         }
  906. }

  907. void MainTank::Shoot(list<Object*>& lstBullets)
  908. {
  909.         Bullet* pBullet = new Bullet(m_pos, m_dir, m_color);
  910.         pBullet->SetStep(20);

  911.         lstBullets.push_back(pBullet);
  912. }

  913. void MainTank::Boom(list<Object*>& lstBombs)
  914. {

  915. }
  916. Object.h
  917. #ifndef __OBJECT_H__
  918. #define __OBJECT_H__

  919. #include <list>

  920. #include "Graphic.h"

  921. using namespace std;

  922. enum Dir { UP, DOWN, LEFT, RIGHT };

  923. class Object
  924. {
  925. public:
  926.         // 绘图
  927.         virtual void Display() = 0;

  928.         // 移动
  929.         virtual void Move() = 0;

  930.         // 爆炸
  931.         virtual void Boom(list<Object*>& lstBombs) = 0;

  932.         // 设置消失
  933.         virtual void SetDisappear() = 0;

  934.         // 判断是否消失
  935.         virtual bool IsDisappear() = 0;

  936.         virtual Rect GetSphere() = 0;

  937. protected:
  938.         // 计算势力范围
  939.         virtual void CalculateSphere() = 0;

  940.         // 位置
  941.         Point m_pos;

  942.         // 势力范围
  943.         Rect m_rectSphere;

  944.         // 颜色
  945.         COLORREF m_color;
  946.         // 方向
  947.         Dir m_dir;
  948.         // 存在状态
  949.         bool m_bDisappear;
  950.         // 单次前进步长
  951.         int m_step;
  952. };

  953. #endif
  954. Point.cpp
  955. #include "Point.h"

  956. void Point::Set(int x, int y)
  957. {
  958.         m_x = x;
  959.         m_y = y;
  960. }

  961. void Point::SetX(int x)
  962. {
  963.         m_x = x;
  964. }

  965. void Point::SetY(int y)
  966. {
  967.         m_y = y;
  968. }

  969. int Point::GetX() const
  970. {
  971.         return m_x;
  972. }

  973. int Point::GetY() const
  974. {
  975.         return m_y;
  976. }
  977. Point.h
  978. #ifndef __POINT_H__
  979. #define __POINT_H__

  980. class Point
  981. {
  982. public:
  983.         Point(int x = 0, int y = 0) : m_x(x), m_y(y){};
  984.         ~Point(){};

  985.         Point& operator=(const Point &p)
  986.         {
  987.                 m_x = p.m_x;
  988.                 m_y = p.m_y;

  989.                 return *this;
  990.         }

  991.         void Set(int x, int y);

  992.         void SetX(int x);
  993.         void SetY(int y);

  994.         int GetX() const;
  995.         int GetY() const;

  996. private:
  997.         int m_x;
  998.         int m_y;
  999. };

  1000. #endif
  1001. Rect.h
  1002. #ifndef __RECTANGLE_H__
  1003. #define __RECTANGLE_H__

  1004. #include "Point.h"

  1005. class Rect
  1006. {
  1007. public:
  1008.         Rect(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) : m_startPoint(x1, y1), m_endPoint(x2, y2){}
  1009.         Rect(const Point p1, const Point p2) : m_startPoint(p1), m_endPoint(p2){}
  1010.         Rect(const Rect& r1) : m_startPoint(r1.GetStartPoint()), m_endPoint(r1.GetEndPoint()){}
  1011.         ~Rect(){};

  1012.         Rect& operator=(const Rect &rect)
  1013.         {
  1014.                 m_startPoint = rect.GetStartPoint();
  1015.                 m_endPoint = rect.GetEndPoint();

  1016.                 return *this;
  1017.         }

  1018.         void Set(const Point pStart, const Point pEnd);
  1019.         void Set(int x1, int y1, int x2, int y2);

  1020.         void SetStartPoint(const Point p);
  1021.         void SetEndPoint(const Point p);

  1022.         Point GetStartPoint() const;
  1023.         Point GetEndPoint() const;

  1024.         Point GetTRPoint() const; // Get Top Right Point
  1025.         Point GetBLPoint() const; // Get Bottom Left Point

  1026.         int GetWidth();
  1027.         int GetHeight();


  1028. private:
  1029.         void Check();

  1030.         Point m_startPoint;
  1031.         Point m_endPoint;
  1032. };

  1033. #endif
  1034. Setting.cpp
  1035. #include "Setting.h"

  1036. bool Setting::m_bNewLevel = true;

  1037. int Setting::m_nLife = 3;

  1038. int Setting::m_nGameLevel = 0;
  1039. int Setting::m_nTankLevel = 1;

  1040. int Setting::m_nTankNum = 5;

  1041. int Setting::m_nSumScore = 0;

  1042. int Setting::m_nTankScore = 5;

  1043. int Setting::m_nTankSum = 0;

  1044. void Setting::NewGameLevel()
  1045. {
  1046.         m_nGameLevel++;

  1047.         m_nTankNum = 10 + 5 * (m_nGameLevel - 1);
  1048.         m_nTankScore += 5;
  1049. }

  1050. void Setting::TankDamaged()
  1051. {
  1052.         m_nTankNum--;
  1053.         m_nSumScore += m_nTankScore;

  1054.         m_nTankLevel = m_nSumScore / 150 + 1;

  1055.         if (m_nSumScore % 500 < m_nTankScore)
  1056.         {
  1057.                 m_nLife++;
  1058.         }

  1059.         m_nTankSum++;

  1060.         if (m_nTankNum == 0)
  1061.         {
  1062.                 m_bNewLevel = true;
  1063.         }
  1064. }
  1065. Setting.h
  1066. #ifndef __SETTING_H__
  1067. #define __SETTING_H__

  1068. #include <list>

  1069. using namespace std;

  1070. class Setting
  1071. {
  1072. public:
  1073.         static void NewGameLevel();
  1074.         static void TankDamaged();

  1075.         static int GetLife()
  1076.         {
  1077.                 return m_nLife;
  1078.         }

  1079.         static void Die()
  1080.         {
  1081.                 m_nLife -= 1;
  1082.         }

  1083.         static int GetGameLevel()
  1084.         {
  1085.                 return m_nGameLevel;
  1086.         }

  1087.         static int GetTankLevel()
  1088.         {
  1089.                 return m_nTankLevel;
  1090.         }

  1091.         static int GetTankNum()
  1092.         {
  1093.                 return m_nTankNum;
  1094.         }

  1095.         static int GetSumScore()
  1096. ……………………

  1097. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
坦克大战.zip (5.63 KB, 下载次数: 77)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:329253 发表于 2018-7-9 15:13 来自手机 | 只看该作者
厉害厉害
回复

使用道具 举报

板凳
ID:345773 发表于 2018-7-10 15:04 | 只看该作者
怎么在vc6++里面运行报错呢
回复

使用道具 举报

地板
ID:380546 发表于 2018-10-30 16:37 | 只看该作者
报错啊怎么。。
回复

使用道具 举报

5#
ID:411024 发表于 2018-11-2 16:10 | 只看该作者
最好做移动端吧!很少看到在PC端玩游戏了!
回复

使用道具 举报

6#
ID:481812 发表于 2019-2-27 21:09 | 只看该作者
74LS161 发表于 2018-7-10 15:04
怎么在vc6++里面运行报错呢

语法错误 你自己找找错误在哪里
回复

使用道具 举报

7#
ID:617948 发表于 2019-9-29 12:28 | 只看该作者
好编程 不错
回复

使用道具 举报

8#
ID:618406 发表于 2019-10-4 15:21 | 只看该作者
不给源文件怎么运行啊
回复

使用道具 举报

9#
ID:623961 发表于 2019-10-14 16:59 | 只看该作者
报错是什么情况
回复

使用道具 举报

10#
ID:762010 发表于 2020-5-26 22:04 | 只看该作者
报错是什么情况
报错是什么情况
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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