【合成数字】合成类游戏-uniapp项目开发流程详解

以前玩过2048游戏,从中发现规律,想到跟合成类游戏相似,知道为什么很相似吗,在这里,做一个数字合成游戏玩玩吧,感兴趣的话可以看看,这里给大家讲一讲数字合成游戏的开发过程。

文章目录

  • 创建项目
  • 页面布局
    • 初始页面
    • 游戏页面
  • 游戏逻辑
    • 加载模块
    • 初始化画布
    • 初始化游戏数据
    • 绘制游戏状态
    • 绘制网格
    • 开始游戏
    • 重新开始
    • 触摸事件
  • 游戏测试

创建项目

这里用HBuilderX开发工具来创建一个uniapp项目,

例如项目名填写uniapp_CompositeNumber,依次选择如下图
在这里插入图片描述

  • 选择新建uni-app项目
  • 使用默认模板
  • Vue版本选择 3

页面布局

新建好项目,会看到自动创建了一个初始页面文件,

初始页面

文件位置在pages/index/index.vue,打开看看,

在页面布局中,对应的template标签里添加一个按钮组件,按钮名叫进入游戏,

然后在script标签里,添加一个按钮点击方法,实现打开游戏页面,

打开页面的代码很简单,自己能写出来吧,这里就不展开讲,

游戏页面

需要自己创建一个游戏页面,

页面文件在pages/game/game.vue,打开接着写,

在页面布局中,对应的template标签里添加,内容如下

<!--pages/game/game.wxml-->
<view class="page"><canvas type="2d" id="zs1028_csdn" class="canvas" bindtouchstart="onTouchStart" bindtouchmove="onTouchMove" bindtouchend="onTouchEnd" disable-scroll="{{true}}"/>
</view>

就这么简单,只放一个canvas组件即可,组件的一些属性不用说能看懂吧

写好后,要做出运行的游戏页面效果,就像如下图这样
在这里插入图片描述

看着是不是很像2048游戏呢,没错,与其不同的是从数字1开始计算,
实现思路,就是把两个相同的数字合成,如1+1=2,计算规则n+n=2n

游戏逻辑

接下来,在script标签里,写游戏逻辑,

加载模块

开始写初始化代码,先加载游戏模块,添加代码如下

// pages/game/game.js
import ZS1028_CSDN from '../../utils/zs1028_CSDN.js'
import Gesture from '../../utils/gesture.js'const app = getApp()Page({//.../*** 生命周期函数--监听页面初次渲染完成*/async onReady() {//...这里处理初始化},/*** 生命周期函数--监听页面卸载*/onUnload() {if(this.timer) clearTimeout(this.timer)this.game?.destroy()},/*** 以下是通过canvas的触摸事件来调用*/onTouchStart(e) {...},onTouchMove(e) {...},onTouchEnd(e) {...},
})

导入的两个模块,想必看过之前笔者发布过文章的读者会有点映像,
Gesture ,是一个处理触摸手势模块,有参考文章 关于手机中的触摸手势操作实现过程详解;
ZS1028_CSDN ,是一个游戏引擎框架模块,让游戏实现变得简单;

初始化画布

游戏大致的思路呢,是要先把画布初始化,然后绘制出来游戏画面,

也就是绘制网格,然后绘制一些数字在上面,

就在onReady()方法里写,画布初始化的逻辑,代码如下

const { node: canvas, width, height } = await ZS1028_CSDN.query('#zs1028_csdn')
Object.assign(canvas, { width, height })
const game = ZS1028_CSDN.createMiniGameEngine({canvas,// isTest: true //游戏测试用途
})
this.game = game

初始化游戏数据

继续写下去,初始化游戏数据,代码如下,

//游戏状态数据
const gameState = {bottom: 38 //游戏标题底部位置
}
//游戏网格数据
const gridsData = {grids: [], //游戏网格列表cols: 5, //网格列数isNew: false, //是否出现新的数字 
}

绘制游戏状态

接下来,调用游戏对象的绘制过程,

这是绘制游戏标题,显示游戏状态,代码如下

const that = this
//初始化游戏标题层
game.initTopBar({data: gameState,reset() {//重置数据的Object.assign(this.data,{scope: 0,best: app.getMaxScope(),timerNum: 300,})},redraw(data) {const { canvas, context: ctx, topBar } = datalet { scope, best, timerNum } = this.data//这里绘制游戏标题区域...}
})

绘制网格

接下来,绘制出来网格,代码如下

//添加游戏背景层,绘制网格
game.addBgObject({data: gridsData,reset() {const { grids } = this.data//...这里重置游戏网格数据//添加随机数字到网格for(let i=0;i<5;i++){this.addRandomGridValue()}},redraw(data) {const { canvas, context: ctx, topBar } = datalet { cols, grids, gridSize, isNew } = this.dataif (!this.cacheBgImg) {//...在这里画背景图片,也就是绘制网格,第一次就要画出来,导出图片,然后就直接用图片绘制来代替return}//...判断一个状态,如果要新的随机位置数字if (isNew) {this.addRandomGridValue()//添加好,就重置一下状态this.data.isNew = false}//这里先绘制背景图片(网格)ctx.drawImage(this.cacheBgImg, 0, 0, canvas.width, canvas.height)let r = gridSize / 2//...这里绘制网格中的数字grids.forEach(g => {if (g.value < 1) return//...绘制数字valuectx.fillText(g.value, g.x + g.relX + r, g.y + g.relY + r * 1.1)//...这之后就是绘制移动数字动画的,代码虽少,但不好理解})},methods: {addRandomGridValue() {//...自定义方法,实现添加随机位置的数}}
})

开始游戏

最后,准备就绪,开始游戏,代码如下

//将初始化数据存放好
this.gameData = {gameState,gridsData
}
//最后,调用此方法开始游戏
this.restart()

重新开始

写重新开始的逻辑很简单,

在开始游戏调用方法restart()里有实现,代码如下

game.reset()
//...其它的初始化逻辑
game.run()

可见,重新开始游戏,只需调用游戏对象game的两个方法就可以了

触摸事件

接下来,处理画布canvas触摸事件,让游戏与玩家交互,

用到了处理手势的模块,这实现会变得简单,

开始触摸时,记录下按下的点数据,

就是触摸开始点touch1 和移动到最后的点touch2两个,代码如下

onTouchStart(e) {if (this.isGameEnd || this.startAnimating) returnthis.touch1 = e.touches[0]
},onTouchMove(e) {if (!this.touch1) returnthis.touch2 = e.touches[0]
},

触摸移动结束时,调用手势模块的方法,就能得出滑动的方向,

这样就知道往哪个方向移动,来处理网格里的一些数字移动,

实现移动的逻辑,加上动画,这会变得复杂一些,

仔细构思一下,就写了出来,代码如下

onTouchEnd(e) {if (this.touch1 && this.touch2) {//通过调用模块的方法获取let g = Gesture.touchesToG(this.touch1, this.touch2)let list = this.scanGrids(g)let gs = []let isReverse //是否反向排列//判断是哪个手势switch (g) {case Gesture.G.left:case Gesture.G.right:isReverse = truebreakcase Gesture.G.up:case Gesture.G.down:isReverse = falsebreakdefault:throw new Error('this is error')}//遍历一遍,将可移动的数字记录到gs列表中list.forEach(arr => gs.push(...this.calcMoveGrids(arr, isReverse)))//这里列表若不为空,就有移动的数字在里面if (gs.length > 0) {this.startAnimating = true//开始下一个的移动数字动画 this.nextAnimation(list,gs,isReverse,1)} else {//没有可移动的,可能有存在两个相邻的相同数字,需要调用合并数字的方法let scope = this.compositeNumber(list, isReverse)//当scope大于0,也就是有得分,表示合并成功,就执行移动数字动画if (scope > 0) {this.startAnimating = true//开始下一个的移动数字动画this.nextAnimation(list,gs,isReverse)}}}//最后,别忘了重置触摸点数据this.touch1 = undefinedthis.touch2 = undefined
},

别法算法想那么复杂,只要思路是对的,能实现出来的就没问题

游戏测试

写到这里,基本上就可以运行测试玩玩了,

看看合成数字的游戏效果吧,运行动图如下
请添加图片描述

想要改成2048游戏一样是可以的,只需要在新建的随机位置数字代码里修改12即可;

想要项目源码在点这里查看下载,或者直接点这里搜索:合成数字,在本博客站内请放心下载,感谢支持!

可能手机上看不到,请改用电脑浏览器查看;
如果搜索不到,只能在资源一栏慢慢找了(太多了不好找

请添加图片描述

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

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

相关文章

Pandas-DataFtame的索引与切片(第3讲)

Pandas-DataFtame的索引与切片(第3讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

【动态读取配置文件】ParameterTool读取带环境的配置信息

不同环境Flink配置信息是不同的&#xff0c;为了区分不同环境的配置文件&#xff0c;使用ParameterTool工具读取带有环境的配置文件信息 区分环境的配置文件 三个配置文件&#xff1a; flink.properties&#xff1a;决定那个配置文件生效 flink-dev.properties&#xff1a;测…

主持知识竞赛类节目的一般流程是什么

竞争性的团队活动&#xff0c;更适合青年的特点&#xff0c;更容易得到青年的支持&#xff0c;也是"离教于乐"的好方式。 这类活动可从内容和特点上分为知识性竞赛&#xff0c;技能性竞赛&#xff0c;文娱性竞赛&#xff0c;体育竞技性竞赛等形式。 知识性竞赛&…

【VMware安装及虚拟机配置】

1. 下载VMware 进入 VMware Workstation 17 Pro下载链接 下拉到如下位置&#xff0c;点击DOWNLOAD 2. 安装VMware 参考&#xff1a;虚拟机VMware下载与安装教程 本次安装是vmware 17&#xff0c;安装步骤差不多&#xff0c;只参考第二部分即可。 3. 激活VMware 密钥&…

【Qt QML入门】TextInput

TextInput&#xff1a;单行文本输入框。 TextInput除了光标和文本外&#xff0c;默认没有边框等效果。 import QtQuick import QtQuick.Window import QtQuick.ControlsWindow {id: winwidth: 800height: 600visible: truetitle: qsTr("Hello World")//单行文本输…

HarmonyOS开发实战:如何实现一个运动排名榜页面

HarmonyOS开发实战&#xff1a;如何实现一个运动排名榜页面 代码仓库&#xff1a; 运动排名榜页面 项目介绍 本项目使用声明式语法和组件化基础知识&#xff0c;搭建一个可刷新的排行榜页面。在排行榜页面中&#xff0c;使用循环渲染控制语法来实现列表数据渲染&#xff0c;…

03 使用Vite开发Vue3项目

概述 要使用vite创建Vue3项目&#xff0c;有很多种方式&#xff0c;如果使用命令&#xff0c;则推荐如下命令&#xff1a; # 使用nvm将nodejs的版本切换到20 nvm use 20# 全局安装yarn npm install -g yarn# 使用yarnvite创建项目 yarn create vite不过&#xff0c;笔者更推荐…

LeedCode刷题---滑动窗口问题(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、将X减到0的最小操作数 题目链接&#xff1a;将 x 减到 0 的最小操作数 题目描述 给你一个整数数组 nums 和一个整数 x 。每一…

mysql的负向条件查询会不会使用索引

mysql的负向条件查询&#xff0c;例如not in&#xff0c;会不会使用索引&#xff1f; 其实&#xff0c;mysql还是会尽量利用索引。如果查询的列上有索引&#xff0c;并且索引能够覆盖查询所需的列&#xff0c;那么mysql可能会使用索引来获取结果&#xff0c;而不是进行全表扫描…

2024中国国际大数据产业博览会年度主题征集公告

2024中国国际大数据产业博览会年度主题征集公告 中国国际大数据产业博览会&#xff08;以下简称数博会&#xff09;&#xff0c;是全球首个以大数据为主题的国家级博览会&#xff0c;由国家发展和改革委员会、工业和信息化部、国家互联网信息办公室和贵州省人民政府共同主办&am…

ADB命令安装卸载手机APP

前言 手机内置的浏览器很多广告&#xff0c;推荐的新闻也很多负面的新闻&#xff0c;所以就想卸载内置的手机app&#xff0c;不过现在很多手机都是限制了内置的软件都不能卸载&#xff0c;以前随便获取一下root权限&#xff0c;也是可以卸载的&#xff0c;不过最近搞了一下&am…

【POI的如何做大文件的写入】

&#x1f513;POI如何做大文件的写入 &#x1f3c6;文件和POI之间的区别是什么&#xff1f;&#x1f3c6;POI对于当今的社会发展有何重要性&#xff1f;&#x1f3c6;POI大文件的写入&#x1f396;️使用XSSF写入文件&#x1f396;️使用SXSSFWorkbook写入文件&#x1f396;️对…

设计可编辑表格组件

前言 什么是可编辑表格呢&#xff1f;简单来说就是在一个表格里面进行表单操作&#xff0c;执行增删改查。这在一些后台管理系统中是尤为常见的。 今天我们根据vue2 element-ui来设计一个表单表格组件。&#xff08;不涉及完整代码&#xff0c;想要使用完整功能可以看底部连…

ReenterLock重入锁

synchronized就是一种最简单的控制方法&#xff0c;它决定了一个线程释放可以访问临界区资源。 同时&#xff0c;Object.wait()方法和Object.notify()方法起到了线程等待和通知的作用。 ReenterLock重入锁可以完全替代关键字Synchoronized.重入锁是Synchoronized、Object.wait(…

[楚慧杯 2023] web

文章目录 eaaevalupload_shell eaaeval 打开题目&#xff0c;源码给了用户密码 登陆后啥也没有&#xff0c;扫一下发现源码泄露www.zip <?php class Flag{public $a;public $b;public function __construct(){$this->a admin;$this->b admin;}public function _…

C++ list常用操作

目录 一、介绍 二、list的常用操作 1、构造 2、迭代器 3、元素访问 4、容量操作 一、介绍 std::list文档链接 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个…

独立看门狗 IWDG

看门狗介绍 "看门狗"通常指的是计算机科学和信息技术领域中的一种技术或设备&#xff0c;用于监控系统的运行状态&#xff0c;并在系统出现故障或异常情况时采取相应的措施。这种技术或设备起到类似于守卫的作用&#xff0c;确保系统的稳定性和可靠性。 在计算机系统…

beebox靶场A1 low 命令注入通关教程(上)

一&#xff1a;html注入 get HTML注入&#xff0c;就是当用户进行输入时&#xff0c;服务器没有对用户输入的数据进行过滤或转义&#xff0c;导致所有输入均被返回前端&#xff0c;网页解析器会将这些数据当作html代码进行解析,这就导致一些恶意代码会被正常执行。 首先进行简…

DC电源模块的设计与制造技术创新

BOSHIDA DC电源模块的设计与制造技术创新 DC电源模块的设计与制造技术创新主要涉及以下几个方面&#xff1a; 1. 高效率设计&#xff1a;传统的DC电源模块存在能量转换损耗较大的问题&#xff0c;技术创新可通过采用高效率的电路拓扑结构、使用高性能的功率开关器件和优化控制…

面向对象三大特征——继承

目录 1. 概述 2. 继承的限制 2.1 单继承 2.2 访问修饰符 2.3 . final 3. 重写 4. super 4.1super的作用 4.2访问父类的成员和被重写方法 4.3调用父类的构造器 1. 概述 多个类中存在相同属性和行为时&#xff0c;将这些内容抽取到单独一个类中&#xff0c;那么就无需在…