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

初始化项目以及通过dapp-kit连接钱包的部分就不再赘述,具体可以点击查看,如果篇幅当中遇到了一些未添加的依赖项,直接通过pnpm add -D <name>一般都可以解决。

一:链上网络切换

这里提供一个最简单的切换方式,不需要放置下拉框,也不需要添加任何其它更多的设置,只需要在调用SuiClientProvider的时候增加一个参数onNetworkChange={(network) => setNetwork(network)},它的作用是当Sui钱包插件改变链上网络的时候触发setNetwork方法,并将新的链上网络传入设置。

tsx 复制代码
function App() {
	const queryClient = new QueryClient();
	const [network, setNetwork] = React.useState("testnet");
	const networks = {
		testnet: { url: getFullnodeUrl('testnet') },
		mainnet: { url: getFullnodeUrl('mainnet') },
	};

	return (
		<div>
			<QueryClientProvider client={queryClient}>
				<SuiClientProvider networks={networks} network={network as keyof typeof networks} onNetworkChange={(network) => setNetwork(network)}>
					<WalletProvider>
						<div className='ConnectButton'>
							<ConnectButton />
						</div>
						<MineClearance />
						<FeedBack />
					</WalletProvider>
				</SuiClientProvider>
			</QueryClientProvider>
		</div>
	);
}

二:游戏区域

首先是一个开始游戏的按钮,它的运行逻辑要在连接钱包之后,因为后面与链上的交互都需要事先明确"我是谁"。

tsx 复制代码
function MineClearance() {
	const account = useCurrentAccount();

	const StartGame = () => {
		document.getElementById('NotConnect')!.hidden = true;

		if (!account) {
			document.getElementById('NotConnect')!.hidden = false;
			return;
		}

		// console.log("Connected");
		return;
	};

	return (
		<div className='Game'>
			<div className='StartButton'>
				<Button variant="contained" onClick={StartGame}>Game</Button>
				<br></br>
				<i id="NotConnect" hidden={true}>Please Connect First!!!</i>
			</div>
			<div id='Checkerboard'>
				<DrawCheckerboard />
			</div>
		</div>
	);
}

其次我们来考虑扫雷区域该如何进行描绘,很自然联想到,它是由一个又一个小方块依次拼接而成的,而mui正好又提供了一系列的ButtonGroup,所以问题就简化成了如何通过循环进行处理这些个按钮,包括放置、点击以及后续得到反馈后实时更改按钮状态等等。

本篇只涉及放置以及最基本的点击逻辑,而链上调用以及反馈信息处理等部分将留到下一篇文章。

tsx 复制代码
function DrawCheckerboard() {
	const clickBoard = (event: any) => {
		const r = event.target.getAttribute('button-key')
		const l = event.target.parentElement.getAttribute('button-key');
		console.log(`(${r}, ${l})`);

		let str1 = event.currentTarget.innerHTML.split('<', 1)[0];
		const str2 = event.currentTarget.innerHTML.substring(str1.length);
		str1 = str1 == "x" ? "1" : "x";
		const str = str1.concat(str2);
		console.log(str);
		event.currentTarget.innerHTML = str;

		event.target.disabled = true;

		HiddenFeedBack();
		ShowFeedBack("circular_progress");
		// ShowFeedBack("success_alert");
		// ShowFeedBack("encourage_alert");
		// ShowFeedBack("failure_alert");
	}

	const childboard = [];
	let i = 1;
	while (i <= MaxRow) {
		childboard.push(<Button key={i} button-key={i} size="large" onClick={clickBoard} sx={{width: "1px"}}>&nbsp;</Button>);
		i += 1;
	}

	const checkerboard = [];
	let j = 1;
	while (j <= MaxList) {
		checkerboard.push(<ButtonGroup orientation='vertical' aria-label='Vertical button group' variant='outlined' key={j} button-key={j}>{childboard}</ButtonGroup>);
		j += 1;
	}

	return (
		<Box>
			{checkerboard}
		</Box>
	);
}

三:提示信息

mui提供了加载等待、成功失败提示等ui选择,我们直接选取其中的一些进行调用,目的是当后续实现了链上调用后的信息反馈,包括但不限于游戏成功、游戏失败等提示信息。

这些信息出现的位置应当是游戏区域下方,而且若非特殊需求,应当一次只出现一个,其它的都应该隐藏,这里就需要令写函数对这系列的<div>标签进行统一管理。

tsx 复制代码
function FeedBack() {
	return (
		<div className='FeedBack'>
			<div id="circular_progress" hidden={true}>
				<CircularProgress />
			</div>
			<div id="success_alert" className='SuccessAlert' hidden={true}>
				<Alert variant="outlined" severity="success">
					Congratulations on your successful mine clearance!
				</Alert>
			</div>
			<div id="encourage_alert" className='EncourageAlert' hidden={true}>
				<Alert variant="outlined" severity="info">
					Fortunately you didn't touch a landmine, please consider your next step!
				</Alert>
			</div>
			<div id="failure_alert" className='FailureAlert' hidden={true}>
				<Alert variant="outlined" severity="error">
					Unfortunately, the minesweeper failed!
				</Alert>
			</div>
		</div>
	);
}

function ShowFeedBack(id: string) {
	// document.getElementById(id)!.hidden = false;
	if (id == "circular_progress")
		document.getElementById(id)!.hidden = false;
	else
		document.getElementById(id)!.style.display = "inline-flex";
}

function HiddenFeedBack() {
	document.getElementById("circular_progress")!.hidden = true;
	// document.getElementById("success_alert")!.hidden = true;
	// document.getElementById("encourage_alert")!.hidden = true;
	// document.getElementById("failure_alert")!.hidden = true;
	document.getElementById("success_alert")!.style.display = "none";
	document.getElementById("encourage_alert")!.style.display = "none";
	document.getElementById("failure_alert")!.style.display = "none";
}

这里的实现方式多样,呈现的只是其中一种也绝非是最优解,毕竟自己看着都有点累赘(后面可能会视情况更改)。

四:其它

完整代码可以点击查看,下面是几张实际运行图。

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

相关推荐
酷爱码1 分钟前
css中的 vertical-align与line-height作用详解
前端·css
沐土Arvin15 分钟前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
专注VB编程开发20年16 分钟前
VB.NET关于接口实现与简化设计的分析,封装其他类
java·前端·数据库
小妖66626 分钟前
css 中 content: “\e6d0“ 怎么变成图标的?
前端·css
L耀早睡1 小时前
mapreduce打包运行
大数据·前端·spark·mapreduce
HouGISer1 小时前
副业小程序YUERGS,从开发到变现
前端·小程序
outstanding木槿1 小时前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
霸王蟹2 小时前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹2 小时前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
专注VB编程开发20年2 小时前
asp.net IHttpHandler 对分块传输编码的支持,IIs web服务器后端技术
服务器·前端·asp.net