1. 简介
斗地主是一款非常受欢迎的纸牌游戏,现在在微信小程序中也有斗地主游戏,而斗地主游戏中的一个非常重要的工具就是记牌器。本文将介绍如何编写一个简单的微信小程序斗地主记牌器。
2. 目标
在本文中,我们将编写一个小程序,实现以下目标:
实现一个记牌器,能够统计当前牌堆中各种牌的数量。
支持发牌时更新牌堆信息,以及游戏中玩家出牌时更新牌堆信息。
能够识别牌局中可能发生的错误,例如牌堆中已经缺少某种牌,但又从玩家出牌中发现该牌出现。
3. 开始编写
3.1 前置知识
在编写本小程序前,需要先了解微信小程序的基础知识,例如微信小程序的生命周期、组件、事件等。另外,了解编程语言 JavaScript 及基础的 DOM 操作也是必要的。
3.2 创建初始界面
首先,在微信开发者工具中创建一个新的小程序项目。接下来,在 app.json 文件中配置页面路由:
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarTitleText": "斗地主记牌器"
}
}
然后,在 index 目录下创建 index.wxml、index.wxss 和 index.js 文件。我们主要关注 index.wxml 文件:
<view class="container">
<view class="title">当前牌堆</view>
<view class="card-list">
<view class="card-item" wx:for="{{cards}}" wx:key="{{index}}">
<image src="/images/{{item}}.png" />
<view class="card-count">{{counts[item]}}</view>
</view>
</view>
</view>
这段代码主要是用于渲染牌堆信息。接下来,在 index.js 中准备好初始数据和渲染逻辑:
Page({
data: {
cards: ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'w', 'W'], // 牌堆包含的牌
counts: { // 初始时各个牌的数量均为 4
'A': 4,
'2': 4,
'3': 4,
// ...
'W': 4
}
}
});
最后,在 index.wxss 中设置样式,让界面看起来更美观:
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 28rpx;
font-weight: bold;
margin-top: 40rpx;
margin-bottom: 20rpx;
}
.card-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.card-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 10rpx;
width: 120rpx;
height: 200rpx;
border-radius: 8rpx;
background-color: #f5f5f5;
}
.card-item image {
width: 100rpx;
height: 140rpx;
margin-bottom: 10rpx;
}
.card-count {
font-size: 24rpx;
font-weight: bold;
color: #ff0000;
}
完成上述代码后,在开发者工具中预览,就能看到初始界面:
3.3 更新牌堆信息
接下来,我们需要实现更新牌堆信息的功能。为了方便实现,我们先在界面上添加一个“发牌”按钮,点击此按钮后随机生成一手牌并更新牌堆信息。修改 index.wxml 文件,添加以下代码:
<button bindtap="deal" class="btn">发牌</button>
然后,在 index.js 中添加 deal 函数:
deal: function() {
// 随机生成一手牌
var handCards = [];
for (var i = 0; i < 20; i++) {
handCards.push(this.data.cards[Math.floor(Math.random() * this.data.cards.length)]);
}
// 更新牌堆信息
var counts = Object.assign({}, this.data.counts);
for (var i = 0; i < handCards.length; i++) {
var card = handCards[i];
if (counts[card] > 0) {
counts[card]--;
} else {
// 牌出现异常,弹出提示
wx.showModal({
title: '出现异常',
content: '牌堆中已经缺少 ' + card + ',但又从玩家出牌中发现该牌出现。',
showCancel: false
});
return;
}
}
this.setData({
counts: counts
});
}
deal 函数中,首先随机生成一手牌。然后遍历该手牌,将牌堆中对应的牌的数量减一。如果牌堆中已经没有该种牌了,则弹出错误提示。最后,用 setData 函数更新界面。
此时我们再次预览页面,在点击“发牌”按钮后,牌堆信息会刷新为发牌后的状态。如果发牌时出现错误,也能正确提示。
3.4 更新牌堆信息 II
接下来,我们需要支持在游戏过程中玩家出牌时更新牌堆信息。为了方便起见,我们在界面上添加一个输入框和一个“出牌”按钮,玩家通过输入框输入出牌信息,点击“出牌”按钮后更新牌堆信息。修改 index.wxml 文件,添加以下代码:
<view class="card-form">
<input placeholder="请输入出牌信息" bindinput="input" />
<button bindtap="play" class="btn">出牌</button>
</view>
然后,在 index.js 中添加 input 和 play 函数:
input: function(e) {
this.setData({
currentCard: e.detail.value.toUpperCase()
});
},
play: function() {
// 获取当前出牌
var card = this.data.currentCard || '';
if (card === '') {
wx.showToast({
title: '出牌不能为空',
icon: 'none'
});
return;
}
// 更新牌堆信息
var counts = Object.assign({}, this.data.counts);
if (counts[card] > 0) {
counts[card]--;
} else {
// 牌出现异常,弹出提示
wx.showModal({
title: '出现异常',
content: '牌堆中已经缺少 ' + card + ',但又从玩家出牌中发现该牌出现。',
showCancel: false
});
return;
}
this.setData({
counts: counts
});
}
这里的 input 函数主要是用于获取当前输入框的值。play 函数中,首先获取当前的出牌。如果出牌为空,则弹出提示。否则,更新牌堆信息,并用 setData 函数更新界面。这样,玩家就可以在玩耍游戏时及时更新牌堆信息了。
至此,我们的小程序斗地主记牌器就编写完成了。完整代码如下:
<view class="container">
<view class="title">当前牌堆</view>
<view class="card-list">
<view class="card-item" wx:for="{{cards}}" wx:key="{{index}}">
<image src="/images/{{item}}.png" />
<view class="card-count">{{counts[item]}}</view>
</view>
</view>
<view class="card-form">
<input placeholder="请输入出牌信息" bindinput="input" />
<button bindtap="play" class="btn">出牌</button>
</view>
<button bindtap="deal" class="btn">发牌</button>
</view>
Page({
data: {
cards: ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'w', 'W'], // 牌堆包含的牌
counts: { // 初始时各个牌的数量均为 4
'A': 4,
'2': 4,
'3': 4,
'4': 4,
'5': 4,
'6': 4,
'7': 4,
'8': 4,
'9': 4,
'10': 4,
'J': 4,
'Q': 4,
'K': 4,
'w': 1,
'W': 1
},
currentCard: ''
},
input: function(e) {
this.setData({
currentCard: e.detail.value.toUpperCase()
});
},
deal: function() {
// 随机生成一手牌
var handCards = [];
for (var i = 0; i < 20; i++) {
handCards.push(this.data.cards[Math.floor(Math.random() * this.data.cards.length)]);
}
// 更新牌堆信息
var counts = Object.assign({}, this.data.counts);
for (var i = 0; i < handCards.length; i++) {
var card = handCards[i];
if (counts[card] > 0) {
counts[card]--;
} else {
// 牌出现异常,弹出提示
wx.showModal({
title: '出现异常',
content: '牌堆中已经缺少 ' + card + ',但又从玩家出牌中发现该牌出现。',
showCancel: false
});
return;
}
}
this.setData({
counts: counts
});
},
play: function() {
// 获取当前出牌
var card = this.data.currentCard || '';
if (card === '') {
wx.showToast({
title: '出牌不能为空',
icon: 'none'
});
return;
}
// 更新牌堆信息
var counts = Object.assign({}, this.data.counts);
if (counts[card] > 0) {
counts[card]--;
} else {
// 牌出现异常,弹出提示
wx.showModal({
title: '出现异常',
content: '牌堆中已经缺少 ' + card + ',但又从玩家出牌中发现该牌出现。',
showCancel: false
});
return;
}
this.setData({
counts: counts
});
}
});