home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 03 Pathfinding with Astar / 01 Matthews / ase / aseView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-05  |  7.9 KB  |  359 lines

  1. // aseView.cpp : implementation of the CAseView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "ase.h"
  6.  
  7. #include "aseDoc.h"
  8. #include "aseView.h"
  9.  
  10. #define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
  11.  
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. #define ci(x,y) x*ASE_BOARDY+y
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CAseView
  22.  
  23. IMPLEMENT_DYNCREATE(CAseView, CView)
  24.  
  25. BEGIN_MESSAGE_MAP(CAseView, CView)
  26.     //{{AFX_MSG_MAP(CAseView)
  27.     ON_WM_LBUTTONDOWN()
  28.     ON_WM_LBUTTONUP()
  29.     ON_WM_MOUSEMOVE()
  30.     ON_WM_ERASEBKGND()
  31.     ON_WM_RBUTTONDBLCLK()
  32.     //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CAseView construction/destruction
  37.  
  38. static COLORREF crBrushes [] = {
  39.     RGB(255,255,255),
  40.     RGB(192,192,192),
  41.     RGB(128,128,128),
  42.     RGB(000,000,000),
  43.     RGB(255,000,000),
  44.     RGB(000,255,000),
  45. };
  46.  
  47. CAseView::CAseView()
  48. {
  49.     m_bDragging = false;
  50.     m_uBrushType = 0;
  51. }
  52.  
  53. CAseView::~CAseView()
  54. {
  55. }
  56.  
  57. BOOL CAseView::PreCreateWindow(CREATESTRUCT& cs)
  58. {
  59.     return CView::PreCreateWindow(cs);
  60. }
  61.  
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CAseView drawing
  64.  
  65. void CAseView::OnDraw(CDC* pDC)
  66. {
  67.     CAseDoc* pDoc = GetDocument();
  68.     ASSERT_VALID(pDoc);
  69.  
  70.     CRect rect;
  71.     GetClientRect(rect);
  72.  
  73.     CDC memdc;
  74.     CBitmap bmp, *oldbmp;
  75.     CPen *oldpen, pen(PS_SOLID, 1, RGB(255,0,255));
  76.  
  77.     memdc.CreateCompatibleDC(GetDC());
  78.     bmp.CreateDiscardableBitmap(pDC, rect.Width(), rect.Height());
  79.     oldbmp = memdc.SelectObject(&bmp);
  80.     oldpen = memdc.SelectObject(&pen);
  81.     
  82.     char *board = pDoc->GetBoard();
  83.     
  84.     memdc.FillSolidRect(rect, RGB(255,255,255));
  85.  
  86.     int i;
  87.     int dx = rect.Width();
  88.     int dy = rect.Height();
  89.  
  90.     // Cycle through the board and draw any squares
  91.  
  92.     for (i=0; i<ASE_BOARDX; i++) {
  93.         for (int j=0; j<ASE_BOARDY; j++) {
  94.             if (board[ci(i,j)] != 0) {
  95.                 DrawRectangle(i, j, &memdc, crBrushes[board[ci(i,j)]]);
  96.             }
  97.         }
  98.     }
  99.  
  100.     // Draw start, end and debug points
  101.     if (m_cStart.x != -1) DrawRectangle(m_cStart.x, m_cStart.y, &memdc, crBrushes[4]);
  102.     if (m_cEnd.x != -1)   DrawRectangle(m_cEnd.x, m_cEnd.y, &memdc, crBrushes[5]);
  103.  
  104.     // Draw the grid...
  105.  
  106.     for (i=0; i<dx; i+=8) {
  107.         for (int j=0;j<dy;j+=8) {
  108.             memdc.SetPixel(i, j, RGB(192, 192, 192));
  109.         }
  110.     }
  111.  
  112.     // Draw route if necessary
  113.     if (pDoc->DrawRoute()) DrawRoute(&memdc);
  114.  
  115.     if (m_cHilight.x != -1) {
  116.         DrawRectangle(m_cHilight.x, m_cHilight.y, &memdc, RGB(0,0,255));
  117.         
  118.         CPoint centre;
  119.         centre.x = m_cHilight.x*ASE_GRIDSIZE+(ASE_GRIDSIZE/2);
  120.         centre.y = m_cHilight.y*ASE_GRIDSIZE+(ASE_GRIDSIZE/2);
  121.  
  122.         memdc.MoveTo(centre);
  123.  
  124.         int numchildren = m_cHilightNode->numchildren;
  125.         _asNode *temp;
  126.     
  127.         for (int i=0; i<numchildren; i++) {
  128.             temp = m_cHilightNode->children[i];
  129.             memdc.LineTo(temp->x * ASE_GRIDSIZE + (ASE_GRIDSIZE/2),
  130.                         temp->y * ASE_GRIDSIZE + (ASE_GRIDSIZE/2));
  131.             memdc.MoveTo(centre);
  132.         }
  133.     }
  134.  
  135.     CPoint bp = pDoc->GetBreakpoint();
  136.     if (bp.x != -1) DrawCircle(bp.x, bp.y, &memdc, RGB(128,0,0));
  137.  
  138.     pDC->BitBlt(0,0,rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
  139.  
  140.     memdc.SelectObject(oldpen);
  141.     memdc.SelectObject(oldbmp);
  142. }
  143.  
  144. void CAseView::DrawRectangle(int x, int y, CDC *pDC, COLORREF cr)
  145. {
  146.     CBrush br(RGB(0,0,0));
  147.     CRect rect(x*ASE_GRIDSIZE, y*ASE_GRIDSIZE, 
  148.                x*ASE_GRIDSIZE+ASE_GRIDSIZE+1,
  149.                y*ASE_GRIDSIZE+ASE_GRIDSIZE+1);
  150.  
  151.     pDC->FillSolidRect(rect, cr);
  152.     pDC->FrameRect(&rect, &br);
  153. }
  154.  
  155. void CAseView::DrawCircle(int x, int y, CDC *pDC, COLORREF cr)
  156. {
  157.     CBrush br(cr), *oldbrush;
  158.     CPen pen(PS_SOLID, 0, RGB(0,0,0)), *oldpen;
  159.     CRect rect(x*ASE_GRIDSIZE, y*ASE_GRIDSIZE, 
  160.                x*ASE_GRIDSIZE+ASE_GRIDSIZE+1,
  161.                y*ASE_GRIDSIZE+ASE_GRIDSIZE+1);
  162.  
  163.     oldbrush = pDC->SelectObject(&br);
  164.     oldpen   = pDC->SelectObject(&pen);
  165.  
  166.     pDC->Ellipse(rect);
  167.  
  168.     pDC->SelectObject(oldbrush);
  169.     pDC->SelectObject(oldpen);
  170. }
  171.  
  172. void CAseView::DrawRoute(CDC *pDC)
  173. {
  174.     CAseDoc* pDoc = GetDocument();
  175.     ASSERT_VALID(pDoc);
  176.  
  177.     CPen pen(PS_SOLID,1,RGB(0,0,0)),*oldpen;
  178.  
  179.     oldpen = pDC->SelectObject(&pen);
  180.  
  181.     CAStar *astar = pDoc->GetPathFinder();
  182.     _asNode *best = astar->GetBestNode();
  183.         
  184.     int x,y,px,py;
  185.  
  186.     if (best) {
  187.         x = best->x;
  188.         y = best->y;
  189.         
  190.         px = x * ASE_GRIDSIZE + (ASE_GRIDSIZE / 2);
  191.         py = y * ASE_GRIDSIZE + (ASE_GRIDSIZE / 2);
  192.  
  193.         pDC->MoveTo(px,py);
  194.         best = best->parent;
  195.     }
  196.  
  197.     while (best) {
  198.         x = best->x;
  199.         y = best->y;
  200.         
  201.         px = x * ASE_GRIDSIZE + (ASE_GRIDSIZE / 2);
  202.         py = y * ASE_GRIDSIZE + (ASE_GRIDSIZE / 2);
  203.         
  204.         pDC->LineTo(px,py);
  205.  
  206.         best = best->parent;
  207.     }
  208.  
  209.     pDC->SetPixel(px,py, RGB(0,0,128));
  210.     pDC->SelectObject(oldpen);
  211. }
  212.  
  213. void CAseView::HighlightNode(_asNode *node, bool drawKidsConnections)
  214. {
  215.     if (!node) {
  216.         m_cHilight.x = -1;
  217.         m_cHilightNode = NULL;
  218.     } else {
  219.         m_cHilight.x = node->x;
  220.         m_cHilight.y = node->y;
  221.         m_cHilightNode = node;
  222.     }
  223.  
  224.     Invalidate(false);
  225. }
  226.  
  227. void CAseView::RemoveHighlight()
  228. {
  229.     m_cHilight.x = -1;
  230.     m_cHilightNode = NULL;
  231. }
  232.  
  233. void CAseView::OnInitialUpdate()
  234. {
  235.     CView::OnInitialUpdate();
  236.  
  237.     m_cHilight.x = -1;
  238.     m_cHilightNode = NULL;
  239.     GetDocument()->GetStartEnd(m_cStart, m_cEnd);
  240. }
  241.  
  242. /////////////////////////////////////////////////////////////////////////////
  243. // CAseView diagnostics
  244.  
  245. #ifdef _DEBUG
  246. void CAseView::AssertValid() const
  247. {
  248.     CView::AssertValid();
  249. }
  250.  
  251. void CAseView::Dump(CDumpContext& dc) const
  252. {
  253.     CView::Dump(dc);
  254. }
  255.  
  256. CAseDoc* CAseView::GetDocument() // non-debug version is inline
  257. {
  258.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAseDoc)));
  259.     return (CAseDoc*)m_pDocument;
  260. }
  261. #endif //_DEBUG
  262.  
  263. /////////////////////////////////////////////////////////////////////////////
  264. // CAseView message handlers
  265.  
  266. void CAseView::OnLButtonDown(UINT nFlags, CPoint point) 
  267. {
  268.     CAseDoc* pDoc = GetDocument();
  269.     ASSERT_VALID(pDoc);
  270.  
  271.     MouseToPoint(point, m_uBrushType);
  272.  
  273.     if (m_uBrushType < 4) m_bDragging = true;
  274.  
  275.     CView::OnLButtonDown(nFlags, point);
  276. }
  277.  
  278. void CAseView::OnLButtonUp(UINT nFlags, CPoint point) 
  279. {
  280.     m_bDragging = false;
  281.     GetDocument()->NotifyClick();
  282.     
  283.     CView::OnLButtonUp(nFlags, point);
  284. }
  285.  
  286. void CAseView::OnMouseMove(UINT nFlags, CPoint point) 
  287. {
  288.     if (m_bDragging) {
  289.         MouseToPoint(point, m_uBrushType);
  290.     }
  291.     
  292.     CView::OnMouseMove(nFlags, point);
  293. }
  294.  
  295. void CAseView::MouseToPoint(CPoint point, UINT brush)
  296. {
  297.     CClientDC dc(this);
  298.  
  299.     int px = point.x/8, py = point.y/8;
  300.  
  301.     CPoint round(px*ASE_GRIDSIZE, py*ASE_GRIDSIZE),temp;
  302.  
  303.     GetDocument()->GetStartEnd(m_cStart, m_cEnd);
  304.  
  305.     // If start or end
  306.     if (brush == 4) {
  307.         temp.x = m_cStart.x * ASE_GRIDSIZE;
  308.         temp.y = m_cStart.y * ASE_GRIDSIZE;
  309.  
  310.         m_cStart.x = px;
  311.         m_cStart.y = py;
  312.  
  313.         InvalidateRect(CRect(round,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  314.         InvalidateRect(CRect(temp,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  315.     } else if (brush == 5) {
  316.         temp.x = m_cEnd.x * ASE_GRIDSIZE;
  317.         temp.y = m_cEnd.y * ASE_GRIDSIZE;
  318.  
  319.         m_cEnd.x = px;
  320.         m_cEnd.y = py;
  321.         
  322.         InvalidateRect(CRect(round,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  323.         InvalidateRect(CRect(temp,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  324.     } else if (brush == -1) {
  325.         CPoint bp = GetDocument()->GetBreakpoint();
  326.  
  327.         temp.x = bp.x * ASE_GRIDSIZE;
  328.         temp.y = bp.y * ASE_GRIDSIZE;
  329.  
  330.         bp.x = px;
  331.         bp.y = py;
  332.  
  333.         GetDocument()->SetBreakpoint(bp);
  334.  
  335.         InvalidateRect(CRect(round,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  336.         InvalidateRect(CRect(temp,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  337.     } else {
  338.         char *board = GetDocument()->GetBoard();
  339.  
  340.         board[ci(px,py)] = brush;
  341.         InvalidateRect(CRect(round,CSize(ASE_GRIDSIZE+1,ASE_GRIDSIZE+1)), false);
  342.     }
  343.  
  344.     GetDocument()->SetStartEnd(m_cStart, m_cEnd);
  345. }
  346.  
  347. BOOL CAseView::OnEraseBkgnd(CDC* pDC) 
  348. {
  349.     return false;    
  350.     return CView::OnEraseBkgnd(pDC);
  351. }
  352.  
  353. void CAseView::OnRButtonDblClk(UINT nFlags, CPoint point) 
  354. {
  355.     MouseToPoint(point, -1);
  356.     
  357.     CView::OnRButtonDblClk(nFlags, point);
  358. }
  359.