]>
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 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 msg
.Printf(wxT("%d bombs %d remaining cells"),
176 m_game
->GetNumBombs(), m_game
->GetNumRemainingCells() );
178 #if wxUSE_LOG && wxUSE_STATUSBAR
181 this->GetParent()->SetTitle(msg
);
185 // Refreshes the field image
186 // xc1,yc1 etc. are the (inclusive) limits of the area to be drawn,
187 // expressed in cells.
188 void BombsCanvas::RefreshField(int xc1
, int yc1
, int xc2
, int yc2
)
191 DrawField(& dc
, xc1
, yc1
, xc2
, yc2
);
195 memDC
.SelectObject(*m_bmp
);
196 DrawField(&memDC
, xc1
, yc1
, xc2
, yc2
);
197 memDC
.SelectObject(wxNullBitmap
);
201 // Called when uncovering a cell.
202 void BombsCanvas::Uncover(int x
, int y
)
205 RefreshField(x
, y
, x
, y
);
207 const int gridWidth
= m_game
->GetWidth();
208 const int gridHeight
= m_game
->GetHeight();
210 const bool hasWon
= m_game
->GetNumRemainingCells() == 0;
211 if (m_game
->IsBomb(x
,y
) || hasWon
)
216 wxMessageBox(wxT("Nice! You found all the bombs!"),
217 wxT("wxWin Bombs"), wxOK
|wxCENTRE
);
219 else // x,y is a bomb
221 m_game
->Explode(x
, y
);
224 for(x
=0; x
<gridWidth
; x
++)
225 for(y
=0; y
<gridHeight
; y
++)
227 RefreshField(0, 0, gridWidth
-1, gridHeight
-1);
229 else if (!m_game
->Get(x
, y
))
231 int left
= ( x
> 0 ) ? x
-1 : 0;
232 int right
= ( x
< gridWidth
- 1 )
235 int top
= ( y
> 0 ) ? y
-1 : 0;
236 int bottom
= ( y
< gridHeight
- 1 )
241 for (j
=top
; j
<=bottom
; j
++)
242 for (i
=left
; i
<=right
; i
++)
243 if ( (i
!= x
|| j
!= y
) && m_game
->IsHidden(i
, j
)
244 && !m_game
->IsMarked(i
, j
) )
251 // Called when the canvas receives a mouse event.
252 void BombsCanvas::OnMouseEvent(wxMouseEvent
& event
)
254 const int gridWidth
= m_game
->GetWidth();
255 const int gridHeight
= m_game
->GetHeight();
258 event
.GetPosition(&fx
, &fy
);
259 int x
= fx
/(m_cellWidth
*X_UNIT
);
260 int y
= fy
/(m_cellHeight
*Y_UNIT
);
261 if (x
<gridWidth
&& y
<gridHeight
)
263 if ( (event
.RightDown() || (event
.LeftDown() && event
.ShiftDown()))
264 && (m_game
->IsHidden(x
,y
)
265 || !m_game
->GetNumRemainingCells() ) )
267 // store previous and current field
268 int prevFocusX
= m_game
->m_gridFocusX
;
269 int prevFocusY
= m_game
->m_gridFocusY
;
270 m_game
->m_gridFocusX
= x
;
271 m_game
->m_gridFocusY
= y
;
272 RefreshField(prevFocusX
, prevFocusY
, prevFocusX
, prevFocusY
);
274 RefreshField(x
, y
, x
, y
);
277 else if (event
.LeftDown() && m_game
->IsHidden(x
,y
)
278 && !m_game
->IsMarked(x
,y
))
280 // store previous and current field
281 int prevGridFocusX
= m_game
->m_gridFocusX
;
282 int prevGridFocusY
= m_game
->m_gridFocusY
;
283 m_game
->m_gridFocusX
= x
;
284 m_game
->m_gridFocusY
= y
;
285 RefreshField(prevGridFocusX
, prevGridFocusY
,
286 prevGridFocusX
, prevGridFocusY
);
293 void BombsCanvas::OnChar(wxKeyEvent
& event
)
295 int keyCode
= event
.GetKeyCode();
296 int prevGridFocusX
= m_game
->m_gridFocusX
;
297 int prevGridFocusY
= m_game
->m_gridFocusY
;
299 const int gridWidth
= m_game
->GetWidth();
300 const int gridHeight
= m_game
->GetHeight();
306 m_game
->m_gridFocusX
++;
307 if (m_game
->m_gridFocusX
>= gridWidth
) m_game
->m_gridFocusX
= 0;
311 m_game
->m_gridFocusX
--;
312 if (m_game
->m_gridFocusX
<0) m_game
->m_gridFocusX
= gridWidth
-1;
316 m_game
->m_gridFocusY
++;
317 if (m_game
->m_gridFocusY
>= gridHeight
) m_game
->m_gridFocusY
= 0;
321 m_game
->m_gridFocusY
--;
322 if (m_game
->m_gridFocusY
<0) m_game
->m_gridFocusY
= gridHeight
-1;
326 if ( (prevGridFocusX
== m_game
->m_gridFocusX
)
327 && (prevGridFocusY
== m_game
->m_gridFocusY
)
328 && (m_game
->IsHidden(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
)) )
330 m_game
->Mark(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
331 if (!m_game
->IsMarked(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
))
333 Uncover(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
335 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
336 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);
345 if ((prevGridFocusX
!= m_game
->m_gridFocusX
)
346 || (prevGridFocusY
!= m_game
->m_gridFocusY
))
348 // cause focused field to be visible after first key hit after launching new game
349 if( m_game
->m_gridFocusX
< 0 ) m_game
->m_gridFocusX
= 0;
350 if( m_game
->m_gridFocusY
< 0 ) m_game
->m_gridFocusY
= 0;
352 // refresh previous field and focused field
353 RefreshField(prevGridFocusX
, prevGridFocusY
,
354 prevGridFocusX
, prevGridFocusY
);
355 RefreshField(m_game
->m_gridFocusX
, m_game
->m_gridFocusY
,
356 m_game
->m_gridFocusX
, m_game
->m_gridFocusY
);