@@ -2,6 +2,7 @@ package layout
22
33import (
44 "fmt"
5+ "image"
56 "image/color"
67
78 "github.com/hajimehoshi/ebiten/v2"
@@ -15,14 +16,16 @@ const (
1516 gridSize = 32
1617 Rows = 10
1718 Cols = 10
18- PanelHeight = 36 // 上方面板高度
19- PaddingX = 140 // 面板內文字左邊距
20- PaddingY = 20 // 面板
19+ PanelHeight = 36 // 上方面板高度
20+ PaddingX = 32 // 面板內文字左邊距
21+ PaddingY = 20 // 面板
2122 ScreenHeight = PanelHeight + gridSize * Rows
2223 ScreenWidth = gridSize * Cols
2324 MineCounts = 9
2425)
2526
27+ var buttonRectRelativePos = image .Rect (0 , 0 , 32 , 32 ) // 一個方格大小的 button
28+
2629type Coord struct {
2730 Row int
2831 Col int
@@ -37,6 +40,16 @@ func NewGameLayout(gameInstance *game.Game) *GameLayout {
3740}
3841
3942func (g * GameLayout ) Update () error {
43+ // 偵測 restart icon 有被點擊
44+ if ebiten .IsMouseButtonPressed (ebiten .MouseButtonLeft ) {
45+ xPos , yPos := ebiten .CursorPosition ()
46+ if xPos >= ((ScreenWidth - 1.5 * gridSize )/ 2 + buttonRectRelativePos .Min .X ) &&
47+ xPos <= (ScreenWidth )/ 2 + buttonRectRelativePos .Max .X + 0.5 * gridSize &&
48+ yPos >= buttonRectRelativePos .Min .Y &&
49+ yPos <= buttonRectRelativePos .Max .Y + 3 {
50+ g .Restart ()
51+ }
52+ }
4053 // 當狀態為遊戲結束
4154 if g .gameInstance .IsGameOver || g .gameInstance .IsPlayerWin {
4255 return nil
@@ -207,61 +220,94 @@ func (g *GameLayout) drawBoard(screen *ebiten.Image) {
207220 }
208221}
209222
210- // drawRemainFlag
211- func (g * GameLayout ) drawRemainFlag (screen * ebiten.Image ) {
212- status , bgColor := g .getColorStatus ()
223+ // drawGamePanel - 繪製遊戲狀態面板
224+ func (g * GameLayout ) drawGamePanel (screen * ebiten.Image ) {
225+ emojiIcon , bgColor := g .getColorStatus ()
213226 panel := ebiten .NewImage (ScreenWidth , PanelHeight )
214227 panel .Fill (bgColor )
215228 screen .DrawImage (panel , nil )
216- // 畫旗子面板(固定在上方)
217- textValue := fmt .Sprintf ("Flags: %d/%d, Status: %s" , g .gameInstance .Board .GetRemainingFlags (), MineCounts , status )
218- textXPos := PaddingX
229+ // 畫旗子面板(固定在左方)
230+ g .drawRemainingFlagInfo (screen )
231+ // 畫顯示狀態 button
232+ g .drawButtonWithIcon (screen , emojiIcon )
233+ }
234+
235+ // drawButtonWithIcon - 繪製 buttonIcon
236+ func (g * GameLayout ) drawButtonWithIcon (screen * ebiten.Image , emojiIcon string ) {
237+ vector .DrawFilledRect (screen ,
238+ float32 ((ScreenWidth - 1.5 * gridSize )/ 2 + buttonRectRelativePos .Min .X ),
239+ float32 (buttonRectRelativePos .Min .Y ),
240+ float32 (buttonRectRelativePos .Dx ()+ 0.5 * gridSize ),
241+ float32 (buttonRectRelativePos .Dy ()+ 3 ),
242+ color.RGBA {120 , 120 , 120 , 255 },
243+ true ,
244+ )
245+ vector .DrawFilledCircle (screen , ScreenWidth / 2 , gridSize / 2 , 16 ,
246+ color.RGBA {180 , 180 , 0 , 255 },
247+ true ,
248+ )
249+ emojiValue := emojiIcon
250+ emojiXPos := (ScreenWidth ) / 2
251+ emojiYPos := PaddingY
252+ emojiOpts := & text.DrawOptions {}
253+ emojiOpts .ColorScale .ScaleWithColor (getTileColor (IsButtonIcon ))
254+ emojiOpts .PrimaryAlign = text .AlignCenter
255+ emojiOpts .SecondaryAlign = text .AlignCenter
256+ emojiOpts .GeoM .Translate (float64 (emojiXPos ), float64 (emojiYPos ))
257+ text .Draw (screen , emojiValue , & text.GoTextFace {
258+ Source : emojiFaceSource ,
259+ Size : 32 ,
260+ }, emojiOpts )
261+ }
262+
263+ // drawRemainingFlagInfo
264+ func (g * GameLayout ) drawRemainingFlagInfo (screen * ebiten.Image ) {
265+ // 畫旗子面板(固定在左方)
266+ textValue := fmt .Sprintf ("%03d" , g .gameInstance .Board .GetRemainingFlags ())
267+ textXPos := PaddingX + len (textValue )
219268 textYPos := PaddingY
220269 textOpts := & text.DrawOptions {}
221270 textOpts .ColorScale .ScaleWithColor (getTileColor (- 1 ))
222- textOpts .PrimaryAlign = text .AlignCenter
271+ textOpts .PrimaryAlign = text .AlignStart
223272 textOpts .SecondaryAlign = text .AlignCenter
224273 textOpts .GeoM .Translate (float64 (textXPos ), float64 (textYPos ))
225274 text .Draw (screen , textValue , & text.GoTextFace {
226275 Source : mplusFaceSource ,
227276 Size : 20 ,
228277 }, textOpts )
278+ emojiValue := "🚩"
279+ emojiXPos := len (emojiValue )
280+ emojiYPos := PaddingY
281+ emojiOpts := & text.DrawOptions {}
282+ emojiOpts .ColorScale .ScaleWithColor (getTileColor (- 1 ))
283+ emojiOpts .PrimaryAlign = text .AlignStart
284+ emojiOpts .SecondaryAlign = text .AlignCenter
285+ emojiOpts .GeoM .Translate (float64 (emojiXPos ), float64 (emojiYPos ))
286+ text .Draw (screen , emojiValue , & text.GoTextFace {
287+ Source : emojiFaceSource ,
288+ Size : 20 ,
289+ }, emojiOpts )
229290}
230291
231292func (g * GameLayout ) Draw (screen * ebiten.Image ) {
232293 g .drawBoard (screen )
233- g .drawRemainFlag (screen )
234- if g .gameInstance .IsGameOver {
235- g .drawCoverOnGameOver (screen )
236- }
294+ g .drawGamePanel (screen )
237295}
238296
239297func (g * GameLayout ) Layout (outsideWidth , outsideHeight int ) (int , int ) {
240298 return ScreenWidth , ScreenHeight
241299}
242300
243- // drawCoverOnGameOver - 畫出無法操作的灰色遮罩
244- func (g * GameLayout ) drawCoverOnGameOver (screen * ebiten.Image ) {
245- w , h := ScreenWidth , ScreenHeight - PanelHeight
246- vector .DrawFilledRect (
247- screen ,
248- 0 , PanelHeight , // x, y
249- float32 (w ), float32 (h ), // width, height
250- color.RGBA {0 , 0 , 0 , 128 }, // 半透明黑色 (128 = 約 50% 透明)
251- false ,
252- )
253- }
254-
255301// getColorStatus - 根據 IsGameOver 與 IsPlayerWin 來找出對 message, bgColor
256302func (g * GameLayout ) getColorStatus () (string , color.RGBA ) {
257303 bgColor := color.RGBA {100 , 100 , 0x10 , 0xFF }
258- status := "playing "
304+ status := "😀 "
259305 if g .gameInstance .IsGameOver {
260- status = "game over "
306+ status = "😵 "
261307 bgColor = color.RGBA {150 , 0 , 0x10 , 0xFF }
262308 }
263309 if g .gameInstance .IsPlayerWin {
264- status = "you win "
310+ status = "😎 "
265311 bgColor = color.RGBA {200 , 200 , 0 , 0xFF }
266312 }
267313 return status , bgColor
@@ -281,3 +327,8 @@ func (g *GameLayout) handlePositionClickEvent(listenHandler func(row, col int))
281327 }
282328 }
283329}
330+
331+ // Restart - 重新建立 Game 狀態
332+ func (g * GameLayout ) Restart () {
333+ g .gameInstance = game .NewGame (Rows , Cols , MineCounts )
334+ }
0 commit comments