0基础从前端到Web3 —— Mine Clearance Frontend(二)

在一的基础上继续往下,本篇主要是链上调用部分,让整个项目可以进行最基本的扫雷游戏。

S u i   M o v e \mathit {Sui\ Move} Sui Move 链上部署的自主实现的简单扫雷游戏可以点击查看,只不过这里将区域大小扩大为了 10  ×  20 \text {10}\ \times\ \text {20} 10 × 20,更新了雷格判断是否存在雷的逻辑使其不至于越界报错,具体内容已经 p u s h \mathit {push} push 到了 G i t h u b \mathit {Github} Github,可以自行查看。

一:创建游戏

在前篇,点击 G A M E \mathit {GAME} GAME 按钮只是判断了是否连接到了 S u i \mathit {Sui} Sui 钱包,在这里,我们往这个按钮的点击事件里额外调用两个函数,一个是清空当前的游戏区域,因为可能残存上一局的游戏内容,第二个则是链上调用,创建一局全新的游戏,并获取返回的链上对象GameInfoID

1.1 ClearCheckerboard

回想前篇,我们是如何绘制雷格的?
将一个个按钮组合成ButtonGroup再放到一起组合成 10  ×  20 \text {10}\ \times\ \text {20} 10 × 20 的区域。
同理,想要改变每一个按钮的内容,也需要通过循环取用加以修改。

为了让功能更具有通用性,再来考虑链上调用后得到的游戏内容变化会以何种形式呈现?
S u i   M o v e \mathit {Sui\ Move} Sui Move 的合约代码中会对每一次游戏点击触发一个事件,不管游戏成功、失败还是继续游戏,都会将最新的方格信息传回来。前端通过这一事件获得当前的雷区详情,而这一信息会以一个字符串数组的形式呈现。

也就是说,我们需要构建一个内容为空的字符串数组,再将其视为当前雷区的实际情形对每一个按钮的内容进行循环遍历删改。

function ChangeCheckerboard(checkerboard: any) {
	// console.log(checkerboard);
	// for (let row of checkerboard) {
	// 	console.log(row);
	// }
	const htmlCheckerboard = document.getElementById("Checkerboard")!.children[0].children;
	let i = 0, j = 0;
	for (let list of htmlCheckerboard) {
		// console.log(list);
		for (let row of list.children) {
			// console.log(row);
			// console.log(checkerboard[i][j]);
			const replace = checkerboard[i][j] !== "-" ? checkerboard[i][j] : " ";
			ChangeChess(row, replace);
			i += 1;
		}
		j += 1;
		i = 0;
	}
}

function ChangeChess(html: Element, replace: string) {
	// console.log(html.innerHTML);
	const str1 = html.innerHTML.split('<', 1)[0];
	const str2 = html.innerHTML.substring(str1.length);
	html.innerHTML = replace.concat(str2);
}

function ClearCheckerboard() {
	const checkerboard = [];
	for (let i = 0; i < MaxRow; i++) {
		let rowStr = "";
		for (let j = 0; j < MaxList; j++)
			rowStr = rowStr.concat("-");
		checkerboard.push(rowStr);
	}
	ChangeCheckerboard(checkerboard);
	HiddenFeedBack();
}

1.2 MoveCallStartGame

这个函数会在按钮的点击事件中被调用,如果到了那个时候再从一些SDK取值则会报错,所以我们需要事先声明,再通过参数的形式传入。

const account = useCurrentAccount();
const { mutate: signAndExecuteTransactionBlock } = useSignAndExecuteTransactionBlock();
const [gameInfoID, setGameInfoID] = React.useState("");

通过前前篇的文章可以知道,这里的链上调用其实跟直接用 T y p e S c r i p t \mathit {TypeScript} TypeScript 来调用没什么太大的区别,都是往TransactionBlock里面填充一笔笔交易信息,再signAndExecuteTransactionBlock签名提交交易块到链上执行,重点是如何对成功交易后返回的信息筛选处理,取得我们所需要的值。

首先,需要在signAndExecuteTransactionBlock中,将showObjectChanges设置为true,因为我们的目的是取得某一个对象的ID;接着可以通过onSuccess来截取返回的信息,如果不确定其结构,就将其console.log出来查看,最后不断通过.层层深入取用。

function MoveCallStartGame(signAndExecuteTransactionBlock: any, setGameInfoID: any) {
	const txb = new TransactionBlock();
	const [coin] = txb.splitCoins(txb.gas, [666]);

	txb.moveCall({
		target: `${Package}::player::start_game`,
		arguments: [
			txb.object(GameCap),
			coin,
		]
	});

	signAndExecuteTransactionBlock(
		{
			transactionBlock: txb,
			chain: `sui:$network`,
			options: {
				showObjectChanges: true,
			}
		},
		{
			onSuccess: (result: any) => {
				// console.log(result.objectChanges);
				for (let obj of result.objectChanges) {
					// console.log(obj);
					if (obj.type === "created") {
						// console.log(obj.objectId);
						setGameInfoID(obj.objectId);
						break;
					}
				}
			}
		}
	);
}

一切顺利的情况下,在编写该按钮点击事件的函数当中,一个名为gameInfoID的变量就已经被设置成了我们所需要的值。

二:享受游戏

在前篇当中,雷区的按钮点击逻辑就是显现一行提示语,再将其填充进 X \mathit {X} X,在这里,我们完善这一逻辑。

第一步,点击相当于链上调用,其中有个关键的参数就是需要知道玩家点击的是第几行第几列的方格。
在按钮中,有一个button-key的属性,可以通过点击事件的event.target.getAttribute('button-key')取得,如果是其父节点则是const l = event.target.parentElement.getAttribute('button-key')
我们将这两个值,按照按钮排列方式,一个设成行,一个设成列(生成区域时从循环的i, j来赋值),此时取出转换为数字类型传参即可。

已知点击过后的游戏区域的详细信息会通过链上事件的方式触发,那么这第二步就是从这信息当中截取我们所需要的,也就是从中找出存储有雷区揭示情形的字符串数组,通过上面的方法将其显现到前端。
看过该合约的一定也知道,一旦游戏成功或者失败,是会额外触发一个对应的事件的,这一点就可以用来判断该显示哪一句提示(胜利、继续、失败)。

function MoveCallGameClick(r: number, l: number, gameInfoID: string, signAndExecuteTransactionBlock: any) {
	const txb = new TransactionBlock();

	txb.moveCall({
		target: `${Package}::player::game_click`,
		arguments: [
			txb.pure(r),
			txb.pure(l),
			txb.object(gameInfoID),
		]
	});

	signAndExecuteTransactionBlock(
		{
			transactionBlock: txb,
			chain: `sui:$network`,
			options: {
				showEvents: true,
			}
		},
		{
			onSuccess: (result: any) => {
				// console.log(result);
				let showed = false;
				for (let event of result.events) {
					if (event.type === GameEvent) {
						// console.log(event.parsedJson.checkerboard);
						ChangeCheckerboard(event.parsedJson.checkerboard);
					} else if (event.type === GameSuccessEvent) {
						ShowFeedBack("success_alert");
						showed = true;
					} else {
						ShowFeedBack("failure_alert");
						showed = true;
					}
				}
				if (!showed)
					ShowFeedBack("encourage_alert");
			}
		}
	);
}

三:实机演示

在这里插入图片描述

在这里插入图片描述

四:加入组织,共同进步!

  • Sui 中文开发群(TG)
  • M o v e \mathit{Move} Move 语言学习交流群: 79489587

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Plesk中如何移除之前添加的域名

我这边想要移除我之前绑定到主机的域名&#xff0c;但是不知道如何在主机上面进行移除&#xff0c;由于我使用的Hostease的Windows虚拟主机产品默认带普通用户权限的Plesk面板&#xff0c;但是不知道如何在Plesk上操作移除域名&#xff0c;因为也是对于Hostease主机产品不是很了…

python给图片加上图片水印

python给图片加上图片水印 作用效果代码 作用 给图片加上图片水印图片水印的透明度&#xff0c;位置可自定义 效果 原始图片&#xff1a; 水印图片&#xff1a; 添加水印后的图片&#xff1a; 代码 from PIL import Image, ImageDraw, ImageFontdef add_watermark(in…

联盟 | 歌者 AIPPT X HelpLook携手,开启企业高效办公新时代

面对日益增长的工作负荷和追求效率优化的压力&#xff0c;企业知识的积累与传播显得愈发重要。如何系统化地沉淀员工与企业的知识精华&#xff1f;如何快速分享内外部知识&#xff1f;更重要的是&#xff0c;如何在获取这些知识后&#xff0c;迅速将其转化为精美的PPT&#xff…

抖店一件代发,从0到1操作全流程

我是王路飞。 先说明一点&#xff0c;新手不需要纠结抖店一件代发&#xff08;即无货源模式&#xff09;还能不能做的问题。 无货源只是前期帮助新手阶段的你进入到这个市场里来的一种方式&#xff0c;不是你长期做店的思路。 入门之后&#xff0c;基本就转型为有货源去玩了…

漫画|基于SprinBoot+vue的漫画网站(源码+数据库+文档)

漫画网站 目录 基于SprinBootvue的漫画网站 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大…

node 版本对应的 node-sass 版本号

当我们在项目中使用 node-sass 时&#xff0c;电脑的 node版本号一定要与 node-sass 版本号对应&#xff0c;不对应时下载就会报错 ❌问题&#xff1f;node-sass: Command failed. ✅解决方案&#xff0c;可能是node 跟 node-sass版本不一致 1、查询node版本 node -v &#…

RabbitMQ - SimpleMessageListenerContainer的实现逻辑

RabbitMQ - SimpleMessageListenerContainer的实现逻辑 Queue&#xff08;队列&#xff09;&#xff1a;在 RabbitMQ 中用于存储消息的数据结构。生产者将消息发送到队列中&#xff0c;而消费者从队列中接收消息。 Connection&#xff08;连接&#xff09;&#xff1a;连接是应…

Unity 实现心电图波形播放(需波形图图片)

实现 在Hierarchy 面板从2D Object 中新建一个Sprite&#xff0c;将波形图图片的赋给Sprite。 修改Sprite 的Sprite Renderer 组件中Draw Mode 为Tiled, 修改Sprite Renderer 的Size 即可实现波形图播放。 在Hierarchy 面板从2D Object 中新建一个Sprite Mask 并赋以遮罩图片…

【学习笔记】Windows GDI绘图(六)图形路径GraphicsPath详解(中)

上一篇【学习笔记】Windows GDI绘图(五)图形路径GraphicsPath详解(上)介绍了GraphicsPath类的构造函数、属性和方法AddArc添加椭圆弧、AddBezier添加贝赛尔曲线、AddClosedCurve添加封闭基数样条曲线、AddCurve添加开放基数样条曲线、基数样条如何转Bezier、AddEllipse添加椭圆…

2024年了, 你还不会使用node.js做压力测试?

前些天刷抖音&#xff0c;看到网传的Java继父&#xff0c;求人攻击压测他的网站&#xff0c;这不得摩拳擦掌。 所以今天来聊聊如何对自己的项目、接口进行压力测试。 压力测试的目的 首先, 绝对不是为了压测、攻击别人的网站为乐。 1、探索线上系统流量承载的极限&#xff…

python批发模块的调试之旅:从新手到专家的蜕变

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、调试技巧的重要性 二、批发模块调试的实战演练 1. 设置断点 2. 逐行执行代码 3. 观察…

安全风险 - 检测Android设备系统是否已Root

在很多app中都禁止 root 后的手机使用相关app功能&#xff0c;这种场景在金融app、银行app更为常见一些&#xff1b;当然针对 root 后的手机&#xff0c;我们也可以做出风险提示&#xff0c;告知用户当前设备已 root &#xff0c;谨防风险&#xff01; 最近在安全检测中提出了一…

【博主推荐】HTML5实现520表白、情人节表白模板源码

文章目录 1.设计来源1.1 表白首页1.2 甜蜜瞬间11.3 甜蜜瞬间21.4 甜蜜瞬间31.5 甜蜜瞬间41.6 甜蜜瞬间51.7 甜蜜瞬间61.8 永久珍藏 2.效果和源码2.1 页面动态效果2.2 页面源代码2.3 源码目录2.4 更多为爱表白源码 3.源码下载地址 作者&#xff1a;xcLeigh 文章地址&#xff1a;…

行业首发 | MS08067-SecGPT(送邀请码)

一、简介 MS08067-SecGPT基于LLM大模型技术专门为网络安全领域设计的智能助手&#xff0c;集问答、分析、工具为一体的对话式安全专家&#xff0c;支持可以创建多会话问答。目的是辅助用户完成网络安全相关的工作&#xff0c;学员通过问答方式体验到SecGPT所具备的威胁情报分…

mySql从入门到入土

基础篇 在cmd中使用MYSQL的相关指令&#xff1a; net start mysql // 启动mysql服务 net stop mysql // 停止mysql服务 mysql -uroot -p1234//登录MYSQL&#xff08;-u为用户名-p为密码&#xff09; //登录参数 mysql -u用户名 -p密码 -h要连接的mysql服务器的ip地址(默认1…

开源博客项目Blog .NET Core源码学习(25:App.Hosting项目结构分析-13)

本文学习并分析App.Hosting项目中后台管理页面的文章管理页面。   文章管理页面用于显示、检索、新建、编辑、删除文章数据&#xff0c;以便在前台页面的首页、文章专栏、文章详情页面显示文章数据。文章管理页面附带一新建及编辑页面&#xff0c;以支撑新建和编辑文章数据。…

智慧平安小区建设方案:EasyCVR视频+AI能力全面提升小区安全管理水平

随着城市化进程的加快和科技的不断发展&#xff0c;智慧平安小区建设成为了提升社区治理水平和居民安全感的重要手段。TSINGSEE青犀EasyCVR智慧平安小区平台采集汇总智慧小区各类视频资源基础数据&#xff0c;进行分级分类管理&#xff0c;并为公安、政法、大数据局、街道社区等…

从零开始:Spring Boot项目中如何集成并使用Infinispan

一、介绍 Infinispan 其实就是一个分布式缓存和数据网格平台&#xff0c;提供了高度可扩展和高性能数据缓存解决方案。Infinispan可以作为本地缓存或分布式缓存使用&#xff0c;支持事务、查询、处理大数据等功能。简单地说&#xff0c;Infinispan 可以理解为是 MySQL 的内存版…

docker容器安装nexus3以及nexus3备份迁移仓库数据

一、安装步骤 1.搜索nexus3镜像 docker search nexus3 2.拉取镜像 docker pull sonatype/nexus3或者指定版本 docker pull sonatype/nexus3:3.68.0 3.查看拉取的镜像 docker images | grep "nexus3" 4.启动nexus服务 直接启动 docker run -d --name nexus3 -…

优于InstantID!中山大学提出ConsistentID:可以仅使用单个图像根据文本提示生成不同的个性化ID图像

给定一些输入ID的图像&#xff0c;ConsistentID可以仅使用单个图像根据文本提示生成不同的个性化ID图像。效果看起来也是非常不错。 相关链接 Code:https://github.com/JackAILab/ConsistentID Paper&#xff1a;https://ssugarwh.github.io/consistentid.github.io/arXiv.pd…