有没有玩过数独游戏呢,听说,它是一个能训练大脑思维的棋盘类游戏,游戏规则很简单,通过小程序来实现很容易,非常适合对数独游戏逻辑感兴趣的同学,选择它开发入门吧。
准备
- 会使用微信开发者工具,
- 有JavaScript编程和Canvas绘制基础,
- 最好有了解学习过Vue
首先,没有玩过数独的同学,请看一下,数独游戏规则如下
- 独一无二,
-
- 一个数独自占用一块地盘,其周边不能再出现这个数,
-
- 规定在一个宫格(3x3)内(地盘),不能有两个相同的数,
- 消除影响,
-
- 在整个大网格中,横向或纵向方向不能存在两个相同的数,
- 稳操胜算,
-
- 把网格留下的空白全部填充完,这样地盘就稳了,算游戏攻关。
创建小程序
打开微信开发者工具,开始创建小程序,最后点确定,如下图
注意选择
- 小程序
- 不使用云服务
- JavaScript 基础模板
第一页
接下来,开始写第一个页面,文件位置在/pages/index/index.wxml
,
打开文件续写,加上一个表单组件,选择游戏难度和按钮,布局页面如下图所示
点击开始游戏按钮,可进入游戏页面,
第一个页面对应的index.js
文件逻辑不难写,
相信初学者会自己做出来,这里不做详细说明
第二页
这里再创建一个第二个页面,为游戏页面,文件位置在/pages/game/game.wxml
,
如下图,要做的页面是这样的
游戏页面布局,用一个canvas画布,显示元素和一些底部选择按钮
游戏逻辑
先从加载游戏的方法中处理,初始化canvas游戏地图,再实现触摸操作,最后就是处理游戏判断逻辑的
初始化
要知道,小程序页面的生命周期,就是说页面的一些回调函数(方法),
页面打开时,系统调用顺序是先调用onLoad()
,再调用onReady()
的,
选择在合适的时机,去处理游戏逻辑,实现代码如下
Page({
/**
* 页面的初始数据
*/
data: {
timeNum:0,//计数
keys:['1','2','3','4','5','6','7','8','9','清除'],//选择的按键
activeIndex:0,//选中值
rank:0,//游戏难度
isEnd:false,//是否结束游戏
//...
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
//...处理从第一页传来的参数游戏难度
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
wx.createSelectorQuery().select('#'+canvasId).fields({
size:true, node:true
},res=>{
const { width, height, node } = res;
//...省略了
//初始化网格数据(棋盘)
this.initGrid();
//重新绘制方法
this.redraw();
//定时更新计数器
this.data.timer = setInterval(()=>{
//...
this.data.timeNum++
this.setData({
timeNum:this.data.timeNum
});
},1000)
}).exec()
},
unLoad(){
//...关闭定时器
}
//...
}
上面用到了两个方法,这里会讲一下,
初始化网格方法是initGrid()
,这里实现绘制游戏地盘,参考如下代码
initGrid(){
const { width, height, context:ctx } = this.data.canvas;
//...
let grids = [];
//获取初始值(地盘)的数据方法
const cols = 9;//9x9网格
let nums = this.getInitNumGrids();
let index = 0;
for(let r=0; r<cols; r++){
for(let c=0; c<cols; c++){
let num = nums[index++];
let g = {
//...网格数据
};
//...绘制网格
ctx.rect(g.left,g.top,gs,gs);
grids.push(g);
}
}
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 3;
for(let r=0; r<gs; r+=3){
//...绘制宫格(3x3)
}
ctx.stroke();
//设置一些值
Object.assign(this.data.canvas, { cols, gs, grids });
//将绘制的棋盘背景缓存,下次会用到
this.data.bgImg = ctx.getImageData(0,0,width,height);
},
上面还用到了方法
getInitNumGrids()
是可以自己定义的,相当于游戏的背景数据,包括了初始化的一些数字,可用于增加可选择游戏关卡和难度,这里就不做说明了
重绘方法是redraw()
,实现刷新游戏的显示逻辑,参考如下代码,看着很简单
redraw(){
const { gs, grids, context:ctx, width, height } = this.data.canvas;
//...省略了逻辑,先清除画布
//绘制前,把之前缓存的背景图画出来
ctx.putImageData(this.data.bgImg,0,0);
const r = gs/2;
//...省略了逻辑,设置画笔大小和颜色,再绘制网格
grids.forEach(g=>{
//...省略了逻辑,判断有数字就绘制出来
if(g.num) ctx.fillText(g.num,g.left+r,g.top+r*1.3);
});
},
触摸操作
游戏地盘绘制逻辑写好了后,接下来需要完善触摸操作,
绑定在画布canvas的开始触摸方法是onTouchStart(e)
,这里处理游戏的交互,实现对用户触摸操作的反馈,代码如下
Page({
//...
onTouchStart(e){
if(this.data.isEnd) return;
const touch = e.touches[0];
const { gs, grids } = this.data.canvas;
//根据触摸位置计算找出位置所在的网格
let grid = this.findGrid(grids,touch);
//选择的按键
let activeBtn = this.data.keys[this.data.activeIndex];
let isReraw;
//判断按键
switch (activeBtn){
case '清除':
//...清除网格中的数字
break;
default:
if (grid.num==undefined) {
//判断规则,返回存在相同的网格(数)
let scopes = this.scanGridsToScopes(grid,activeBtn);
if (scopes.length<1){
//...省略了,如果不存在相同的数,就继续绘制
isReraw=true;
}
else{
//...省略了,如果存在相同的数,就把数字染成红色,提醒用户
this.redraw();
//设一个延迟处理
this.data.timer2 = setTimeout(()=>{
this.data.timer2 = undefined;
//...到时,将数字恢复原色
this.redraw();
},1000);
}
}
}
if(isReraw) {
this.redraw();
//查找网格是否还存在空位
let count = this.filterGrids();
//如果没有了,就判断通关,游戏结束
if(count<1){
this.data.isEnd=true;
wx.showModal({
title:'系统提示',
content:`游戏结束!耗时:${this.data.timeNum}s`,
confirmText:'重新开始',
success: (res) => {
//...
}
});
}
}
},
onClick(e){
//...处理用户点击按钮的逻辑
},
//...
}
其中方法
onClick(e)
是处理按钮点击的,
例如打开游戏帮助提示对话框,和点击数字按钮为选中状态,
很简单的,这里就不讲
判断规则
数独的游戏规则上面有开始讲了的,
这个方法是scanGridsToScopes(grid,activeBtn)
,实现有点儿复杂,大致讲一下
scanGridsToScopes(grid,activeBtn){
const { grids } = this.canvas;
let scan = function(g,x=0,y=0) {
//...省略了判断逻辑
return false;
};
//过滤方法判断
let scopes = grids.filter(g=>{
let exist = false;
if (g.num==activeBtn) {
//...
if(!exist) exist = scan(g);
if(!exist) exist = scan(g,3);
//...
}
return exist;
});
return scopes;
}
JavaScript基础必掌握的
filter()
,是数组(列表)的按条件过滤方法,
主要是多次调用scan()
方法来判断,把一个网格周围不同方向的扫描一遍,这样实现对游戏规则的判断
运行测试
讲到这里,整个独数游戏的逻辑就算写完了,看看写得代码不是很多吧,那游戏的实现思路是否清晰了呢,
最后编译运行,运行时游戏效果图如下,
显示绿色的数字是填入的数字,
显示红色的数字提示玩家这里有相同数字,是不允许再填入的,
底部的一排数字键是选择键,可以选择填入哪个数字,或清除,
把所有空白填完就算攻关,
看着很像解密游戏,适合一个人玩,这游戏太烧脑,一般人玩不了!
关于项目
这个游戏逻辑实现过程是很简单的,想要学习微信小程序开发的新手同学,可以试试入手,
想看项目源码,请前往点这里找,其中有个名称叫数独游戏,项目源码完整,请放心下载,多谢支持!
若觉得有帮助,请记得点个赞,表示认可,
如有遇到问题请留言,作者有空会回复哦!