]>
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
17 #include "wx/wxprec.h"
25 #endif //precompiled headers
29 // Draws the field on the device context dc
30 // xc1,yc1 etc. are the (inclusive) limits of the area to be drawn,
31 // expressed in cells.
32 void BombsCanvas::DrawField(wxDC
*dc
, int xc1
, int yc1
, int xc2
, int yc2
)
37 wxColour wxYellow
= wxTheColourDatabase
->Find(wxT("YELLOW"));
38 wxColour wxFocused
= wxTheColourDatabase
->Find(wxT("GREY"));
40 wxPen
*bluePen
= wxThePenList
->FindOrCreatePen(*wxBLUE
, 1, wxSOLID
);
42 wxBrush
*focusedBrush
= wxTheBrushList
->FindOrCreateBrush(wxFocused
, wxSOLID
);
43 wxBrush
*yellowBrush
= wxTheBrushList
->FindOrCreateBrush(wxYellow
, wxSOLID
);
45 dc
->SetPen(*wxBLACK_PEN
);
48 int xMax
= this->GetGridSizeInPixels().GetWidth();
49 int yMax
= this->GetGridSizeInPixels().GetHeight();
50 for(x
=xc1
; x
<=xc2
; x
++)
51 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, 0, x
*m_cellWidth
*X_UNIT
, yMax
);
52 for(y
=xc1
; y
<=yc2
; y
++)
53 dc
->DrawLine(0, y
*m_cellHeight
*Y_UNIT
, xMax
, y
*m_cellHeight
*Y_UNIT
);
56 wxFont font
= BOMBS_FONT
;
59 for(x
=xc1
; x
<=xc2
; x
++)
60 for(y
=yc1
; y
<=yc2
; y
++)
62 if (m_game
->IsMarked(x
,y
))
64 dc
->SetPen(*wxBLACK_PEN
);
66 if (m_game
->IsFocussed(x
, y
))
67 dc
->SetBrush(*focusedBrush
);
69 dc
->SetBrush(*wxLIGHT_GREY_BRUSH
);
71 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
72 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
74 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
75 dc
->SetTextForeground(*wxBLUE
);
77 dc
->SetTextForeground(*wxRED
);
79 dc
->SetTextBackground(*wxLIGHT_GREY
);
80 dc
->GetTextExtent(buf
, &chw
, &chh
);
82 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
83 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2 );
85 if (!m_game
->IsHidden(x
,y
) && m_game
->IsBomb(x
,y
))
87 dc
->SetPen(*wxRED_PEN
);
88 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
89 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
90 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
91 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
94 else if (m_game
->IsHidden(x
,y
))
96 dc
->SetPen(*wxBLACK_PEN
);
97 if (m_game
->IsFocussed(x
, y
))
98 dc
->SetBrush(*focusedBrush
);
100 dc
->SetBrush(*wxLIGHT_GREY_BRUSH
);
102 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
103 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
105 else if (m_game
->IsBomb(x
,y
))
107 dc
->SetPen(*wxBLACK_PEN
);
108 dc
->SetBrush(*wxRED_BRUSH
);
109 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
110 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
112 dc
->SetTextForeground(*wxBLACK
);
113 dc
->SetTextBackground(*wxRED
);
114 dc
->GetTextExtent(buf
, &chw
, &chh
);
116 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
117 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
118 if (m_game
->IsExploded(x
,y
))
120 dc
->SetPen(*bluePen
);
121 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
122 (x
+1)*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
);
123 dc
->DrawLine(x
*m_cellWidth
*X_UNIT
, (y
+1)*m_cellHeight
*Y_UNIT
,
124 (x
+1)*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
);
127 else // Display a digit
129 dc
->SetPen(*wxBLACK_PEN
);
130 if (m_game
->IsFocussed(x
, y
))
131 dc
->SetBrush(*focusedBrush
);
132 else if (m_game
->IsSelected(x
,y
))
133 dc
->SetBrush(*wxWHITE_BRUSH
);
135 dc
->SetBrush(*yellowBrush
);
136 dc
->DrawRectangle( x
*m_cellWidth
*X_UNIT
, y
*m_cellHeight
*Y_UNIT
,
137 m_cellWidth
*X_UNIT
+1, m_cellHeight
*Y_UNIT
+1);
139 int digit_value
= m_game
->Get(x
,y
) & BG_MASK
;
144 dc
->SetTextForeground(*wxGREEN
);
148 dc
->SetTextForeground(*wxBLUE
);
151 buf
.Printf(wxT("%d"),digit_value
);
152 dc
->SetTextForeground(*wxBLACK
);
155 dc
->GetTextExtent(buf
, &chw
, &chh
);
156 dc
->SetTextBackground(*wxWHITE
);
158 x
*m_cellWidth
*X_UNIT
+ (m_cellWidth
*X_UNIT
-chw
)/2,
159 y
*m_cellHeight
*Y_UNIT
+ (m_cellHeight
*Y_UNIT
-chh
)/2);
162 dc
->SetFont(wxNullFont
);
165 msg
.Printf(wxT("%d bombs, %u marked, %d remaining cells"),
166 m_game
->GetNumBombs(), m_game
->GetNumMarkedCells(),
167 m_game
->GetNumRemainingCells() );
169 #if wxUSE_LOG && wxUSE_STATUSBAR
172 this->GetParent()->SetTitle(msg
);
176 // Refreshes the field image
177 // xc1,yc1 etc. are the (inclusive) limits of the area to be drawn,
178 // expressed in cells.
179 void BombsCanvas::RefreshField(int xc1
, int yc1
, int xc2
, int yc2
)
182 DrawField(& dc
, xc1
, yc1
, xc2
, yc2
);
186 memDC
.SelectObject(*m_bmp
);
187 DrawField(&memDC
, xc1
, yc1
, xc2
, yc2
);
188 memDC
.SelectObject(wxNullBitmap
);
192 // Called when uncovering a cell.
193 void BombsCanvas::Uncover(int x
, int y
)
195 m_game
->Unhide(x
,y
,true);
196 RefreshField(x
, y
, x
, y
);
198 const int gridWidth
= m_game
->GetWidth();
199 const int gridHeight
= m_game
->GetHeight();
201 const bool hasWon
= m_game
->GetNumRemainingCells() == 0;
202 if (m_game
->IsBomb(x
,y
) || hasWon
)
207 wxMessageBox(wxT("Nice! You found all the bombs!"),
208 wxT("wxWin Bombs"), wxOK
|wxCENTRE
);
210 else // x,y is a bomb
212 m_game
->Explode(x
, y
);
215 for(x
=0; x
<gridWidth
; x
++)
216 for(y
=0; y
<gridHeight
; y
++)
217 m_game
->Unhide(x
,y
,false);
219 RefreshField(0, 0, gridWidth
-1, gridHeight
-1);
221 else if (0 == (m_game
->Get(x
, y
) & BG_MASK
))
223 int left
= ( x
> 0 ) ? x
-1 : 0;
224 int right
= ( x
< gridWidth
- 1 )
227 int top
= ( y
> 0 ) ? y
-1 : 0;
228 int bottom
= ( y
< gridHeight
- 1 )
233 for (j
=top
; j
<=bottom
; j
++)
234 for (i
=left
; i
<=right
; i
++)
235 if ( (i
!= x
|| j
!= y
) && m_game
->IsHidden(i
, j
)
236 && !m_game
->IsMarked(i
, j
) )
243 // Called when the canvas receives a mouse event.
244 void BombsCanvas::OnMouseEvent(wxMouseEvent
& event
)
246 const int gridWidth
= m_game
->GetWidth();
247 const int gridHeight
= m_game
->GetHeight();
250 event
.GetPosition(&fx
, &fy
);
251 int x
= fx
/(m_cellWidth
*X_UNIT
);
252 int y
= fy
/(m_cellHeight
*Y_UNIT
);
253 if (x
<gridWidth
&& y
<gridHeight
)
255 if ( (event
.RightDown() || (event
.LeftDown() && event
.ShiftDown()))
256 && (m_game
->IsHidden(x
,y
)
257 || !m_game
->GetNumRemainingCells() ) )
259 // store previous and current field
260 int prevFocusX
= m_game
->m_gridFocusX
;
261 int prevFocusY
= m_game
->m_gridFocusY
;
262 m_game
->m_gridFocusX
= x
;
263 m_game
->m_gridFocusY
= y
;
264 RefreshField(prevFocusX
, prevFocusY
, prevFocusX
, prevFocusY
);
266 RefreshField(x
, y
, x
, y
);
269 else if (event
.LeftDown() && m_game
->IsHidden(x
,y
)
270 && !m_game
->IsMarked(x
,y
))
272 // store previous and current field
273 int prevGridFocusX
= m_game
->m_gridFocusX
;
274 int prevGridFocusY
= m_game
->m_gridFocusY
;
275 m_game
->m_gridFocusX
= x
;
276 m_game
->m_gridFocusY
= y
;
277 RefreshField(prevGridFocusX
, prevGridFocusY
,
278 prevGridFocusX
, prevGridFocusY
);
285 void BombsCanvas::OnChar(wxKeyEvent
& event
)
287 int keyCode
= event
.GetKeyCode();
288 int prevGridFocusX
= m_game
->m_gridFocusX
;
289 int prevGridFocusY
= m_game
->m_gridFocusY
;
291 const int gridWidth
= m_game
->GetWidth();
292 const int gridHeight
= m_game
->GetHeight();
298 m_game
->m_gridFocusX
++;
299 if (m_game
->m_gridFocusX
>= gridWidth
) m_game
->m_gridFocusX
= 0;
303 m_game
->m_gridFocusX
--;
304 if (m_game
->m_gridFocusX
<0) m_game
->m_gridFocusX
= gridWidth
-1;
308 m_game
->m_gridFocusY
++;
309 if (m_game
->m_gridFocusY
>= gridHeight
) m_game
->m_gridFocusY
= 0;
313 m_game
->m_gridFocusY
--;
314 if (m_game
->m_gridFocusY
<0) m_game
->m_gridFocusY
= gridHeight
-1;
318 if ( (prevGridFocusX
== m_game
->m_gridFocusX
)
319 && (prevGridFocusY
== m_game
->m_gridFocusY
)
320 && (m_game
->IsHidden(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
)) )
322 m_game
->Mark(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
323 if (!m_game
->IsMarked(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
))
325 Uncover(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
327 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
328 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
337 if ((prevGridFocusX
!= m_game
->m_gridFocusX
)
338 || (prevGridFocusY
!= m_game
->m_gridFocusY
))
340 // cause focused field to be visible after first key hit after launching new game
341 if( m_game
->m_gridFocusX
< 0 ) m_game
->m_gridFocusX
= 0;
342 if( m_game
->m_gridFocusY
< 0 ) m_game
->m_gridFocusY
= 0;
344 // refresh previous field and focused field
345 RefreshField(prevGridFocusX
, prevGridFocusY
,
346 prevGridFocusX
, prevGridFocusY
);
347 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
348 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);