记得小时候玩过的搭积木游戏吗,和叠高高游戏原理差不多的,与之类似的还有盖高楼游戏,就是看谁盖的(叠的)最高,这里讲一下比较基础的叠高高游戏小程序实现过程,对编程感兴趣的同学可以参考学习一下,代码不会很多,非常值得入手研究学习哦。
打开微信开发工具,选择小程序,创建一个项目,

讯享网
例如项目名称为
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,是可以调节刷新速度的
游戏测试
讲到这里,上面的游戏基本就算完成了,还有剩下的细节没有说,那不重要,不要在意,
看到这里,能想到小时候玩过的叠高高游戏是怎样实现了吧,
这个叠高高游戏实现过程是否有给你启发呢,
看着像不像多个图层叠起来的运动效果呢,叠高高是不是在叠图层,
如果还不够详细,可以看项目源代码,是完整的,项目源代码点击这里查看,在资源类别下可找到(如果在手机上浏览可能会找不到,请用电脑浏览器查看),感谢支持。
来看一下运行时是怎么样的,运行效果图如下


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/116021.html