【叠高高】叠蛋糕游戏的微信小程序开发流程详解
记得小时候玩过的搭积木游戏吗,和叠高高游戏原理差不多的,与之类似的还有盖高楼游戏,就是看谁盖的(叠的)最高,这里讲一下比较基础的叠高高游戏小程序实现过程,对编程感兴趣的同学可以参考学习一下,代码不会很多,非常值得入手研究学习哦。
打开微信开发工具,选择小程序,创建一个项目,
例如项目名称为
miniprogram-StackHigh
,然后选择以下,再确定创建
- AppID 使用自己的测试号
- 不使用云服务
- JavaScript - 基础模板
开始页面
要实现从开始页面跳转到游戏页面,
只需在文件/pages/index/index.js
里的onLoad()
方法中添加一段代码即可,代码如下
wx.navigateTo({url: '/pages/game/game',
})
游戏页面
在一个游戏页面文件/pages/game/game.wxml
中写,只需要一个canvas画布组件即可,布局如下
<view class="page"><canvas type="2d" id="canv" class="canvas" bindtouchstart="onTouchStart" bindtouchend="onTouchEnd"></canvas>
</view>
游戏逻辑
理清一下游戏逻辑,大致是这样,
需要一个钩子放在上面左右移动,同时带着方块,
当用户点击屏幕时,方块就会脱钩向下掉落,有惯性,会稍微偏移一点,
最好可以落到下面的方块上面,这样看着可以计算高度,
目标很简单,就是盖楼,叠高高,看谁的最高,
增加关卡难度,盖得越高,移动钩子越快
在一个游戏逻辑文件/pages/game/game.js
中开始写代码,
加载时
先写好,从页面加载完成时的onReady()
方法中去写获取canvas
组件,
然后绑定的触摸事件onTouchStart
和onTouchEnd
,代码如下
Page({/*** 生命周期函数--监听页面初次渲染完成*/onReady() {wx.createSelectorQuery().select('#canv').fields({ size: true, node: true }, res => {//...//设置到画布的数据this.canvasData = {canvas: res.node,ctx: res.node.getContext('2d'),};//初始化画布this.initCanvas();}).exec()},/*** 触摸开始事件*/onTouchStart(e) {//这里没关系,可不写任何代码},/*** 触摸结束事件*/onTouchEnd() {// 这里先判断 如果在动画进行中 或者 游戏已结束 就不继续处理if (this.isAnimining || this.isGameEnd) return;const { objBlock, objHook } = this.canvasData;// 判断 方块是否被钩子勾上if (!objBlock.isHook) return;// 将方块脱钩 修改它的属性:下落速度 和 没勾objBlock.offsetX = objHook.offsetX;objBlock.isHook = false;// 动画开始了 方块将下落this.isAnimining = true;},})
初始化
获取组件后,会看到上面有调用了初始化方法initCanvas()
,
先加载图片资源,图片文件都放在项目里的static
文件夹中, 实现的代码如下
const { canvas, ctx } = this.canvasData;
this.loadResources([{src: '/static/hook.png',width: canvas.width * 0.2
}, {src: '/static/block-black.png',width: canvas.width * 0.3
}, {src: '/static/block-blue.png',width: canvas.width * 0.3
}, {src: '/static/block-yellow.png',width: canvas.width * 0.3
}, {src: '/static/block-red.png',width: canvas.width * 0.3
}], images => {// 将图片数据设置到画布数据中this.canvasData.images = images;// 初始化图层方法this.initLayers();// 设置初始化计时this.currentTime = 0;// 初始化游戏未结束this.isGameEnd = false;// 执行重绘方法this.redraw();
});
会看到调用了加载图片资源的方法
loadResources(resources, success)
,
其中传入的两个参数分别是说:
- resources:这是一个数组,传入每个项都是引用图片文件的路径,和图片在游戏画布中的显示宽度;
- success:这是一个回调函数,由于加载图片文件是异步操作的,待所有图片加载完就会调用这个函数,从中得到图片资源列表
images
,然后继续处理
上面的初始化方法中,继续处理中有调用了两个方法,一个是initLayers()
,另一个是redraw()
,分别是怎么实现的呢
图层
一个初始化图层的方法initLayers()
,实现代码大致如下,
const { canvas, ctx, images } = this.canvasData;
//初始化所有基本的图层对象
const layers = [{ type: 'bg' },Object.assign({ type: 'hook' }, images[0]),Object.assign({ type: 'block' }, images[1]),{ type: 'info' }].map(layer => Object.assign({ x: 0, y: 0 }, layer));const objBackground = layers[0];//这是背景图对象const objHook = layers[1];//这是钩子图对象const objBlock = layers[2];//这是方块图对象const objInfo = layers[3];//这是游戏显示信息对象//这里进一步初始化处理,不同类型的对象有不同的处理方式layers.forEach((layer, index) => {//这里代码看着比较多,稍后讲...});// 将所有的图片 和 游戏对象 设置到画布数据中,将来有用Object.assign(this.canvasData, {layers, objBackground, objHook, objBlock, objInfo});
从 layers.forEach()
遍历出不同类型的对象,有不同的处理方式,代码如下
//通过图层layer的属性type判断
switch (layer.type) {case 'bg'://背景图{//设置平台(托盘)数据 用于能接住从上面掉落下的方块layer.platform = {//省略...};//更新和绘制方法layer.update = () => {//省略...//绘制图片ctx.drawImage(layer.image, layer.x, layer.y);};break;}case 'hook'://钩子{//...//更新和绘制方法layer.update = () => {//...//绘制图片ctx.drawImage(layer.image, layer.x, layer.y);};break;}case 'block'://方块{//...layer.update = () => {//...//这里判断 如果没有被下面的平台(托盘)接住if (layer.isFallOut) {//判断 方块是否落到画布外if (layer.y > canvas.height) {// 设置动画结束,减去HP值this.isAnimining = false;objInfo.hp--;// 判断HP值 如果还有,继续游戏if (objInfo.hp > 0) {wx.showToast({title: '还有机会,再试试',icon: 'none'});//...// 重新绘制背景 恢复上次的redrawBg();// 重置方块数据resetBlock();return;}//HP值 不够则提示游戏结束this.gameEnd();return;}//...ctx.drawImage(layer.image, layer.x, layer.y);//...return;} else {// 绘制方块ctx.drawImage(layer.image, layer.x, layer.y);}//...};break;}case 'info':// 游戏信息{//...layer.update = () => {//...// 更新显示游戏信息ctx.fillText(`❤x${layer.hp} ⏰${layer.time}s ${layer.scope}m`, layer.x, layer.y);};}
}
看上面的方法实现代码比较多,有省略了,有一些没有说,看着会不会觉得复杂呢,能看懂大概吧,
有没有看出来,每个游戏对象都有初始化属性,包括它的方法update()
是用于将来更新绘制游戏对象的
重绘
另一个是重新绘制的方法redraw()
,这个看着简单,
就是将所有的图层(游戏对象)都重绘一遍,实现代码大致如下,
if (this.isGameEnd) return;
const { canvas, ctx, objInfo, layers } = this.canvasData;
// 每一次绘制 都要先清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 遍历每个游戏对象 调用对象的更新和绘制方法
layers.forEach((layer) => layer.update());
// 这里记录时间
this.currentTime += TimeFPS;
let time = Math.floor(this.currentTime / 1000);
// 判断计时数是否变化 有变化就更新
if (time != objInfo.time) objInfo.time = time;
// 设置延迟多少ms就进行下一个重绘
this.timer = setTimeout(() => canvas.requestAnimationFrame(() => this.redraw()), TimeFPS)
TimeFPS 就是延迟多少毫秒的常量,这里它的值是
TimeFPS = 60
,是可以调节刷新速度的
游戏测试
讲到这里,上面的游戏基本就算完成了,还有剩下的细节没有说,那不重要,不要在意,
看到这里,能想到小时候玩过的叠高高游戏是怎样实现了吧,
这个叠高高游戏实现过程是否有给你启发呢,
看着像不像多个图层叠起来的运动效果呢,叠高高是不是在叠图层,
如果还不够详细,可以看项目源代码,是完整的,项目源代码点击这里查看,在资源类别下可找到(如果在手机上浏览可能会找不到,请用电脑浏览器查看),感谢支持。
来看一下运行时是怎么样的,运行效果图如下
在这个游戏基础上,学会了可以实现与之原理类似的游戏,例如盖楼,抓娃娃机等等;
如果遇到什么问题,可以留言哦,请耐心等待作者回复 ~
相关文章:

【叠高高】叠蛋糕游戏的微信小程序开发流程详解
记得小时候玩过的搭积木游戏吗,和叠高高游戏原理差不多的,与之类似的还有盖高楼游戏,就是看谁盖的(叠的)最高,这里讲一下比较基础的叠高高游戏小程序实现过程,对编程感兴趣的同学可以参考学习一…...

收集关键词的方法有哪些?(如何查找精准的行业流量关键词)
关键词的收集通常可以通过以下几种方法: 关键词收集方法 1.根据市场价值、搜索词竞争性和企业实际产品特征进行筛选:确定您的关键词列表之前,建议先进行市场分析,了解您的竞争对手、行业状况和目标受众等信息,以更好地了解所需的特…...
【GreenDao】RxQuery查询并修改GreenDao数据库,完成后更新UI
GreenDao是一个轻量级的ORM(对象关系映射)数据库,而RxJava是一个响应式编程库,可以帮助我们更轻松地处理异步事件。在 Android 应用程序中,您可以使用这两个库一起处理数据库查询和更新,并使用观察者模式来…...
Modifier ‘public‘ is redundant for interface methods错误
java中接口的方法默认是 public abstract 的 所以放心的删掉public即可,如果改为protected 或者 private还会报错 接口的方法及变量的默认修饰符 1.接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract (只能是 public abst…...

Redis缓存击穿及解决问题
缓存击穿的意思是对于设置了过期时间的key,缓存在某个时间点过期的时候,恰好这时间点对这个 Key有大量的并发请求过来,这些请求发现缓存过期- -般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把DB压垮。 解决方案有两种…...

环境感知算法——2.CenterNet基于KITTI数据集训练
1. CenterNet简介 CenterNet采用了一种新的检测思路,即以目标中心点为基础,直接回归出目标的位置和大小。而传统的目标检测算法通常会先产生大量候选框(Anchor),再通过分类器进行筛选,这种方法比较复杂。C…...

JUC 高并发编程基础篇
JUC 高并发编程基础篇 • 1、什么是 JUC • 2、Lock 接口 • 3、线程间通信 • 4、集合的线程安全 • 5、多线程锁 • 6、Callable 接口 • 7、JUC 三大辅助类: CountDownLatch CyclicBarrier Semaphore • 8、读写锁: ReentrantReadWriteLock • 9、阻塞队列 • 10、ThreadPo…...

【十二】设计模式~~~行为型模式~~~命令模式(Java)
命令模式-Command Pattern【学习难度:★★★☆☆,使用频率:★★★★☆】 1.1. 模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个…...

可再生能源的不确定性和储能系统的时间耦合的鲁棒性和非预期性区域微电网的运行可行性研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Revit中如何使创建的族文件内存变小
族文件的大小直接影响到项目文件的大小和软件运行速度,如何将族文件做的最小并且满足项目需求呢? 方法一:清除未使用项 1. 族制作完成可以把族文件中未用到的外部载入族或其他多余数据删掉,点击“管理”选项卡下拉的“清除未使用项”命令; 2…...

ClassLoader源码
介绍 ClassLoader 顾名思义就是类加载器 ClassLoader 是一个抽象类 没有父类 作用 1.负责将 Class 加载到 JVM 中 2.审查每个类由谁加载(父优先的等级加载机制) 3.将 Class 字节码重新解析成 JVM 统一要求的对象格式 常量&变量 //注册本地方法…...

Kafka分区消息积压排查指南
针对某个TOPIC只有几个分区积压的场景,可以采用以下方法进行排查: 消息生产是否指定key? 如果指定了消息key,那么消息会指定生产到hash(key)的分区中。如果指定了key,那么有下列几种可能: 生产该key的消息体…...

数据库 期末复习(4) 概念数据库的设计
第一部分 为啥要引入概念数据库 感觉只有一个重点 实体联系模型----ER模型 第二部分-----实体联系模型 这个例子可以全看完之后再来看 举个例子:根据COMPANY数据库的需求来构造数据库模式:The company is organized into DEPARTMENTs. Each department has a name, number …...
WuThreat身份安全云-TVD每日漏洞情报-2023-05-26
漏洞名称:Barracuda Email Security Gateway TAR文件命令注入 漏洞级别:严重 漏洞编号:CVE-2023-2868,CNNVD-202305-2128 相关涉及:Barracuda Email Security Gateway 5.1.3.001 漏洞状态:在野 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-12949 漏洞名称…...

关于Idea的一些常用设置项
1. 输出中文不乱码 设置工程项目编码 file -> settings -> Editor -> File Encodings-> 如下图通通UTF-8 2. 创建文件自动设置本文模板 File–>settings–>Editor–>File and Code Templates–>Includes -> 输入类注释模板 /*** Classname ${N…...

Python使用WMI模块获取Windows系统的硬件信息,并使用pyinstaller库编译打包成exe的可执行文件
引言 今天给大家分享一篇有关Python和Windows系统的文章。你有没有想过如何获取Windows系统的硬件信息?或者你是否曾经尝试过将Python脚本编译打包成可执行文件?如果你对这些问题感兴趣,那么这篇文章一定适合你。 背景 由于公司现阶段大多…...
JavaScript语句(七)
JavaScript语句 1、条件语句2、循环语句3、break 和 continue 语句4、异常处理语句4.1、抛出异常4.2、捕获异常4.3、处理异步代码块中的异常4.3.1、Promise4.3.2、async/await try-catch 4.4、处理未捕获的异常4.5、总结 1、条件语句 名称描述if当指定条件为 true 时…...
孪生诱捕网络在欺骗防御领域的应用
信息化在给人们带来便利的同时,网络信息安全问题也日益凸显。尤其是随着网络攻击由传统的盲目、直接、粗暴的方式转变为目前的精确化、持久化、隐匿式的恶意攻击,攻击过程中只需发现并利用一个未被修复的漏洞或不安全配置即可击破边界防御,试图将攻击者拒之门外的安全防护方…...

【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路
前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入,我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段,需要在每个版本中,对某些新增接口进行性能测试,有时还需要在一天中的不同时段分别进行…...

ARM体系结构与异常处理
目录 一、ARM体系架构 1、ARM公司概述 ARM的含义 ARM公司 2.ARM产品系列 3.指令、指令集 指令 指令集 ARM指令集 ARM指令集 Thumb指令集 (属于ARM指令集) 4.编译原理 5.ARM数据类型 字节序 大端对齐 小端对齐 …...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...