【迷宫】地下迷宫游戏-微信小程序开发流程详解

news2024/11/28 9:40:24

可曾记得,小时候上学路边买的透明铅笔盒,里面内嵌了一个小球,它用重力可从起点滚动到终点,对小朋友来说是感觉有趣的,在这个游戏的基础上,弄一款微信小程序的迷宫探索游戏试试,在不同关卡的迷宫中解开机关与谜题,最终到达迷宫的终点,人生要有自己的目标,就不会迷失方向。

打开微信开发工具,选择小程序,创建一个项目,
在这里插入图片描述

例如项目名称为miniprogram-maze,然后选择以下,再确定创建

  • AppID 使用自己的测试号
  • 不使用云服务
  • JavaScript - 基础模板

开始页面

要实现从开始页面跳转到游戏页面,

页面文件在/pages/index/index.wxml,添加选择关卡的表单组件,和点击按钮,绑定点击事件方法enterGame()

布局显示如下即可
在这里插入图片描述

3个关卡是不是少了点,这个可以通过一种叫地图编辑器操作来添加很多关卡

只需在文件/pages/index/index.js里的enterGame()方法中添加一段代码即可,代码如下

import Map from '../../utils/map.js';

Page({
  data: {
  	//获取所有关卡显示
    maps:(new Map()).getMaps(),
  },
  enterGame(e){
     const { map } = e.detail.value;
     wx.navigateTo({
       url: '/pages/game/game?map='+map,//传入关卡id
     })
 }
})

可以看到导入的模块map.js,这就是存放所有关卡的数据Map类,类似地图数据

游戏页面

在一个游戏页面文件/pages/game/game.wxml中写,只需要一个canvas画布组件即可,布局如下

<view class="page">
    <view class="game-view" id="game-view">
        <canvas class="canvas" type="2d" id="canv" bindtouchstart="onTouchStart" bindtouchmove="onTouchMove" bindtouchend="onTouchEnd" bindtouchcancel="onTouchEnd"></canvas>
    </view>
</view>

要做的游戏页面如下,从入口到出口的路线是通的
在这里插入图片描述

游戏逻辑

理清一下迷宫游戏逻辑,这个基础的迷宫游戏,相信在座的各位都熟悉怎么玩吧,这里就不概述了

初始化

在页面准备完成时,调用方法onReady()这里,开始写代码,

先获取到画布,然后处理初始化,看如下代码

wx.createSelectorQuery().select('#canv').fields({
 	size: true,
    node: true
}, res => {
    //...
    this.canvasData = {
        canvas: res.node,
        ctx: res.node.getContext('2d')
    };
    //使用迷宫的地图数据,mapid是指定用哪个地图数据
    const map = new Map();
    const mapData = map.getMap(this.mapid || 0);
    //...
    const grids = [];
	// 创建一个离屏画布
    const canvas = wx.createOffscreenCanvas({
        type: '2d',
        width: res.width,
        height: res.height
    });
    const ctx = canvas.getContext('2d');
    // 在离屏画布上绘制迷宫

	//先画背景
    ctx.fillStyle = '#666666';
    ctx.beginPath();
    ctx.rect(paddingLeft, paddingTop, size * cols, size * rows);
    ctx.fill();
    //在画其它的
    ctx.fillStyle = '#333333';
    for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
            let g = {
            	//...
            };
            grids.push(g);
            //...
            //若是墙壁数据,就画出来
            if (g.a=='1') {
                ctx.beginPath();
                ctx.rect(g.x, g.y, size, size);
                ctx.fill();
            }
        }
    }
	//将所有数据设置到新的地图数据中
    this.map = {
        //...
        grids,
        //游戏选手数据
        player: {
            //...
        }
    };
    //这里将离屏绘制好的地图设置到地图数据中,将来有用
    this.map.data = ctx.getImageData(0,0,canvas.width,canvas.height);
	//这里处理加载所需的图片资源数据
    Promise.all(['../../static/player-1.png','../../static/player-2.png','../../static/player-3.png'].map(src=>new Promise((resolve,reject)=>{
        let playerImg = res.node.createImage();
        playerImg.onload = () => resolve(playerImg);
        playerImg.onerror = reject;
        playerImg.src = src;
    }))).then(res=>{
    	//在游戏选手数据里放好所有图片数据
        this.map.player.headImgs = res;
        //重置游戏数据,开始游戏
        this.restart();
    }).catch(err => console.error(err))
}).exec()

从初始化的方法中可以看到,使用了离屏画布wx.createOffscreenCanvas(),可能有一些小伙伴不什么理解它,

离屏画布与组件canvas的用法是一样的,但是有所区别,离屏画布可以理解为后台绘制,绘制出来的图形是不可见的,

后台绘制完后,要用canvas组件绘制,也就是覆盖一下,才能看到图形,
它的绘制方法,在下面的重绘方法redraw()中会提到

初始化方法处理完成,就进入开始游戏方法restart(),代码大致如下

//...
const { player, inIndex, outIndex } = this.map;
const { canvas } = this.canvasData;
//重置游戏选手数据和状态
player.index = inIndex;//表示在迷宫的入口
player.timer = TIMER_FULL;//这是常量,最大计时60s
//...
this.isGameEnd = false;
this.preIndex = inIndex;
//...
//处理下一帧的方法
const nextFrame = () => {
	//延迟执行
    this.timer = setTimeout(() => {
        if (player.timer <= 0) {
            this.showModal('挑战失败!\n爱是一道光,没了你发慌...');
            return;
        }
        else if (player.index == outIndex) {
            this.showModal('挑战成功!\n头上带点绿,生活过的去...');
            return;
        }
        else if (player.index == inIndex && this.preIndex!=inIndex) {
            this.preIndex = inIndex;
            // 如果走到原点(迷宫入口),就提示
            wx.showToast({
                title:'你不能回去...',
                icon:'none'
            });
        }
        //重绘
        this.redraw();
        //执行下一帧
        canvas.requestAnimationFrame(() => nextFrame());
    }, FRAME_TIME);
};
nextFrame();

其中FRAME_TIME就是常量,延迟执行下一帧的时间,它的值是60,单位毫秒

接下来,看看重绘方法redraw(),代码大致如下

const { map } = this;
const { canvas, ctx } = this.canvasData;
const { player, grids, size, rows, cols, paddingTop, paddingLeft, outIndex } = map;
//绘制前,先清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
//判断游戏是否结束了
if (this.isGameEnd) {
	//绘制迷宫地图
    ctx.putImageData(map.data, 0, 0);
}else{
	//在选手头像的位置周围内绘制(限制在一格距离),超过距离都绘制黑色,表示看不见远处的
    let index = player.index;
    let g = grids[index-cols-1];
    //省略了...
    //3个格的距离
    let s = size*3;
    //这里将离屏绘制出来的地图绘制出来,传入的参数可决定绘制的地图范围
    ctx.putImageData(map.data, 0, 0, g.x, g.y, s, s);
	//...
}
//获取选手所在的格子数据
let playerG = grids[player.index];
//如不在终点位置
let isFail = outIndex!=player.index;
//是否游戏结束
if (this.isGameEnd) {
	//有没有到终点,绘制选手头像将是不一样的
    if (isFail) ctx.drawImage(player.headImgs[1],playerG.x,playerG.y,size,size);
    else ctx.drawImage(player.headImgs[2],playerG.x,playerG.y,size,size);
}else{
	//绘制选手头像
    ctx.drawImage(player.headImgs[0],playerG.x,playerG.y,size,size);
    //...
    //绘制出口的灯光泡,r是半径,可以改变,一大一小变化
    playerG = grids[outIndex];
    ctx.fillStyle = '#F4E286';
    ctx.beginPath();
    ctx.arc(playerG.x + r, playerG.y + r, r*s, 0, Math.PI * 2);
    ctx.fill(); 
}

//绘制剩余时间,每过一秒就更新一下timer
ctx.fillStyle = '#ff0000';
ctx.font = 20+'px sans-serif';
ctx.fillText(`剩余时间 ${player.timer}`, paddingLeft, paddingTop*0.6);

在游戏进行中,迷宫地图应该是隐藏的,显示效果如下

在这里插入图片描述

由于是探索类迷宫,选手游戏时是没有地图可看的,
有方向感,可感知距离,还有手速,还是可以攻关的,
随着倒计时开始,会增加游戏紧张度吧,
关卡地图越大,挑战难度就越大。

接下来,是实现游戏交互逻辑了,通过触摸操作识别出移动方向,

请参考这个文章来实现 关于手机中的触摸手势操作实现过程详解,

主要是改变player.index就可以实现移动

游戏测试

写到这里,这个迷宫游戏基本就算完成了,看着不是很多,是不是感觉简单呢,运行效果动图如下,
请添加图片描述

想看详细的可以去找一下对应的项目源码,点此查看,在资源类别下可以找到(如果在手机上看到的,可能看不到,请用电脑浏览器上看),感谢支持。

游戏用到素材,同下面,如觉得不合适,自己修改替换就好,
在这里插入图片描述

爱是一道光,没了你发慌
如果被爱是一道光,那没了以后,就问你慌不慌

在这里插入图片描述

生活过得去,头上带点绿
那点绿,可以理解为慢羊羊头上的那颗智慧草吗😄

以上讲得是选微信小程序开发的,
如果想要选小游戏开发,请参考这个文章 微信小程序的游戏转到小游戏上实现方法详解 来实现,
觉得有帮助,就点个赞呗~

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

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

相关文章

14 【Vuex】

1.理解 Vuex 1.1 Vuex 是什么 概念&#xff1a;专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对Vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用…

基于RK3399+FPGA的地面测试台多参数数据记录仪方案(一)软件设计及测试

完成了测试台软件分析和编程环境搭建后&#xff0c;接下来就是软件的编写。本章主要包括 软件窗口界面设计和功能代码实现。以某型号数据记录仪的工作需求为目标&#xff0c;根据测试 工作流程&#xff0c;以 Linux-Qt 为主要开发手段&#xff0c;设计一款功能完备、界面友…

Java8 Stream详解及结束操作方法使用示例(三)

结束操作是指结束 Stream 该如何处理的操作&#xff0c;并且会触发 Stream 的执行。下面是一些常用的结束操作方法。结束操作会对数据源进行遍历&#xff0c;因此是及早求值的。 Java8 Stream详解及中间操作方法使用示例&#xff08;一&#xff09; ​​​​​​​Java8 Strea…

三种经典博弈(取石子问题)

三种经典博弈 巴什博奕威佐夫博奕尼姆博奕 博弈是有一种很有意思的游戏&#xff0c;就是有物体若干堆&#xff0c;可以是火柴棍或是围棋子等等均可。两个人轮流从堆中取物体若干&#xff0c;规定最后取光物体者取胜。这是我国民间很古老的一个游戏&#xff0c;别看这游戏极其简…

一体化协同平台助力企业回归生产本质,创造价值

核心观点 单点工具的串联无法有效解决研效痛点问题&#xff0c;企业需要通过一体化协同平台提高端到端价值流动效率。一体化协同平台的价值是软件工程理念最大化落地、数字化研发管理、沉浸式研发体验。一体化协同平台集成需要评估闭环效率杠杆&#xff0c;确定集成边界和集成…

什么是关系模型? 关系模型的基本概念

关系模型由IBM公司研究员Edgar Frank Codd于1970年发表的论文中提出&#xff0c;经过多年的发展&#xff0c;已经成为目前最常用、最重要的模型之一。 在关系模型中有一些基本的概念&#xff0c;具体如下。 (1)关系(Relation)。关系一词与数学领域有关&#xff0c;它是集合基…

TensorRT 从7.2升级到8.5,改写plugin以适配新版本

前言 TensorRT是NVIDIA推出的一款高效深度学习模型推理框架&#xff0c;其包括了深度学习推理优化器和运行时&#xff0c;能够让深度学习推理应用拥有低时延和高吞吐的优点。 TensorRT的版本迭代速度非常快&#xff0c;很多之前写的plugin在版本升级后可能就没法直接使用&…

广州虚拟动力携数字人交互技术产品参展第十九届深圳文博会

2023年6月7-11日 深圳国际会展中心 第十九届深圳文博会正式举办&#xff01; 广州虚拟动力携数字人交互技术产品参展 诚邀您莅临粤港澳大湾区馆&#xff08;11号馆&#xff09; 广东参展团展位参观交流 数字技术&#xff0c;引领文化产业新发展 中国文化及相关文化产业的…

【Apache Pinot】Controller、Broker 和 Server 的概念和工作流程

背景 笔者最近一段时间使用 Apache Pinot 比较多&#xff0c;发现目前国内使用 Pinot 的很少&#xff0c;所以跟他相关的资料也比较少&#xff0c;本人在扩容&#xff0c;升级&#xff0c;部署&#xff0c;查询等方面操作有些许经验&#xff0c;知道其中有很多细节需要注意和规…

北邮22信通:实验七 三角波-方波(锯齿波-矩形波)发生器实验报告(着急验收的同学先看看,后续细节正在赶来中)

北邮22信通一枚~ 持续更新模电实验讲解 关注作者&#xff0c;解锁更多邮苑模电实验报告~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22信通——电子电路_青山如墨雨如画的博客-CSDN博客 实验七 三角波-方波&#xff08;锯齿波-矩形波&#xff09;发生器实验…

数据结构——树的概念、二叉树的概念

文章目录 引言1.树的概念1.1.树的其他相关概念 2.树的代码实现的结构2.1.树形结构的应用 3.二叉树的概念3.1.特殊二叉树的概念3.1.1.完全二叉树3.1.2.满二叉树 3.2.二叉树试题讲解3.2.1.试题一3.2.2.试题二3.2.3.试题三 4.二叉树的存储结构4.1.顺序结构存储4.2.链式结构存储 引…

重温经典:简读光干涉、衍射原理

如果您不是光学专业的&#xff0c;或者是文科生&#xff0c;那么您想到光的干涉和衍射第一反应应该是很多公式对不对&#xff1f;头好大是不是&#xff1f;好&#xff0c;那么今天我们就不用一个公式来重新解读光的干涉和衍射。 光&#xff0c;也叫电磁波&#xff0c;他的表现…

java并发编程:Java线程池详解

文章目录 为什么要用线程池线程池的原理ThreadPoolExecutor提供的构造方法ThreadPoolExecutor的策略线程池主要的任务处理流程ThreadPoolExecutor如何做到线程复用的&#xff1f; 四种常见的线程池newCachedThreadPoolnewFixedThreadPoolnewSingleThreadExecutornewScheduledTh…

web3.js获取导入

我们访问 https://github.com/ 我们搜索 web3.js 然后我们直接点击第一个进去 进入之后 往下拉 你会看到 它支持node项目的两种引入方式 这里 大家可以直接下载我的资源 https://download.csdn.net/download/weixin_45966674/87878737 下载好解压出来就会有一个 web3.min.js…

C#读写EM4205/4305/4469卡复制ID卡制做FDX-B动物标签源码

EM4305/EM4205卡是采用瑞士EM微电子公司工作频率为125kHz&#xff0c;具有读、写功能的非接触式RFID射频芯片&#xff0c;它具有功耗低、可提供多种数据传输速率和数据编码方法等特点&#xff0c;适合射频芯片ISO 11784/11785规范&#xff0c;该芯片被广泛应用于动物识别和跟踪…

《C++高级编程》读书笔记(五、六:面向对象设计设计可重用代码)

1、参考引用 C高级编程&#xff08;第4版&#xff0c;C17标准&#xff09;马克葛瑞格尔 2、建议先看《21天学通C》 这本书入门&#xff0c;笔记链接如下 21天学通C读书笔记&#xff08;文章链接汇总&#xff09; 1. 过程化的思考方式 过程语言&#xff08;例如 C&#xff09;将…

玄奘文旅集团主办学习强企玄奘之路戈壁挑战赛在敦煌圆满完赛!

“学习改变命运&#xff0c;强企复兴中国”&#xff0c;2023年4月16日-20日&#xff0c;由玄奘文旅集团主办的“第23届26届学习强企玄奘之路戈壁挑战赛&#xff08;联赛&#xff09;”在千年古城敦煌圆满落幕&#xff01; 这是商界各行业的一次跨界融合&#xff0c;也是疫情过…

感性了解一下互斥和信号量

一、互斥的四个概念 我们把大家都能看到的资源叫做&#xff1a;公共资源 a、互斥&#xff1a;任何一个时刻&#xff0c;都只允许一个执行流在进行共享资源的访问——加锁 b、我们把任何一个时刻&#xff0c;都只允许一个执行流进行访问的共享资源叫做临界资源 c、临界资源需…

【TA100】图形 2.4 传统经验光照模型详解

一、光照模型 ● 一种模拟自然光照过程的计算机模型 ● 本次课程可以这样理解&#xff1a;光线与物体表面的作用 ● 分类 ○ 基于物理的光照模型&#xff08;PBR&#xff09;&#xff08;有可依据的公式&#xff09; ○ 经验模型&#xff08;进行了一些近似、模拟&#xff0c;…

【小呆的概率论学习笔记】正态分布的代数运算

文章目录 1. 正态分布简介1. 正态分布的数字特征2. 正态分布的代数运算a. 单随机变量的代数运算b. 两个正态分布随机变量的和c. 多个正态分布随机变量的线性组合 1. 正态分布简介 正态分布应该是概率论和数理统计中最重要的一类概率分布&#xff0c;最早的完整论述是由数学王子…