SCORE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //---------------------------------------------------------------------------
  2. // Score.cpp
  3. //---------------------------------------------------------------------------
  4. // Score object to track score, # lives, level.
  5. //---------------------------------------------------------------------------
  6. // (C) Copyright 1995-1997 by Microsoft Corporation.  All rights reserved.
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  9. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  10. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  11. // PARTICULAR PURPOSE.
  12. //---------------------------------------------------------------------------
  13. #include "Main.h"
  14. #pragma hdrstop
  15. #include "Score.h"
  16. #include "Spr.h"
  17. #include "Game.h"
  18. extern CGame *g_pgame;
  19. //---------------------------------------------------------------------------
  20. // DEBUG info
  21. //---------------------------------------------------------------------------
  22. SZTHISFILE
  23. //---------------------------------------------------------------------------
  24. // Initialize score stuff
  25. //---------------------------------------------------------------------------
  26. HRESULT CScore::s_hr = E_FAIL;
  27. HRESULT CScore::CreateScore
  28. (
  29.   HINSTANCE hinst,          // Needed to load bitmaps
  30.   HWND      hwnd,           // hwnd on which to draw the Score, Level, # Lives
  31.   HWND      hwndPS,         // hwnd of PlaySurface
  32.   HWND      hwndStat,       // hwnd of Status Bar
  33.   long      scoreFirst1Up,  // Score to first new life
  34.   long      scoreSecond1Up, // Score to 2nd new life
  35.   long      dscoreNext1Up,  // Score to next new life
  36.   int       cship,          // Number lives to start
  37.   IDBMP     idbmpShip,      // Bitmap for display of # lives
  38.   IDBMP     idbmpPlus,      // Bitmap for "+" when out of room for # lives
  39.   CScore  **ppscoreOut      // Return value: new score object
  40. )
  41. {
  42.   // Initialize output parameters
  43.   *ppscoreOut = NULL;
  44.   // Validate required args, etc.
  45.   if (!idbmpShip || !hwnd)
  46.     return E_INVALIDARG;
  47.   *ppscoreOut = new CScore(hinst, hwnd, hwndPS, hwndStat, scoreFirst1Up, scoreSecond1Up, dscoreNext1Up, cship, idbmpShip, idbmpPlus);
  48.   if (!ppscoreOut)
  49.     return E_OUTOFMEMORY;
  50.   if (s_hr)
  51.     {
  52.     delete *ppscoreOut;
  53.     return s_hr;
  54.     }
  55.   return S_OK;
  56. }
  57. //---------------------------------------------------------------------------
  58. // Initialize score stuff
  59. //---------------------------------------------------------------------------
  60. CScore::CScore
  61. (
  62.   HINSTANCE hinst,          // Needed to load bitmaps
  63.   HWND      hwnd,           // hwnd on which to draw the Score, Level, # Lives
  64.   HWND      hwndPS,         // hwnd of PlaySurface
  65.   HWND      hwndStat,       // hwnd of Status Bar
  66.   long      scoreFirst1Up,  // Score to first new life
  67.   long      scoreSecond1Up, // Score to 2nd new life
  68.   long      dscoreNext1Up,  // Score to next new life
  69.   int       cshipStart,     // Number lives to start
  70.   IDBMP     idbmpShip,      // Bitmap for display of # lives
  71.   IDBMP     idbmpPlus       // Bitmap for "+" when out of room for # lives
  72. )
  73. {
  74.   BITMAP bmp;
  75.   RECT   rectStat;
  76.   INIT_SIGNATURE(SIG_Score);
  77.   // Assume success
  78.   s_hr = S_OK;
  79.   // Assume reasonable default values, if not supplied
  80.   m_hinst          = hinst;
  81.   m_hwnd           = hwnd;
  82.   m_hwndStat       = hwndStat;
  83.   m_hwndPS         = hwndPS;
  84.   m_scoreFirst1Up  = scoreFirst1Up  ? scoreFirst1Up : 0x7fffffff;
  85.   m_scoreSecond1Up = scoreSecond1Up ? scoreFirst1Up : 0x7fffffff;
  86.   m_dscoreNext1Up  = dscoreNext1Up  ? dscoreNext1Up : 0x7fffffff;
  87.   m_cshipStart     = cshipStart;
  88.   // Init rest of class
  89.   m_hbmpShip  = NULL;
  90.   m_hbmpPlus  = NULL;
  91.   m_cyMax     = 0;
  92.   m_cxShip    = 0;
  93.   m_cyShip    = 0;
  94.   m_cxPlus    = 0;
  95.   m_cyPlus    = 0;
  96.   // m_scoreNext1Up = m_scoreFirst1Up;    // Handled by NewGame()
  97.   // m_score        = 0;                  // Handled by NewGame()
  98.   // m_cship        = m_cshipStart;       // Handled by NewGame()
  99.   // m_lvl          = 0;                  // Handled by NewGame()
  100.   // m_rectScore    = 0;                  // Handled below
  101.   // m_rectShip     = 0;                  // Handled below
  102.   // m_rectLvl      = 0;                  // Handled below
  103.   // Finish initing the score object
  104.   this->NewGame();
  105.   ASSERT(m_scoreNext1Up == m_scoreFirst1Up, "NewGame() not initing all");
  106.   ASSERT(!m_score, "NewGame() not initing all");
  107.   ASSERT(m_cship == cshipStart, "NewGame() not initing all");
  108.   ASSERT(!m_lvl, "NewGame() not initing all");
  109.   // Load the bmp for the display of lives
  110.   m_hbmpShip = LoadBitmap(hinst, MAKEINTRESOURCE(idbmpShip));
  111.   if (!m_hbmpShip)
  112.     {
  113.     s_hr = E_FAIL;
  114.     return;
  115.     }
  116.   GetObject(m_hbmpShip, sizeof(bmp), (HGDIOBJ)&bmp);
  117.   m_cxPlus = m_cxShip = bmp.bmWidth;
  118.   m_cyPlus = m_cyShip = m_cyMax = bmp.bmHeight;
  119.   // Load the bmp of the "+" for the display of lives
  120.   if (idbmpPlus)
  121.     {
  122.     m_hbmpPlus = LoadBitmap(hinst, MAKEINTRESOURCE(idbmpPlus));
  123.     if (!m_hbmpPlus)
  124.       {
  125.       s_hr = E_FAIL;
  126.       return;
  127.       }
  128.     GetObject(m_hbmpPlus, sizeof(bmp), (HGDIOBJ)&bmp);
  129.     m_cxPlus = bmp.bmWidth;
  130.     m_cyPlus = bmp.bmHeight;
  131.     if (m_cyPlus > m_cyMax)
  132.       m_cyMax = m_cyPlus;
  133.     }
  134.   // Calc height of Text.
  135.   // HACK: Cheat and use DrawText() with a "|" instead of getting TextMetrics...
  136.   rectStat.top = 0;
  137.   DrawText(GetDC(hwnd), "|", 1, &rectStat, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_CALCRECT);
  138.   m_cyStat = rectStat.bottom;
  139.   if (rectStat.bottom > m_cyMax)
  140.     m_cyMax = rectStat.bottom;
  141.   // Place PlaySurface correctly
  142.   this->Size(372, 282);
  143. }
  144. //---------------------------------------------------------------------------
  145. // Given the size of the PlaySurface, calculate the size of the Dlg & other
  146. // components.
  147. //---------------------------------------------------------------------------
  148. void CScore::Size
  149. (
  150.   int cx,
  151.   int cy
  152. )
  153. {
  154.   RECT rect, rectCli;
  155. #define cBRD  (6)
  156.   GetWindowRect(m_hwnd, &rect);
  157.   GetClientRect(m_hwnd, &rectCli);
  158.   ClientToScreen(m_hwnd, (LPPOINT)&rectCli);
  159.   ClientToScreen(m_hwnd, (LPPOINT)&rectCli.right);
  160.   MoveWindow(m_hwnd,     rect.left,
  161.                          rect.top,
  162.                          cx + (2 * cBRD) + (rect.right - rect.left) - (rectCli.right - rectCli.left),
  163.                          cy + (3 * cBRD + m_cyMax + m_cyStat) + (rect.bottom - rect.top) - (rectCli.bottom - rectCli.top),
  164.                          TRUE);
  165.   GetClientRect(m_hwnd, &rect);
  166.   MoveWindow(m_hwndStat, cBRD,
  167.                          rect.bottom - (m_cyStat + cBRD),
  168.                          rect.right  - (2 * cBRD),
  169.                          m_cyStat, TRUE);
  170.   MoveWindow(m_hwndPS,   cBRD,
  171.                          cBRD + m_cyMax,
  172.                          rect.right  - (2 * cBRD),
  173.                          rect.bottom - (3 * cBRD + m_cyMax + m_cyStat), TRUE);
  174.   GetWindowRect(m_hwndPS, &rect);
  175.   ScreenToClient(m_hwnd, (LPPOINT)&rect);
  176.   ScreenToClient(m_hwnd, (LPPOINT)&rect.right);
  177.   rect.top    = 1;
  178.   rect.bottom = m_cyMax + 4;
  179.   m_rectScore = rect;
  180.   m_rectShip  = rect;
  181.   m_rectLvl   = rect;
  182.   m_rectShip.right = m_rectLvl.left   = rect.left +  (rect.right - rect.left) / 3;
  183.   m_rectLvl.right  = m_rectScore.left = rect.left + ((rect.right - rect.left) / 3 * 2);
  184.   GetClientRect(m_hwndPS, &rect);
  185.   g_pgame->m_pdisp->m_cx = rect.right  - rect.left;
  186.   g_pgame->m_pdisp->m_cy = rect.bottom - rect.top;
  187.   InvalidateRect(m_hwnd,   NULL, TRUE);
  188.   InvalidateRect(m_hwndPS, NULL, TRUE);
  189. }
  190. //---------------------------------------------------------------------------
  191. // Terminate score stuff
  192. //---------------------------------------------------------------------------
  193. CScore::~CScore
  194. (
  195.   void
  196. )
  197. {
  198.   CHECK_SIGNATURE(SIG_Score);
  199.   if (m_hbmpShip)
  200.     DeleteObject((HGDIOBJ)m_hbmpShip);
  201.   if (m_hbmpPlus)
  202.     DeleteObject((HGDIOBJ)m_hbmpPlus);
  203.   DESTROY_SIGNATURE(SIG_Score);
  204. }
  205. //---------------------------------------------------------------------------
  206. // Re-initialize score stuff for new game
  207. //---------------------------------------------------------------------------
  208. void CScore::NewGame
  209. (
  210.   void
  211. )
  212. {
  213.   m_scoreNext1Up = m_scoreFirst1Up;
  214.   m_score        = 0;
  215.   m_cship        = m_cshipStart;
  216.   m_lvl          = 0;
  217.   InvalidateRect(m_hwnd, NULL, TRUE);
  218. }
  219. //---------------------------------------------------------------------------
  220. // Paint score stuff: # 1Ups, current level, score
  221. //---------------------------------------------------------------------------
  222. void CScore::Paint
  223. (
  224.   HDC hdc
  225. )
  226. {
  227.   char  rgch[100];
  228.   int  x, y;
  229.   int  i;
  230.   extern HDC     g_hdcMem;
  231.   extern HBITMAP g_hbmpStock;
  232.   SelectObject(g_hdcMem, m_hbmpShip);
  233.   x = m_rectShip.left;
  234.   y = m_rectShip.top + ((m_rectShip.bottom - m_rectShip.top - m_cyShip) >> 1);
  235.   // Draw the 1Ups w/a "+", if necessary
  236.   for (i=1; i<m_cship; i++)
  237.     {
  238.     BitBlt(hdc, x, y, m_cxShip, m_cyShip, g_hdcMem, 0, 0, SRCCOPY);
  239.     x += m_cxShip + (m_cxShip >> 2);
  240.     // If we only have more 1Ups, but only room for the "+", draw the "+"
  241.     if (x + m_cxShip + m_cxPlus > m_rectShip.right && m_hbmpPlus && i+1<m_cship)
  242.       {
  243.       y = m_rectShip.top + ((m_rectShip.bottom - m_rectShip.top - m_cyPlus) >> 1);
  244.       SelectObject(g_hdcMem, m_hbmpPlus);
  245.       BitBlt(hdc, x, y, m_cxPlus, m_cyPlus, g_hdcMem, 0, 0, SRCCOPY);
  246.       break;
  247.       }
  248.     }
  249.   SelectObject(g_hdcMem, g_hbmpStock);
  250.   SetBkMode(hdc, TRANSPARENT);
  251.   wsprintf(rgch, "%ld", m_score);
  252.   DrawText(hdc, rgch, -1, &m_rectScore, DT_RIGHT|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
  253.   wsprintf(rgch, "%d", m_lvl);
  254.   DrawText(hdc, rgch, -1, &m_rectLvl,   DT_CENTER|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
  255. }
  256. //---------------------------------------------------------------------------
  257. // Change the score by the delta d.
  258. //---------------------------------------------------------------------------
  259. void CScore::Add
  260. (
  261.   long d      // Change the score by this amount (signed)
  262. )
  263. {
  264.   m_score += d;
  265.   if (m_score < 0)
  266.     m_score = 0;
  267.   if (m_score >= m_scoreNext1Up)
  268.     {
  269.     if (m_score > m_scoreSecond1Up)
  270.       m_scoreNext1Up += m_dscoreNext1Up;
  271.     else
  272.       m_scoreNext1Up = m_scoreSecond1Up;
  273.     m_cship++;
  274.     InvalidateRect(m_hwnd, &m_rectShip, TRUE);
  275.     g_pgame->m_pgameoa->FireNewShip();
  276.     }
  277.   InvalidateRect(m_hwnd, &m_rectScore, TRUE);
  278. }
  279. //---------------------------------------------------------------------------
  280. // Called when pausing or unpausing
  281. //---------------------------------------------------------------------------
  282. void CScore::SetStatusText
  283. (
  284.   const char *pszText
  285. )
  286. {
  287.   SetWindowText(m_hwndStat, pszText);
  288. }
  289. //--- EOF -------------------------------------------------------------------