C++遊戲編程:《控制檯小遊戲系列》之《彩畫師-Graphics》

 Graphics類是一個繪圖類,用於構造遊戲畫面,其主要有以下幾個功能:   

       1、在指定位置繪製字符串,字符串顏色可以按參數指定

       2、在指定位置繪製空心矩形,矩形邊框顏色可以按參數指定

       3、在指定位置繪製實心矩形,矩形填充顏色可以按參數指定
       4、用指定顏色清除控制檯畫面

      上述描述中提到一個位置的名詞,對於控制檯來說,缺省是一個80*25的字符界面,單位移動的是一個字符長度,所以控制檯中以字符爲單位距離而非像素。可以定義一個Point類,用於封裝控制檯X與Y軸的位置信息與一系列座標運算。下面是這個Point類的源代碼:
Point.h

  1. #ifndef _POINT_H_  
  2. #define _POINT_H_  
  3.   
  4. #include <windows.h>  
  5.   
  6. class Point  
  7. {  
  8. public:  
  9.     Point():m_ix(-1),m_iy(-1){};  
  10.     Point(int ix,int iy):m_ix(ix),m_iy(iy){};  
  11.     friend Point operator-(const Point &ptPoint1,const Point &ptPoint2);  
  12.     friend Point operator+(const Point &ptPoint1,const Point &ptPoint2);  
  13.     friend BOOL operator==(const Point &ptPoint1,const Point &ptPoint2);  
  14.     friend BOOL operator!=(const Point &ptPoint1,const Point &ptPoint2);  
  15.     virtual BOOL Collision(const Point &ptPoint) const;  
  16.     int GetX() const;  
  17.     int GetY() const;  
  18.   
  19. protected:  
  20.     int m_ix;  
  21.     int m_iy;  
  22. };  
  23.   
  24. inline int Point::GetX() const  
  25. {  
  26.     return m_ix;  
  27. }  
  28.   
  29. inline int Point::GetY() const  
  30. {  
  31.     return m_iy;  
  32. }  
  33.   
  34. #endif//_POINT_H_  

Point.cpp

  1. #include "Point.h"  
  2.   
  3. Point operator -(const Point &ptPoint1,const Point &ptPoint2)  
  4. {  
  5.     return Point(ptPoint1.GetX()-ptPoint2.GetX(),ptPoint1.GetY()-ptPoint2.GetY());  
  6. }  
  7.   
  8. Point operator +(const Point &ptPoint1,const Point &ptPoint2)  
  9. {  
  10.     return Point(ptPoint1.GetX()+ptPoint2.GetX(),ptPoint1.GetY()+ptPoint2.GetY());  
  11. }  
  12.   
  13. BOOL operator==(const Point &ptPoint1,const Point &ptPoint2)  
  14. {  
  15.     return (ptPoint1.GetX()==ptPoint2.GetX()&&ptPoint1.GetY()==ptPoint2.GetY());  
  16. }  
  17.   
  18. BOOL operator!=(const Point &ptPoint1,const Point &ptPoint2)  
  19. {  
  20.     return (ptPoint1.GetX()!=ptPoint2.GetX()||ptPoint1.GetY()!=ptPoint2.GetY());  
  21. }  
  22.   
  23. BOOL Point::Collision(const Point &ptPoint) const  
  24. {  
  25.     Point pt=*this-ptPoint;  
  26.     return abs(pt.GetX())<1&&abs(pt.GetY())<1;  
  27. }  

      Point類中Collision()函數功能爲判斷兩個座標是否相交,用於遊戲中的碰撞檢測。
      有了座標類,便可以創建我們的Graphics繪圖類,下面是這個類的源代碼,函數實現都很簡單,就不用多做說明了。
Graphics.h

  1. #ifndef _GRAPHICS_H_  
  2. #define _GRAPHICS_H_  
  3.   
  4. #include <conio.h>  
  5. #include <iostream>  
  6. #include <string>  
  7. #include "Point.h"  
  8.   
  9. using namespace std;  
  10.   
  11. #define MAX_WIDTH  80  //最大繪製區域寬度  
  12. #define MAX_HEIGHT 25  //最大繪製區域高度  
  13.   
  14. /* 
  15.   —前景顏色<<4爲背景色— 
  16.   BLACK      黑色 
  17.   BLUE       藍色 
  18.   GREEN      綠色 
  19.   RED        紅色 
  20.   INTENSITY  亮度 
  21. */  
  22. #define BLACK      0x0000  
  23. #define BLUE       0x0001  
  24. #define GREEN      0x0002  
  25. #define RED        0x0004  
  26. #define INTENSITY  0x0008  
  27.   
  28. class Graphics  
  29. {  
  30. public:  
  31.     Graphics();  
  32.     ~Graphics();  
  33.     void DrawString(string szStr,int ix,int iy,int iColor) const;  
  34.     void DrawString(string szStr,const Point &ptPoint,int iColor) const;  
  35.     void DrawRectangle(int ix1,int iy1,int iwidth,int iheight,int iColor) const;  
  36.     void DrawRectangle(const Point &ptPoint1,const Point &ptPoint2,int iColor) const;  
  37.     void FillRectangle(int ix1,int iy1,int iwidth,int iheight,int iColor) const;   
  38.     void FillRectangle(const Point &ptPoint1,const Point &ptPoint2,int iColor) const;  
  39.     void Clear(int iColor=BLACK) const;  
  40.     HANDLE GetHandle() const;  
  41. protected:  
  42.     void SetDrawPosition(int ix,int iy) const;  
  43.     void SetDrawColor(int iColor,BOOL bForeground=TRUE) const;  
  44.     void CheckDrawSize(int &ix,int &iy) const;  
  45. private:  
  46.     HANDLE m_hConsole;  
  47. };  
  48.   
  49. inline HANDLE Graphics::GetHandle() const  
  50. {  
  51.     return m_hConsole;  
  52. }  
  53.   
  54. inline void Graphics::CheckDrawSize(int &ix,int &iy) const  
  55. {  
  56.     ix=(ix>=MAX_WIDTH)?MAX_WIDTH-1:ix;  
  57.     iy=(iy>=MAX_HEIGHT)?MAX_HEIGHT-1:iy;  
  58. }  
  59.   
  60. #endif//_GRAPHICS_H_  
Graphics.cpp
  1. #include "Graphics.h"  
  2.   
  3. Graphics::Graphics()  
  4. {  
  5.     //獲得當前控制檯句柄  
  6.     m_hConsole=GetStdHandle(STD_OUTPUT_HANDLE);  
  7. }  
  8.   
  9. Graphics::~Graphics()  
  10. {  
  11.     //  
  12. }  
  13.   
  14. /* 
  15.  * 方法: 
  16.  *     DrawString 繪製字符串 
  17.  * 參數: 
  18.  *     szStr      字符串 
  19.  *     ix         繪製座標x 
  20.  *     iy         繪製座標y 
  21.  *     iColor     繪製字符串顏色 
  22.  */  
  23. void Graphics::DrawString(string szStr,int ix,int iy,int iColor) const  
  24. {  
  25.     SetDrawPosition(ix*2,iy);  
  26.     SetDrawColor(iColor);  
  27.     cout<<szStr;  
  28. }  
  29.   
  30. /* 
  31.  * 方法: 
  32.  *     DrawString 繪製字符串 
  33.  * 參數: 
  34.  *     szStr      字符串 
  35.  *     ptPoint    繪製座標 
  36.  *     iColor     繪製字符串顏色 
  37.  */  
  38. void Graphics::DrawString(string szStr,const Point &ptPoint,int iColor) const  
  39. {  
  40.     DrawString(szStr,ptPoint.GetX(),ptPoint.GetY(),iColor);  
  41. }  
  42.   
  43. /* 
  44.  * 方法: 
  45.  *     DrawRectangle 繪製矩形 
  46.  * 參數: 
  47.  *     ix1           矩形左上角座標x 
  48.  *     iy1           矩形左上角座標y 
  49.  *     ix2           矩形右下角座標x 
  50.  *     iy2           矩形右下角座標y 
  51.  *     iColor        矩形邊框顏色 
  52.  */  
  53. void Graphics::DrawRectangle(int ix1,int iy1,int iwidth,int iheight,int iColor) const  
  54. {  
  55.     int ix2,iy2;  
  56.     ix1*=2;  
  57.     iwidth=iwidth>MAX_WIDTH/2?MAX_WIDTH/2:iwidth;  
  58.     iheight=iheight>MAX_HEIGHT?MAX_HEIGHT:iheight;  
  59.     ix2=iwidth*2+ix1;  
  60.     iy2=iheight+iy1;  
  61.   
  62.     SetDrawColor(iColor,FALSE);  
  63.   
  64.     for(int x=ix1;x<ix2;x++)  
  65.     {         
  66.         SetDrawPosition(x,iy1);  
  67.         cout<<" ";  
  68.         SetDrawPosition(x,iy2-1);  
  69.         cout<<" ";  
  70.     }     
  71.   
  72.     for(int y=iy1;y<iy2;y++)  
  73.     {         
  74.         SetDrawPosition(ix1,y);  
  75.         cout<<" "<<" ";  
  76.         SetDrawPosition(ix2-2,y);  
  77.         cout<<" "<<" ";  
  78.     }     
  79.     SetDrawPosition(0,0);  
  80. }  
  81.   
  82. /* 
  83.  * 方法: 
  84.  *     DrawRectangle 繪製矩形 
  85.  * 參數: 
  86.  *     ptPoint1      矩形左上角座標 
  87.  *     ptPoint2      矩形右下角座標 
  88.  *     iColor        矩形邊框顏色 
  89.  */  
  90. void Graphics::DrawRectangle(const Point &ptPoint1,const Point &ptPoint2,int iColor) const  
  91. {  
  92.     Point ptTemp=ptPoint2-ptPoint1;  
  93.     int iwidth=ptTemp.GetX();  
  94.     int iheight=ptTemp.GetY();  
  95.     DrawRectangle(ptPoint1.GetX(),ptPoint1.GetY(),iwidth,iheight,iColor);  
  96. }  
  97.   
  98. /* 
  99.  * 方法: 
  100.  *     FillRectangle 填充矩形 
  101.  * 參數: 
  102.  *     ix1           矩形左上角座標x 
  103.  *     iy1           矩形左上角座標y 
  104.  *     iwidth        矩形寬度 
  105.  *     iheight       矩形高度 
  106.  *     iColor        矩形填充顏色 
  107.  */  
  108. void Graphics::FillRectangle(int ix1,int iy1,int iwidth,int iheight,int iColor) const  
  109. {  
  110.     int ix2,iy2;  
  111.     ix1*=2;  
  112.     iwidth=iwidth>MAX_WIDTH/2?MAX_WIDTH/2:iwidth;  
  113.     iheight=iheight>MAX_HEIGHT?MAX_HEIGHT:iheight;  
  114.     ix2=iwidth*2+ix1;  
  115.     iy2=iheight+iy1;  
  116.     SetDrawColor(iColor,FALSE);  
  117.   
  118.     for(int y=iy1;y<iy2;y++)  
  119.     {  
  120.         for(int x=ix1;x<ix2;x++)  
  121.         {  
  122.             SetDrawPosition(x,y);  
  123.             cout<<" ";  
  124.         }     
  125.     }  
  126.     SetDrawPosition(0,0);  
  127. }  
  128.   
  129. /* 
  130.  * 方法: 
  131.  *     FillRectangle 填充矩形 
  132.  * 參數: 
  133.  *     ptPoint1      矩形左上角座標 
  134.  *     ptPoint2      矩形右下角座標 
  135.  *     iColor        矩形填充顏色 
  136.  */  
  137. void Graphics::FillRectangle(const Point &ptPoint1,const Point &ptPoint2,int iColor) const  
  138. {  
  139.     FillRectangle(ptPoint1.GetX(),ptPoint1.GetY(),ptPoint2.GetX(),ptPoint2.GetY(),iColor);  
  140. }  
  141.   
  142. /* 
  143.  * 方法: 
  144.  *     Clear 清除繪製畫面 
  145.  * 參數: 
  146.  *     iColor清除背景色 
  147.  */  
  148. void Graphics::Clear(int iColor) const  
  149. {  
  150.     FillRectangle(0,0,MAX_WIDTH-1,MAX_HEIGHT-1,iColor);  
  151. }  
  152.   
  153. /* 
  154.  * 方法: 
  155.  *     SetDrawPosition 設置繪製開始座標 
  156.  * 參數: 
  157.  *     ix              座標x 
  158.  *     iy              座標y 
  159.  */  
  160. void Graphics::SetDrawPosition(int ix,int iy) const  
  161. {  
  162.     CheckDrawSize(ix,iy);  
  163.     COORD pos;  
  164.     pos.X=ix;  
  165.     pos.Y=iy;  
  166.     SetConsoleCursorPosition(m_hConsole,pos);         
  167. }  
  168.   
  169. /* 
  170.  * 方法: 
  171.  *     SetDrawColor 設置繪製顏色 
  172.  * 參數: 
  173.  *     iColor       繪製顏色 
  174.  *     bForeground  前景顏色或者背景顏色標誌 
  175.  */  
  176. void Graphics::SetDrawColor(int iColor,BOOL bForeground) const  
  177. {  
  178.     if(bForeground)  
  179.         SetConsoleTextAttribute(m_hConsole,iColor);  
  180.     else  
  181.         SetConsoleTextAttribute(m_hConsole,iColor<<4);  
  182. }  
      可以看到,函數基本實現思路就是先定位控制檯光標位置,並設定文本顏色,再在相應位置輸出相應的字符序列,讀者可以修改代碼中輸出的字符,可以得到不同字符邊框還有字符填充矩形,我這裏輸出一個空字符,得到實邊框或統一顏色的矩形。

      下面可以對這個類進行一個小測試,看看輸出的圖形是否是我們所期望的。

  1. #include "Graphics.h"  
  2.   
  3. void main(){  
  4.     //設置控制檯標題  
  5.     SetConsoleTitle("Graphics類測試");  
  6.     //初始化一個繪圖對象  
  7.     Graphics g;  
  8.     //在位置(2,2)處畫一個寬5高4的深紅色矩形  
  9.     g.DrawRectangle(2,2,5,4,RED);  
  10.     //在位置(8,2)處畫一個寬5高8的藍色矩形  
  11.     g.DrawRectangle(8,2,5,8,BLUE|INTENSITY);  
  12.     //在位置(2,8)處填充一個寬5高8的綠色矩形  
  13.     g.FillRectangle(2,8,5,8,GREEN|INTENSITY);  
  14.     //在位置(10,4)處畫一個寬10高8的白色矩形  
  15.     g.DrawRectangle(10,4,10,8,15);  
  16.     //在位置(2,17)處畫一個字符串  
  17.     g.DrawString("Hello,ConsoleWorld!",2,17,RED);  
  18.     //在位置(3,18)處畫一個字符串  
  19.     g.DrawString("I'm 阿理...",Point(3,18),BLUE);  
  20.     //  
  21.     getch();  
  22. }  

      所輸出的結果爲:

      測試結果是不是非常”酷“,Graphics類提供非常簡便的函數接口,簡單的調用便能創造出色彩繽紛的世界。有了這個類,以後創建遊戲畫面就簡單多了,如果想豐富這個類的功能,大家就發揮自己的創意吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章