1. 从零搭建双人对战五子棋
五子棋作为经典策略游戏,在微信小程序上实现其实比你想象的简单。我先带大家用最基础的方式实现双人对战版本,后续再逐步升级到智能AI对战。这个过程中你会发现,很多看似复杂的功能拆解后都是基础逻辑的组合。
棋盘绘制是小程序五子棋的第一步。我推荐使用flex布局配合背景图实现,这样既能保证视觉效果,又便于后续落子定位。具体实现时,用15x15的透明view矩阵覆盖在棋盘背景上,每个view的点击事件对应一个落子位置。实测下来,这种方案在各类机型上显示效果最稳定。
javascript复制// WXML部分
<view class="chessboard">
<view
wx:for="{{grids}}"
wx:key="index"
class="grid"
bindtap="onTap"
data-index="{{index}}"
/>
</view>
// JS初始化
Page({
data: {
grids: Array(225).fill('empty'), // 15x15棋盘
currentPlayer: 'black' // 当前执子方
}
})
落子逻辑的核心是三步:检查目标位置是否为空、更新棋盘状态、切换执子方。这里有个细节要注意,小程序setData的性能优化很重要。我遇到过棋盘卡顿的情况,后来发现是频繁触发渲染导致的。解决方案是合并数据更新:
javascript复制onTap(e) {
const index = e.currentTarget.dataset.index
if (this.data.grids[index] !== 'empty') return
// 使用临时变量减少setData调用
const newGrids = [...this.data.grids]
newGrids[index] = this.data.currentPlayer
this.setData({
grids: newGrids,
currentPlayer: this.data.currentPlayer === 'black' ? 'white' : 'black'
})
this.checkWin(index)
}
胜负判断是五子棋最易出bug的环节。常见错误包括边界判断遗漏、对角线检测错误等。我的经验是采用方向向量法:预先定义四个检测方向(水平、垂直、两对角线),每个方向正反扫描连续同色棋子。这样代码更简洁且不易出错:
javascript复制// 方向向量定义
const DIRECTIONS = [
[1, 0], // 水平
[0, 1], // 垂直
[1, 1], // 主对角线
[1, -1] // 副对角线
]
checkWin(index) {
const x = index % 15
const y = Math.floor(index / 15)
const color = this.data.grids[index]
for (const [dx, dy] of DIRECTIONS) {
let count = 1 // 当前落子已计1
// 正向检测
for (let i = 1; i < 5; i++) {
const nx = x + dx * i
const ny = y + dy * i
if (nx >= 15 || ny >= 15 || nx < 0 || ny < 0) break
if (this.data.grids[ny * 15 + nx] !== color) break
count++
}
// 反向检测
for (let i = 1; i < 5; i++) {
const nx = x - dx * i
const ny = y - dy * i
if (nx >= 15 || ny >= 15 || nx < 0 || ny < 0) break
if (this.data.grids[ny * 15 + nx] !== color) break
count++
}
if (count >= 5) {
this.showResult(color + '方胜利!')
return
}
}
}
2. 基础功能优化与体验提升
完成核心对战功能后,我们需要优化用户体验。首先是悔棋功能,这个看似简单,但实际开发时要注意状态管理的完整性。我采用栈结构记录落子历史,每次悔棋时弹出最近两步(黑白各一步):
javascript复制// 初始化历史栈
data: {
moveHistory: []
}
// 落子时记录
onTap(e) {
// ...原有逻辑...
this.data.moveHistory.push(index)
}
// 悔棋实现
undo() {
if (this.data.moveHistory.length < 2) return
const newGrids = [...this.data.grids]
// 弹出最后两步
const step1 = this.data.moveHistory.pop()
const step2 = this.data.moveHistory.pop()
newGrids
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容