微信小程序之斗地主记牌器

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

});

}

});