iT邦幫忙

2025 iThome 鐵人賽

DAY 10
2

🎯 主題

當盤面已無空格且無法合併,判定遊戲結束。
這是 2048 遊戲的重要終止條件,能讓玩家在無法再進行任何動作時,看到明確的「Game Over」提示。

📝 開發目標

  • 檢查盤面空格:判斷是否還有 0(代表空格)。
  • 檢查是否可合併:檢查每一格是否有相鄰的相同數字(上下左右)。
  • 觸發 Game Over 狀態:若上述兩條件都不滿足,將 isGameOver = true。
  • 在畫面上顯示提示:當遊戲結束時,在畫布中央顯示 "Game Over" 文字。
  • 在畫面上顯示: 可以重新開始的 button 區塊 ,例如顯示 restart 的方塊

🧩 核心邏輯

  1. 檢查是否有空格
// hasEmptyTile - 判斷是否還有可移動的位置
func (g *Game) hasEmptyTile() bool {
	for row := 0; row < sideSize; row++ {
		for col := 0; col < sideSize; col++ {
			if g.board[row][col] == 0 {
				return true
			}
		}
	}

	return false
}
  1. 檢查是否可合併
// canMerge 判斷是否有可以合併的 tiles
func (g *Game) canMerge() bool {
	for row := 0; row < sideSize; row++ {
		for col := 0; col < sideSize; col++ {
			if col < sideSize-1 && g.board[row][col] == g.board[row][col+1] {
				return true
			}
			if row < sideSize-1 && g.board[row][col] == g.board[row+1][col] {
				return true
			}
		}
	}

	return false
}
  1. 判斷遊戲是否結束
// IsGameOver - 判斷遊戲是否無法繼續
func (g *Game) IsGameOver() bool {
	return !g.hasEmptyTile() && !g.canMerge()
}
  1. 在 Ebiten 畫面顯示 Game Over
func (g *GameLayout) Draw(screen *ebiten.Image) {
	// 背景色
	screen.Fill(color.RGBA{250, 248, 239, 255})
	// 畫出目前局面
	g.drawBoard(screen)
	// 當 gameOver 顯示 GameOver
	if g.isGameOver {
		g.drawGameOver(screen)
	}
}

由於版面不足,所以其他相關的繪圖邏輯可以在 github 上作搜尋查看

  1. 在 Update 中觸發判斷
// Update - 用來處理畫面偵測,與使用者互動,並且觸發狀態變更
func (g *GameLayout) Update() error {
	// 判斷是否遊戲結束
	if g.isGameOver {
		// 處理 restart 邏輯
		g.handleRestartGame()
		return nil
	}
	// 根據輸入產生對應的更新
	g.handleInput()

	// 根據目前的盤面跟更新是否能夠繼續執行
	if g.gameInstance.IsGameOver() {
		g.isGameOver = true
	}
	return nil
}

處理 restart 的判定如下

// handleRestartGame - 偵測目前 restart button
func (g *GameLayout) handleRestartGame() {
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
		x, y := ebiten.CursorPosition()
		if restartButtonRect.Min.X <= x && x <= restartButtonRect.Max.X &&
			restartButtonRect.Min.Y <= y && y <= restartButtonRect.Max.Y {
			g.restartGame()
		}
	}
}

// restartGame - 重設目前遊戲狀態
func (g *GameLayout) restartGame() {
	g.gameInstance.InitGame()
	g.isGameOver = false
}

執行結果

https://ithelp.ithome.com.tw/upload/images/20250824/20111580WRdsQl1waJ.png

Github action 測試

https://github.com/leetcode-golang-classroom/2048-game/actions/runs/17177641085/job/48735744708

✅ 驗收條件

  • 當盤面沒有空格且四個方向都無法再合併時,遊戲顯示 "Game Over" 文字。
  • 遊戲在 Game Over 後不再響應滑動。
  • 可保留棋盤內容供玩家查看。

📌 本日收穫

  • 學會用 空格檢查 + 合併檢查 判斷遊戲終止。
  • 完成 遊戲狀態管理,能鎖住畫面避免額外輸入。
  • 在 Ebiten 中動態繪製提示訊息。

🔮 明日預告

Day 11 — You Win 的顯示勝利條件

  • 當已經產生 2048 格子時,顯示 You Win 字樣
  • 並且顯示出繼續遊戲的選項

上一篇
2048 遊戲: 鍵盤控制滑動 + 整合更新邏輯
下一篇
2048 遊戲: You Win 的顯示勝利條件
系列文
在 ai 時代 gopher 遊戲開發者的 30 天自我養成20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言