【飞行棋】多人游戏-微信小程序开发流程详解

可曾记得小时候玩过的飞行棋游戏,是90后的都有玩过吧,现在重温一下,这是一个可以二到四个人参与的游戏,通过投骰子走棋,一开始靠运气,后面还靠自己选择,谁抢占先机才能赢,还可以和小伙伴们一起玩,狭路相逢勇者胜,可谓趣味多多。

文章目录

  • 创建小程序
  • 开始页面
  • 游戏页面
  • 游戏逻辑
    • 画棋盘
    • 画棋子
    • 投骰子
    • 游戏规则
      • 1. 投骰子
      • 2. 移动棋子
      • 3. 选择棋子
  • 测试游戏
  • 关于项目

创建小程序

打开电脑上的微信开发工具,如下图所示,新建一个小程序项目
新建微信小程序

例如,项目名称为flying-chess,依次选择

  • 小程序
  • 不使用云服务
  • 使用JavaScript - 基础模板

开始页面

新建的项目中,系统有自动创建的第一个页面,文件在/pages/index/index.wxml,就在这里添加布局,

考虑到游戏可视情况选择几人玩,要在布局里添加表单组件,让用户选择,

然后点击开始游戏即可,显示结果如下图所示
在这里插入图片描述

在对应的index.js逻辑文件里,添加开始游戏按钮点击事件,
在事件方法里写上代码调用系统的API如下,可打开游戏页面:
wx.navigateTo({ url:"/pages/game/game", ... }) 还需要把用户选择的数据传过去;

游戏页面

接下来,新建一个文件夹game,建一个游戏页面,文件名都是game

在文件/pages/game/game.wxml中,添加游戏页面的布局,代码如下

<view class="game-panel"><image class="canvas" src="{{bgImg}}" /><view class="float-panel id{{index}} {{index==current ? 'active' : ''}}" wx:for="{{toasts}}" wx:key="index"><view class="title"><text>{{item}}</text></view></view><canvas class="canvas" id="canv" type="2d" disable-scroll="true" bindtouchstart="onTouchStart"></canvas>
</view>
<!-- 这里显示游戏底部的布局 --></view>
</view>

游戏页面上只用了一个canvas画布组件,一个背景图片,一个float-panel类的视图层显示数据,都是层层叠放显示的

游戏逻辑

就在game.js文件里写游戏逻辑,当页面加载渲染完成时,系统会调用其中的方法onReady(),就在这里开始写,先获取canvas组件的数据,

画棋盘

实现画棋盘的逻辑并不复杂的,可以这么做,先用canvas绘制好网格,然后在对应的格子上绘制各种图案就可以,

就像平时用电脑办公的表格制作软件Excel,单元格可以合并的,如下图所示,
在这里插入图片描述

画棋盘的代码放在项目里的一个/utils/game-map.js文件中,作为模块来用

需要用模块的时候,用import导入一下这个模块文件,看如下代码

import GameMap from '../../utils/game-map.js';Page({/*** 页面的初始数据*/data: {bgImg: '',//显示背景图片isAnimaging: false,//是否在动画中isNewAir: false,//是否再加棋子(派新飞机)toasts: ['x4', 'x4', 'x4', 'x4'],//飞机场显示的信息current: 0,//允许哪个玩家操作,默认第一个玩家(1号)currentColor: 'none',//设置游戏地图底部的控件背景颜色isSelectMode: false,//如果一个玩家派出多个棋子,会进入选择棋子状态isEndGame: false,//是否结束游戏},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {//获取canvas组件的数据wx.createSelectorQuery().select('#canv').fields({size: true,node: true}, res => {//...省略了//这里设置canvas组件的节点和绘制APIthis.canvasData = {canvas: res.node,context: res.node.getContext('2d')};//获取底部控件对象 组件 将用来操作this.ctrlPanel = this.selectComponent('#ctrl-panel');//初始化棋盘this.initChessPanel();//...省略了}).exec()},

从上面代码看出来了,调用方法initChessPanel()就可以绘制游戏地图,来看看怎么实现的呢

//设置初始游戏数据
const initGameData = {bgColor: '#55A3FF',//棋盘背景色preCurrentUid: -1,//上一个玩家id,-1表示没有
};
//用不同的四个颜色分别表示四个玩家的棋子
const initUserList = ['#E60116', '#FFC700', '#0277A8', '#08983F'].map((color, i) => {return {chessColor: color,//棋子颜色isJoin: this.joinUsers.indexOf(i) >= 0,//是否加入};
});
//这里调用模块文件game-map.js的GameMap地图对象,把上面的配置数据传入即可
const map = new GameMap(this.canvasData, initUserList, initGameData);
//调用地图对象的绘制地图上所有格子的方法,格子就是棋子的位置,生成图片数据
let bgImg = map.drawMapGrids();
let current = this.data.current;
//设置好地图数据,将来用到
this.gameData = map.gameData;
//更新显示到页面
this.setData({bgImg,//把地图显示到背景中currentColor: this.gameData.userlist[current].chessColor,gameToast: `${current + 1}号玩家点击投骰子`
});
//省略了...

棋盘上各种颜色都是可以替换的,例如到了晚上,背景就显示漆黑的夜空;
其中GameMap是一个游戏地图对象,在模块文件中有实现绘制地图,能给出坐标
想想生活中用到的地图导航,作用一样的,
其中的joinUsers是从开始页面传来的数据,表示有哪些玩家加入游戏

把画好的棋盘生成一个图片数据,设置到背景图片组件中显示,

画出来后,效果如下图
在这里插入图片描述

画棋子

地图有了,再把所有棋子画出来,

开始玩的时候,棋子都是放在飞机场上的,每个玩家都有四个棋子,

在调用方法initChessPanel()里面继续写,代码如下,

//给地图设置棋子上的图像,就是飞机图片
map.setChessImg('/static/fly.png',()=>{//设置好,就可以绘制棋子了this.redraw();
});

然后调用方法redraw()去绘制所有棋子,代码如下

const { canvas, context: ctx } = this.canvasData;//canvas组件的数据
const { grids, userlist, size, chessImg } = this.gameData;//游戏的数据
const r = size / 2;//棋子半径
const { toasts } = this.data;//显示游戏状态的数据
//因为这是重绘方法 使用前先清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
//把参与的玩家的棋子全部画出来
userlist.forEach((user, uid) => {let chesses = [];//记录可以绘制的棋子user.chesses.forEach((chess, i) => {//这里判断一下棋子的状态,如没有隐藏,且棋子有指向棋盘上的坐标,就可以加到记录中if (chess.isHide!=true && chess.gridIndex >= 0) {//...省略了继续判断逻辑}});//绘制棋子的chesses.forEach((chess, i) => {let g = grids[chess.gridIndex];//...省略了//绘制棋子的方法this.drawChessAtLocation(user, g);//判断棋子的数量,这是在同一个坐标上被叠放的棋子if (chess.count > 1) {let p = {//...};//给棋子画上数量标记ctx.fillText('' + chess.count, p.left, p.top);}});//判断这个玩家是否加入游戏if (user.isJoin) {//绘制玩家飞机场上的棋子user.chesses.forEach(chess => {if (chess.gridIndex < 0) {ctx.drawImage(chessImg, chess.left - r, chess.top - r, size, size);}});//更新玩家的信息toasts[uid] = `${uid + 1}号玩家`;} else {toasts[uid] = ``;}
});
//更新显示
this.setData({toasts
})

其中用到了方法drawChessAtLocation(user, g),这是实现在地图上画棋子的,只传入参数用户数据和格子坐标

把所有棋子画出来后, 效果图如下
在这里插入图片描述

投骰子

由于绘制投骰子动画会变得复杂,需要写很多代码,不如做一下布局,这样好弄点,省了不少代码吧,

就用控件组件来代替投骰子,控件组件放在棋盘的底部,在文件/pages/game/game.wxml中加上如下布局代码

<view><block wx:if="{{isEndGame}}"><text>{{gameToast}}</text></block><block wx:else><ctrl-panel id="ctrl-panel" isGameEnd="{{isGameEnd}}" isDisabled="{{isAnimaging || isSelectMode}}" bindstart="onClickStart" bgColor="{{currentColor}}"><text>{{gameToast}}</text></ctrl-panel></block><view>

这个组件ctrl-panel是放在别处的,也是自定义组件,需要的时候可以拿来直接用,用这个来选择操作再好不过了,

看看控件在游戏页面的布局显示效果,如下图
在这里插入图片描述

这控件不仅仅是用来投骰子哦,还有一些细节待发现

游戏规则

接下来,写到游戏规则了,实现过程会复杂一些,

再理清一下思路,想想应该怎么做才合适呢,

飞行棋的游戏规则大致是这样的,没有玩过的可以了解一下:

  • 棋子是顺时针方向走的,目的是走到自己颜色对应的飞机升降点;
  • 若投骰子投到6点,可以选择再拿一个棋子(派一个新飞机),然后再投骰子一次,让新飞机走;
  • 若走到自己对应颜色的一格,可以选择再走4步;
  • 若走到有连接线的一格,可以选择直接飞行,到对面的相同颜色一格;
  • 选择直接飞行时,如果中间的格子有遇到对手的棋子,就打回飞机场;
  • 棋子走到一格子上有自己的棋子,是可以叠放的,
  • 若是走到对手的棋子上就打回,如对手有叠放棋子,自己和对手的棋子就全部打回;
  • 棋子走到升降点中间最接近的一格子上就算游戏胜利;

按照飞行棋的游戏规则,实现游戏逻辑,觉得难不难呢,可以分三步实现,能把难度降低,

1. 投骰子

要移动棋子前,先投骰子,这部分靠运气,通过概率分配实现,

投骰子的逻辑在组件ctrl-panel中有实现,代码如下

// 取1~6之间的随机数
let num = Math.floor(Math.random()*6)+1;

可见Math的一些函数有经常用到

投完骰子后,组件ctrl-panel会传来事件,调用一个方法onClickStart(e)

是写到game.js里面的,代码如下,

const { stepNum } = e.detail;
//这里记录一下步数
this.stepNum = stepNum;
//记录玩家在棋盘中的所有棋子id
let indexes = [];
//...省略了
//定义走下一步的方法
let next = () => {//判断有没有派过新飞机,以及棋子有2个以上,让玩家先选择棋子再走if (this.isNewAir != true && indexes.length > 1) {this.setData({isSelectMode: true,//设置选择棋子状态gameToast: `${current + 1}号玩家选择棋子`});return;}//开始动画 看出棋子移动效果this.startAnimation(false, () => {//动画结束会执行到这里,判断一下是否派过新飞机了,重置一下状态if (this.isNewAir) this.isNewAir = false;});
};
//获取步数后,判断是否是6点,是的话,让用户选择是否再拿一个棋子(派新飞机)
if (stepNum == 6 && this.isNewAir != true && indexes.length > 0) {if (user.chessIndex >= 0) {//...省略了}//下一步next();return;
}
//没有就继续,下一步
next();

2. 移动棋子

获取步数后,就可以移动棋子了,调用的方法startAnimation(used, callback)

需要通过动画实现棋子一步一步走的效果,代码如下

const { current } = this.data;//表示当前的玩家id
const { grids, size, userlist } = this.gameData;//游戏数据
this.gameData.preCurrentUid = current;//记录到上一个
//省略了...
//获取步数
let num = this.stepNum;
//动画结束方法
let end = (index) => {//走完棋子,动画也就结束了,调用此方法处理一下this.endAnimation(chess, index, used, callback);
};
//下一步移动方法
let next = (i) => {//省略了...//棋子位置变了,重新画个棋子this.drawChess(user, d);//如果步数没走完,继续调用下一步方法setTimeout(() => next(i + 1), StepTimeMs);
};
//获取棋子在地图中指定位置上的格子数据
let d = grids[chess.gridIndex];
//判断是否到了自己开始升降的位置,nodes是升降点的地图数据
if (d.nodes && d.nodes[0].grid.cid == current) {//省略了...this.takeGridChess(user, () => {this.enterNextNode(user, chess, d.nodes, num, chess.nodeIndex);});return;
};
//调用带走的棋子方法
this.takeGridChess(user, () => next(1));

调用移动棋子的方法参数used, callback分别是是否使用过,动画结束时会回调,
其中方法takeGridChess()就是把正在移动的棋子拿走,然后重新绘制整个棋子,实现动画效果,
方法enterNextNode()就是在进入升降航道路线时才调用的

还有,动画结束需要处理的方法是endAnimation(chessi, index, used, callback)

这实现了棋子到目标格子上做出反应处理的逻辑,代码如下

const { current } = this.data;
const { userlist, grids, size } = this.gameData;
const user = userlist[current];
const chess = user.chesses[user.chessIndex];
const gridIndex = chess.gridIndex;
let end = () => {//...省略了//处理结束,更新一下显示数据this.setData({isAnimaging: false,gameToast: `${uid + 1}号玩家点击投骰子`});//重新绘制所有棋子this.redraw();//需要结束回调时 就回调if (callback instanceof Function) callback();
};
switch (gridIndex) {case 6:case 19://...{//执行到这里,说明是走到可以直线飞行的格子上,调用控件组件让玩家选择要不要直线飞行this.ctrlPanel.showSelectAirAtLineModal(res => {if (!res.confirm) {//没选择直线飞,就继续判断this.isBeatBackChess(gridIndex,current);end();return;}let i = 0;//直线飞行动画const next = () => {//...省略了i++;if(i>10) {//...省略了this.isBeatBackChess(chess.gridIndex, current, gridIndex + 6);end();return;}//...省略了setTimeout(next, 100);//0.1s移动一次};			this.takeGridChess(user, next);});return;}default:{//...省略了//调用判断是否碰到对方的棋子方法this.isBeatBackChess(chess.gridIndex, current);}
}
end();

3. 选择棋子

只有当玩家的飞机场里至少有两个都出发了,才是可以选择棋子的,

game.js里写,是canvas组件绑定是触摸事件方法onTouchStart(e),选择棋子的代码如下

if (this.data.isEndGame) return;//游戏结束时,不处理操作
const touch = e.touches[0];
const { userlist, grids, size } = this.gameData;
const { current, isSelectMode } = this.data;
// 获取正在操作的玩家数据
let user = userlist[current];
let chessIndex = user.chesses.findIndex((c, i) => {//...省略了
});
//判断是否选择到棋子
if (chessIndex >= 0) {//更新玩家选择的棋子user.chessIndex = chessIndex;//判断是否是选择状态,若是的话,就开始走棋动画if (isSelectMode) {this.startAnimation();}
}

测试游戏

就讲到这里,篇幅有限,上面都有讲了重点的,还有几个方法就不讲了,

可以看看项目源码,直接运行,看到有感觉,里面代码并不多,可以参考学习一下,

最后看一下飞行棋小程序的运行效果图,怎么样,可以吧
请添加图片描述

若想一起玩的人数不够4个,在开始页面上是可以选择人数的

请添加图片描述

三缺一,没事儿,让我的小伙伴们能一起玩就对了

关于项目

如果要看项目源码 请点这里看,在资源一栏下可以找到飞行棋的源码,放心下载,感谢支持!

如果是在手机上看会有可能找不到资源一栏,就在电脑浏览器上看,

喜欢的话,点个赞收藏吧,遇到什么不明白的地方请主动留言,作者看到会回复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38771.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏陪玩小程序开发制作

游戏陪玩小程序开发制作 该项目是一个线上下单线下陪玩项目&#xff0c;主要功能有游戏陪玩大神展示&#xff0c;陪玩大神入驻&#xff0c;用户预约陪玩大神&#xff0c;陪玩大神接单等功能。陪玩大神收益可以提现等功能。 主要功能有聊天室、和平精英陪玩、英雄联盟、绝地求…

微信小程序 | 游戏开发之接宝石箱子游戏

1、什么是微信小游戏 微信小游戏是小程序的一个类目&#xff0c;小游戏是微信开放给小程序的更多的能力&#xff0c;让小程序开发者有了开发游戏的能力。微信小游戏是在小程序的基础上添加了游戏库API。微信小游戏只能运行在小程序环境中&#xff0c;微信小游戏没有小程序中WX…

微信小程序| 做一款多人实时线上的五指棋联机游戏

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …

游戏陪玩小程序怎么开发-游戏陪玩小程序功能

目前游戏陪玩行业已经占据了很大的市场所在&#xff0c;拥有一款完善的陪玩软件可以帮助很多用户实现更好的实现游戏陪玩的寻找&#xff0c;当然开发陪玩小程序也是要注意很多方面。下面说一下如果开发和核心功能 如何开发&#xff1f; 开发无非就是几种 1、自己懂技术慢慢学…

Unity游戏上传到微信小程序

一、注册 地址&#xff1a; 微信小程序 补充信息&#xff08;类目需要选择游戏方面&#xff0c;不然后面调试不了&#xff09; - 注意AppID 二、下载插件 地址&#xff1a;Unity转微信小程序 三、转换项目 四丶 下载微信开发工具并导入项目 微信开发者工具 打包好会生…

微信小程序项目实例——2048小游戏

今日推荐&#x1f481;‍♂️ 第一次听廖俊涛的歌是他首次出现在明日之子舞台上的那首《谁》 到现在这首歌成了我网易云收藏的十几首歌中的一首&#xff0c;也是听的最多的一首 怎么形容呢&#x1f914;算不上惊艳&#xff0c;却百听不厌&#x1f442; &#x1f52e;&#x1…

蛋白互作常用的研究方法

蛋白质是生物功能最直接的执行者&#xff0c;虽然一些蛋白质可以独立的完成他的使命&#xff0c;但是大部分的蛋白都是需要一些伴侣分子的协助一起完成任务或者形成复合物之后才能充分发挥他的功能。所以&#xff0c;了解蛋白质与蛋白质之间的相互作用&#xff0c;能够帮助我们…

OpenAL联合创始人Ilya:你要与AI较劲吗?

AlexNet、AlphaGo、GPT、CLIP、DALL-E、Codex&#xff0c;一个个在AI界夺目闪耀&#xff0c;又影响深远的杰作&#xff0c;其背后都镌刻了一个人的名字。 在2012年博士毕业后的10年里&#xff0c;其论文被引次数超过25万次&#xff0c;领导开发了划时代的GPT系列&#xff0c;成…

改写中文句子的软件-修改文章句子的软件

免费语句改写软件 您是否在写博客、新闻稿或者其他需要大量文本的场合中觉得无从下手&#xff1f;您是否为修改一段语句上耗费大量时间感到困扰&#xff1f;如果您有这样的烦恼&#xff0c;那么我向您介绍我们的免费语句改写软件&#xff0c;可以帮助您快速批量语句改写&#x…

去中心化开源社交平台Misskey

本文是应网友 anthony084 的要求写的&#xff1b; 什么是 Misskey &#xff1f; Misskey 是一个开源、去中心化的社交媒体平台&#xff0c;发帖方式类似于微博和推特。 去中心化则意味着一个 Misskey 实例可以与其他 Misskey 实例进行相互连接&#xff0c;在 Fediverse (Activi…

讯图科技数据网关解决方案

一、方案定位&#xff1a; 一套高可用&#xff0c;支持高并发的数据服务分发系统&#xff1b;一套可配置的动态数据服务开发调试框架&#xff1b;整合alibaba spring cloud、dubbo&#xff0c;支持熔断、限流&#xff1b;可扩展定制go、C#、java开发SDK等。 二、系统架构图 三…

未来5年,生产力的底层逻辑变了,影响所有企业

上周&#xff0c;K哥带领20多位企业家、技术高管参访了阿里钉钉&#xff0c;学习AI大模型如何应用到企业生产经营和组织管理当中&#xff0c;以及企业如何使用新生产力工具实现降本增效。 通过这次参访&#xff0c;我对AI大模型如何驱动企业管理变革有了新的认识&#xff0c;三…

字节发年终奖了

❤️点击上方&#xff0c;选择星标或置顶&#xff0c;每天给你送上干货❤️ 作者 | godweiyang 出品 | 公众号&#xff1a;算法码上来&#xff08;ID&#xff1a;GodNLP&#xff09; - BEGIN - 好久没写文章了&#xff0c;上一次发文章还是2.14情人节了&#xff0c;一转眼两个多…

AIGC狂飙,能否成为娱乐社交应用的狂欢?

4 月 22 日&#xff0c;PMTalk 社交娱乐产品增长与运营新玩法线下沙龙在广州举行&#xff0c;网易云信娱乐社交行业解决方案专家姚柱围绕 AIGC 与娱乐社交玩法融合&#xff0c;分享了《AIGC 狂飙背后的娱乐社交产品趋势与实践》&#xff0c;以下为演讲整理实录。 目前&#xf…

干货篇:如何从 0 到 1 落地你的第一个开源项目?破局分享!

前言 大家好&#xff0c;我是 「周三不Coding」。最近马上就要到秋招提前批啦&#xff0c;相信很多小伙伴都在忙着复习八股文、刷算法题、准备简历中。 最近我也关注到了很多同学都在问一个问题&#xff0c;如何做一个自己的项目。 项目的重要性想必大家都清楚&#xff0c;如…

chatgpt赋能python:Python中让所有单词的首字母变成大写的SEO文章

Python中让所有单词的首字母变成大写的SEO文章 作为一种开源编程语言&#xff0c;Python已经在各个领域崭露头角。伴随着搜索引擎优化&#xff08;SEO&#xff09;的发展&#xff0c;Python也成为了一个极其有用的工具&#xff0c;尤其是当涉及到优化网站上的关键词时。 在本…

chatgpt赋能python:横向拼接图片在SEO中的作用

横向拼接图片在SEO中的作用 在现代网络环境中&#xff0c;图像搜索和视觉呈现在SEO中扮演了非常重要的角色。人们喜欢通过高质量的图像来寻找信息和生成视觉印象。对于像素比率和视觉呈现的好坏&#xff0c;图像品质是重中之重的。在这样的SEO环境中&#xff0c;对于那些希望通…

chatgpt赋能python:如何用Python开发安卓APP并进行SEO优化

如何用Python开发安卓APP并进行SEO优化 介绍 Python是一种著名的编程语言&#xff0c;由于其简洁性和功能强大性&#xff0c;Python被广泛应用于计算机科学和软件工程领域。不仅如此&#xff0c;Python还可以用于开发移动应用程序&#xff08;APP&#xff09;。 虽然Python是…

chatgpt赋能python:Python在SEO优化中的作用

Python在SEO优化中的作用 概述 Python是一种被广泛应用于各种领域的编程语言&#xff0c;包括数据科学、机器学习、Web开发等。近年来&#xff0c;Python在SEO&#xff08;搜索引擎优化&#xff09;中也扮演着重要的角色。Python的强大功能使得它成为一个很好的工具&#xff…

chatgpt赋能python:用Python写SEO工具

用Python写SEO工具 SEO&#xff08;Search Engine Optimization&#xff09;是指在网站设计、内容编写、关键词优化等方面&#xff0c;提高网站在搜索引擎中排名的一种策略。而随着Python编程语言的逐渐流行&#xff0c;我们可以利用Python编写一些SEO工具&#xff0c;帮助我们…