]>
git.saurik.com Git - wxWidgets.git/blob - demos/bombs/bombs1.cpp
1 ///////////////////////////////////////////////////////////////////////////////
4 // Author: P. Foggia 1996
5 // Modified by: Wlodzimierz Skiba (ABX) 2003
8 // Copyright: (c) 1996 P. Foggia
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
13 * implementation of the methods DrawField and OnEvent of the
18 # pragma implementation
21 #include "wx/wxprec.h"
29 #endif //precompiled headers
33 // Draws the field on the device context dc
34 // xc1,yc1 etc. are the (inclusive) limits of the area to be drawn,
35 // expressed in cells.
36 void BombsCanvas::DrawField(wxDC
*dc
, int xc1
, int yc1
, int xc2
, int yc2
)
41 wxColour wxBlack
= wxTheColourDatabase
->Find(wxT("BLACK"));
42 wxColour wxWhite
= wxTheColourDatabase
->Find(wxT("WHITE"));
43 wxColour wxRed
= wxTheColourDatabase
->Find(wxT("RED"));
44 wxColour wxBlue
= wxTheColourDatabase
->Find(wxT("BLUE"));
45 wxColour wxGrey
= wxTheColourDatabase
->Find(wxT("LIGHT GREY"));
46 wxColour wxFocused
= wxTheColourDatabase
->Find(wxT("GREY"));
47 wxColour wxGreen
= wxTheColourDatabase
->Find(wxT("GREEN"));
49 wxPen
*blackPen
= wxThePenList
->FindOrCreatePen(wxBlack
, 1, wxSOLID
);
50 wxPen
*redPen
= wxThePenList
->FindOrCreatePen(wxRed
, 1, wxSOLID
);
51 wxPen
*bluePen
= wxThePenList
->FindOrCreatePen(wxBlue
, 1, wxSOLID
);
52 wxBrush
*whiteBrush
= wxTheBrushList
->FindOrCreateBrush(wxWhite
, wxSOLID
);
53 wxBrush
*greyBrush
= wxTheBrushList
->FindOrCreateBrush(wxGrey
, wxSOLID
);
54 wxBrush
*focusedBrush
= wxTheBrushList
->FindOrCreateBrush(wxFocused
, wxSOLID
);
55 wxBrush
*redBrush
= wxTheBrushList
->FindOrCreateBrush(wxRed
, wxSOLID
);
57 dc
->SetPen(* blackPen
);
60 int xMax
= this->GetGridSizeInPixels().GetWidth();
61 int yMax
= this->GetGridSizeInPixels().GetHeight();
62 for(x
=xc1
; x
<=xc2
; x
++)
63 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, 0, x
*m_cellWidth
*X_UNIT
, yMax
);
64 for(y
=xc1
; y
<=yc2
; y
++)
65 dc
->DrawLine(0, y
*m_cellHeight
*Y_UNIT
, xMax
, y
*m_cellHeight
*Y_UNIT
);
68 wxFont font
= BOMBS_FONT
;
71 for(x
=xc1
; x
<=xc2
; x
++)
72 for(y
=yc1
; y
<=yc2
; y
++)
74 if (m_game
->IsMarked(x
,y
))
76 dc
->SetPen(* blackPen
);
78 if (m_game
->IsFocussed(x
, y
))
79 dc
->SetBrush(* focusedBrush
);
81 dc
->SetBrush(* greyBrush
);
83 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
84 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
86 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
87 dc
->SetTextForeground(wxBlue
);
89 dc
->SetTextForeground(wxRed
);
91 dc
->SetTextBackground(wxGrey
);
92 dc
->GetTextExtent(buf
, &chw
, &chh
);
94 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
95 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2 );
97 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
100 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
101 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
102 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
103 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
106 else if (m_game
->IsHidden(x
,y
))
108 dc
->SetPen(*blackPen
);
109 if (m_game
->IsFocussed(x
, y
))
110 dc
->SetBrush(* focusedBrush
);
112 dc
->SetBrush(*greyBrush
);
114 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
115 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
117 else if (m_game
->IsBomb(x
,y
))
119 dc
->SetPen(* blackPen
);
120 dc
->SetBrush(* redBrush
);
121 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
122 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
124 dc
->SetTextForeground(wxBlack
);
125 dc
->SetTextBackground(wxRed
);
126 dc
->GetTextExtent(buf
, &chw
, &chh
);
128 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
129 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
130 if (m_game
->IsExploded(x
,y
))
132 dc
->SetPen(* bluePen
);
133 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
134 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
135 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
136 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
139 else // Display a digit
141 dc
->SetPen(* blackPen
);
142 if (m_game
->IsFocussed(x
, y
))
143 dc
->SetBrush(* focusedBrush
);
145 dc
->SetBrush(* whiteBrush
);
146 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
147 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
149 int digit_value
= m_game
->Get(x
,y
) & BG_MASK
;
154 dc
->SetTextForeground(wxGreen
);
158 dc
->SetTextForeground(wxBlue
);
161 buf
.Printf(wxT("%d"),digit_value
);
162 dc
->SetTextForeground(wxBlack
);
165 dc
->GetTextExtent(buf
, &chw
, &chh
);
166 dc
->SetTextBackground(wxWhite
);
168 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
169 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
172 dc
->SetFont(wxNullFont
);
175 wxLogStatus(wxT("%d bombs %d remaining cells"),
176 m_game
->GetNumBombs(), m_game
->GetNumRemainingCells() );
180 // Refreshes the field image
181 // xc1,yc1 etc. are the (inclusive) limits of the area to be drawn,
182 // expressed in cells.
183 void BombsCanvas::RefreshField(int xc1
, int yc1
, int xc2
, int yc2
)
186 DrawField(& dc
, xc1
, yc1
, xc2
, yc2
);
190 memDC
.SelectObject(*m_bmp
);
191 DrawField(&memDC
, xc1
, yc1
, xc2
, yc2
);
192 memDC
.SelectObject(wxNullBitmap
);
196 // Called when uncovering a cell.
197 void BombsCanvas::Uncover(int x
, int y
)
200 RefreshField(x
, y
, x
, y
);
202 const int gridWidth
= m_game
->GetWidth();
203 const int gridHeight
= m_game
->GetHeight();
205 const bool hasWon
= m_game
->GetNumRemainingCells() == 0;
206 if (m_game
->IsBomb(x
,y
) || hasWon
)
211 wxMessageBox(wxT("Nice! You found all the bombs!"),
212 wxT("wxWin Bombs"), wxOK
|wxCENTRE
);
214 else // x,y is a bomb
216 m_game
->Explode(x
, y
);
219 for(x
=0; x
<gridWidth
; x
++)
220 for(y
=0; y
<gridHeight
; y
++)
222 RefreshField(0, 0, gridWidth
-1, gridHeight
-1);
224 else if (!m_game
->Get(x
, y
))
226 int left
= ( x
> 0 ) ? x
-1 : 0;
227 int right
= ( x
< gridWidth
- 1 )
230 int top
= ( y
> 0 ) ? y
-1 : 0;
231 int bottom
= ( y
< gridHeight
- 1 )
236 for (j
=top
; j
<=bottom
; j
++)
237 for (i
=left
; i
<=right
; i
++)
238 if ( (i
!= x
|| j
!= y
) && m_game
->IsHidden(i
, j
)
239 && !m_game
->IsMarked(i
, j
) )
246 // Called when the canvas receives a mouse event.
247 void BombsCanvas::OnMouseEvent(wxMouseEvent
& event
)
249 const int gridWidth
= m_game
->GetWidth();
250 const int gridHeight
= m_game
->GetHeight();
253 event
.GetPosition(&fx
, &fy
);
254 int x
= fx
/(m_cellWidth
*X_UNIT
);
255 int y
= fy
/(m_cellHeight
*Y_UNIT
);
256 if (x
<gridWidth
&& y
<gridHeight
)
258 if ( (event
.RightDown() || (event
.LeftDown() && event
.ShiftDown()))
259 && (m_game
->IsHidden(x
,y
)
260 || !m_game
->GetNumRemainingCells() ) )
262 // store previous and current field
263 int prevFocusX
= m_game
->m_gridFocusX
;
264 int prevFocusY
= m_game
->m_gridFocusY
;
265 m_game
->m_gridFocusX
= x
;
266 m_game
->m_gridFocusY
= y
;
267 RefreshField(prevFocusX
, prevFocusY
, prevFocusX
, prevFocusY
);
269 RefreshField(x
, y
, x
, y
);
272 else if (event
.LeftDown() && m_game
->IsHidden(x
,y
)
273 && !m_game
->IsMarked(x
,y
))
275 // store previous and current field
276 int prevGridFocusX
= m_game
->m_gridFocusX
;
277 int prevGridFocusY
= m_game
->m_gridFocusY
;
278 m_game
->m_gridFocusX
= x
;
279 m_game
->m_gridFocusY
= y
;
280 RefreshField(prevGridFocusX
, prevGridFocusY
,
281 prevGridFocusX
, prevGridFocusY
);
288 void BombsCanvas::OnChar(wxKeyEvent
& event
)
290 int keyCode
= event
.GetKeyCode();
291 int prevGridFocusX
= m_game
->m_gridFocusX
;
292 int prevGridFocusY
= m_game
->m_gridFocusY
;
294 const int gridWidth
= m_game
->GetWidth();
295 const int gridHeight
= m_game
->GetHeight();
301 m_game
->m_gridFocusX
++;
302 if (m_game
->m_gridFocusX
>= gridWidth
) m_game
->m_gridFocusX
= 0;
306 m_game
->m_gridFocusX
--;
307 if (m_game
->m_gridFocusX
<0) m_game
->m_gridFocusX
= gridWidth
-1;
311 m_game
->m_gridFocusY
++;
312 if (m_game
->m_gridFocusY
>= gridHeight
) m_game
->m_gridFocusY
= 0;
316 m_game
->m_gridFocusY
--;
317 if (m_game
->m_gridFocusY
<0) m_game
->m_gridFocusY
= gridHeight
-1;
321 if ( (prevGridFocusX
== m_game
->m_gridFocusX
)
322 && (prevGridFocusY
== m_game
->m_gridFocusY
)
323 && (m_game
->IsHidden(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
)) )
325 m_game
->Mark(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
326 if (!m_game
->IsMarked(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
))
328 Uncover(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
330 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
331 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
340 if ((prevGridFocusX
!= m_game
->m_gridFocusX
)
341 || (prevGridFocusY
!= m_game
->m_gridFocusY
))
343 // cause focused field to be visible after first key hit after launching new game
344 if( m_game
->m_gridFocusX
< 0 ) m_game
->m_gridFocusX
= 0;
345 if( m_game
->m_gridFocusY
< 0 ) m_game
->m_gridFocusY
= 0;
347 // refresh previous field and focused field
348 RefreshField(prevGridFocusX
, prevGridFocusY
,
349 prevGridFocusX
, prevGridFocusY
);
350 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
351 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);