]>
git.saurik.com Git - wxWidgets.git/blob - demos/bombs/bombs1.cpp
1 ///////////////////////////////////////////////////////////////////////////////
4 // Author: P. Foggia 1996
5 // Modified by: Wlodzimierz Skiba (ABX) since 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 wxYellow
= wxTheColourDatabase
->Find(wxT("YELLOW"));
42 wxColour wxFocused
= wxTheColourDatabase
->Find(wxT("GREY"));
44 wxPen
*bluePen
= wxThePenList
->FindOrCreatePen(*wxBLUE
, 1, wxSOLID
);
46 wxBrush
*focusedBrush
= wxTheBrushList
->FindOrCreateBrush(wxFocused
, wxSOLID
);
47 wxBrush
*yellowBrush
= wxTheBrushList
->FindOrCreateBrush(wxYellow
, wxSOLID
);
49 dc
->SetPen(*wxBLACK_PEN
);
52 int xMax
= this->GetGridSizeInPixels().GetWidth();
53 int yMax
= this->GetGridSizeInPixels().GetHeight();
54 for(x
=xc1
; x
<=xc2
; x
++)
55 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, 0, x
*m_cellWidth
*X_UNIT
, yMax
);
56 for(y
=xc1
; y
<=yc2
; y
++)
57 dc
->DrawLine(0, y
*m_cellHeight
*Y_UNIT
, xMax
, y
*m_cellHeight
*Y_UNIT
);
60 wxFont font
= BOMBS_FONT
;
63 for(x
=xc1
; x
<=xc2
; x
++)
64 for(y
=yc1
; y
<=yc2
; y
++)
66 if (m_game
->IsMarked(x
,y
))
68 dc
->SetPen(*wxBLACK_PEN
);
70 if (m_game
->IsFocussed(x
, y
))
71 dc
->SetBrush(*focusedBrush
);
73 dc
->SetBrush(*wxLIGHT_GREY_BRUSH
);
75 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
76 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
78 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
79 dc
->SetTextForeground(*wxBLUE
);
81 dc
->SetTextForeground(*wxRED
);
83 dc
->SetTextBackground(*wxLIGHT_GREY
);
84 dc
->GetTextExtent(buf
, &chw
, &chh
);
86 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
87 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2 );
89 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
91 dc
->SetPen(*wxRED_PEN
);
92 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
93 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
94 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
95 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
98 else if (m_game
->IsHidden(x
,y
))
100 dc
->SetPen(*wxBLACK_PEN
);
101 if (m_game
->IsFocussed(x
, y
))
102 dc
->SetBrush(*focusedBrush
);
104 dc
->SetBrush(*wxLIGHT_GREY_BRUSH
);
106 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
107 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
109 else if (m_game
->IsBomb(x
,y
))
111 dc
->SetPen(*wxBLACK_PEN
);
112 dc
->SetBrush(*wxRED_BRUSH
);
113 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
114 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
116 dc
->SetTextForeground(*wxBLACK
);
117 dc
->SetTextBackground(*wxRED
);
118 dc
->GetTextExtent(buf
, &chw
, &chh
);
120 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
121 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
122 if (m_game
->IsExploded(x
,y
))
124 dc
->SetPen(*bluePen
);
125 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
126 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
127 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
128 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
131 else // Display a digit
133 dc
->SetPen(*wxBLACK_PEN
);
134 if (m_game
->IsFocussed(x
, y
))
135 dc
->SetBrush(*focusedBrush
);
136 else if (m_game
->IsSelected(x
,y
))
137 dc
->SetBrush(*wxWHITE_BRUSH
);
139 dc
->SetBrush(*yellowBrush
);
140 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
141 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
143 int digit_value
= m_game
->Get(x
,y
) & BG_MASK
;
148 dc
->SetTextForeground(*wxGREEN
);
152 dc
->SetTextForeground(*wxBLUE
);
155 buf
.Printf(wxT("%d"),digit_value
);
156 dc
->SetTextForeground(*wxBLACK
);
159 dc
->GetTextExtent(buf
, &chw
, &chh
);
160 dc
->SetTextBackground(*wxWHITE
);
162 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
163 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
166 dc
->SetFont(wxNullFont
);
169 msg
.Printf(wxT("%d bombs, %u marked, %d remaining cells"),
170 m_game
->GetNumBombs(), m_game
->GetNumMarkedCells(),
171 m_game
->GetNumRemainingCells() );
173 #if wxUSE_LOG && wxUSE_STATUSBAR
176 this->GetParent()->SetTitle(msg
);
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
)
199 m_game
->Unhide(x
,y
,true);
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
++)
221 m_game
->Unhide(x
,y
,false);
223 RefreshField(0, 0, gridWidth
-1, gridHeight
-1);
225 else if (0 == (m_game
->Get(x
, y
) & BG_MASK
))
227 int left
= ( x
> 0 ) ? x
-1 : 0;
228 int right
= ( x
< gridWidth
- 1 )
231 int top
= ( y
> 0 ) ? y
-1 : 0;
232 int bottom
= ( y
< gridHeight
- 1 )
237 for (j
=top
; j
<=bottom
; j
++)
238 for (i
=left
; i
<=right
; i
++)
239 if ( (i
!= x
|| j
!= y
) && m_game
->IsHidden(i
, j
)
240 && !m_game
->IsMarked(i
, j
) )
247 // Called when the canvas receives a mouse event.
248 void BombsCanvas::OnMouseEvent(wxMouseEvent
& event
)
250 const int gridWidth
= m_game
->GetWidth();
251 const int gridHeight
= m_game
->GetHeight();
254 event
.GetPosition(&fx
, &fy
);
255 int x
= fx
/(m_cellWidth
*X_UNIT
);
256 int y
= fy
/(m_cellHeight
*Y_UNIT
);
257 if (x
<gridWidth
&& y
<gridHeight
)
259 if ( (event
.RightDown() || (event
.LeftDown() && event
.ShiftDown()))
260 && (m_game
->IsHidden(x
,y
)
261 || !m_game
->GetNumRemainingCells() ) )
263 // store previous and current field
264 int prevFocusX
= m_game
->m_gridFocusX
;
265 int prevFocusY
= m_game
->m_gridFocusY
;
266 m_game
->m_gridFocusX
= x
;
267 m_game
->m_gridFocusY
= y
;
268 RefreshField(prevFocusX
, prevFocusY
, prevFocusX
, prevFocusY
);
270 RefreshField(x
, y
, x
, y
);
273 else if (event
.LeftDown() && m_game
->IsHidden(x
,y
)
274 && !m_game
->IsMarked(x
,y
))
276 // store previous and current field
277 int prevGridFocusX
= m_game
->m_gridFocusX
;
278 int prevGridFocusY
= m_game
->m_gridFocusY
;
279 m_game
->m_gridFocusX
= x
;
280 m_game
->m_gridFocusY
= y
;
281 RefreshField(prevGridFocusX
, prevGridFocusY
,
282 prevGridFocusX
, prevGridFocusY
);
289 void BombsCanvas::OnChar(wxKeyEvent
& event
)
291 int keyCode
= event
.GetKeyCode();
292 int prevGridFocusX
= m_game
->m_gridFocusX
;
293 int prevGridFocusY
= m_game
->m_gridFocusY
;
295 const int gridWidth
= m_game
->GetWidth();
296 const int gridHeight
= m_game
->GetHeight();
302 m_game
->m_gridFocusX
++;
303 if (m_game
->m_gridFocusX
>= gridWidth
) m_game
->m_gridFocusX
= 0;
307 m_game
->m_gridFocusX
--;
308 if (m_game
->m_gridFocusX
<0) m_game
->m_gridFocusX
= gridWidth
-1;
312 m_game
->m_gridFocusY
++;
313 if (m_game
->m_gridFocusY
>= gridHeight
) m_game
->m_gridFocusY
= 0;
317 m_game
->m_gridFocusY
--;
318 if (m_game
->m_gridFocusY
<0) m_game
->m_gridFocusY
= gridHeight
-1;
322 if ( (prevGridFocusX
== m_game
->m_gridFocusX
)
323 && (prevGridFocusY
== m_game
->m_gridFocusY
)
324 && (m_game
->IsHidden(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
)) )
326 m_game
->Mark(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
327 if (!m_game
->IsMarked(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
))
329 Uncover(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
331 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
332 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
341 if ((prevGridFocusX
!= m_game
->m_gridFocusX
)
342 || (prevGridFocusY
!= m_game
->m_gridFocusY
))
344 // cause focused field to be visible after first key hit after launching new game
345 if( m_game
->m_gridFocusX
< 0 ) m_game
->m_gridFocusX
= 0;
346 if( m_game
->m_gridFocusY
< 0 ) m_game
->m_gridFocusY
= 0;
348 // refresh previous field and focused field
349 RefreshField(prevGridFocusX
, prevGridFocusY
,
350 prevGridFocusX
, prevGridFocusY
);
351 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
352 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);