iT邦幫忙

2025 iThome 鐵人賽

DAY 15
2

前言

今天我們要開始實作踩地雷遊戲的第一步:繪製格子方格。
踩地雷遊戲的核心畫面就是一個由多個小格子組成的棋盤,因此先把格子畫出來是後續功能的基礎。

今日目標

  • 使用 Ebiten 繪製一個固定大小的棋盤
  • 每個格子在初始狀態下都是「未揭開」的方格
  • 格子以網格形式排列整齊

驗收條件

✅ 畫面正確顯示一個棋盤
✅ 棋盤格子為「未揭開」狀態(例如灰色方格)
✅ 所有格子排列整齊,形成網格

程式碼實作

以下示範一個 10x10 棋盤,每個格子大小為 32x32:

const (
	gridSize     = 32
	Rows         = 10
	Cols         = 10
	ScreenWidth  = gridSize * Rows
	ScreenHeight = gridSize * Cols
	MineCounts   = 9
)

type GameLayout struct {
	gameInstance *game.Game
}

func NewGameLayout(gameInstance *game.Game) *GameLayout {
	return &GameLayout{gameInstance: gameInstance}
}
func (g *GameLayout) Update() error {
	return nil
}

// drawUnTouchCell - 畫出沒有被掀開的格子
func (g *GameLayout) drawUnTouchCell(screen *ebiten.Image, row, col int) {
	vector.DrawFilledRect(
		screen,
		float32(row*gridSize),
		float32(col*gridSize),
		gridSize-1,
		gridSize-1,
		color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
		false,
	)
}

func (g *GameLayout) Draw(screen *ebiten.Image) {
	for row := 0; row < Rows; row++ {
		for col := 0; col < Cols; col++ {
			// 取出格子狀態
			cell := g.gameInstance.Board.GetCell(row, col)
			// 當格子沒有被掀開時,畫出原本的灰階
			if !cell.Revealed {
				g.drawUnTouchCell(screen, row, col)
			}
		}
	}
}

func (g *GameLayout) Layout(outsideWidth, outsideHeight int) (int, int) {
	return ScreenWidth, ScreenHeight
}

主程式執行

func main() {
	ebiten.SetWindowSize(layout.ScreenWidth, layout.ScreenHeight)
	ebiten.SetWindowTitle("Mine Sweeper Grid")
	gameInstance := game.NewGame(layout.Rows, layout.Cols, layout.MineCounts)
	gameLayout := layout.NewGameLayout(gameInstance)
	if err := ebiten.RunGame(gameLayout); err != nil {
		log.Fatal(err)
	}
}

執行後畫面會顯示一個完整的方格棋盤,每個小方格代表一個地雷區塊,目前狀態都是「未揭開」。

執行畫面

https://ithelp.ithome.com.tw/upload/images/20250829/20111580jqrV5yWVTJ.png

驗收條件

  • 畫面正確顯示棋盤網格
  • 所有格子都是「未揭開」的灰色

本日收穫

  • 畫面正確顯示棋盤網格
  • 所有格子都是「未揭開」的灰色

明日預告

明天我們將加入滑鼠點擊事件,讓玩家可以實際點選格子,為後續的「揭開格子」或「插旗子」功能鋪路


上一篇
踩地雷遊戲: 隨機布雷與周圍雷數計算
下一篇
採地雷遊戲:格子揭開與空白區域擴散揭開
系列文
在 ai 時代 gopher 遊戲開發者的 30 天自我養成20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言