如何基于声网互动白板实现一个多人数独游戏

news2024/11/25 10:56:31

本文作者是声网社区的开发者“tjss”。他基于 Vue、声网的互动白板的代码模板,搭建出了一个支持多人互动的数独游戏。本文记录了他的实现过程,欢迎大家也可以尝试实现自己的小游戏或应用。

我基于声网互动白板的 SDK 与 Window Manager 开发了一个场景化窗口插件,实现了一个多人数独游戏。在游戏中,每个玩家进入白板房间,都能看到数独游戏插件,同时可以参与其中,与房间内的小伙伴一起完成数独解题。

前期准备

1、注册一个声网账号,并实名认证,以便在后台创建项目,获取开发时会用到的 Appid 和 Token。

2、了解 Vue 开发的基础知识。

3、了解声网互动白板产品,一些基本的接口和功能,看官方文档就足够了。

4、搭建开发环境:

  • NodeJs 版本 16.0.0

  • @Vue/cli 4.5.1

  • VSCode 代码开发工具

开启和配置互动白板服务

首先我们需要一个实名认证的声网账号,进入控制台(console.agora.io),在声网控制台开启互动白板服务。

这里需要注意的是互动白板是作为服务而显示的,而控制台中只是显示项目列表,并没有直接显示服务。

在这里插入图片描述

这时候我们就先创建一个项目,然后点击“配置”进入到项目详情中,在里面的页面就可以看到服务内容了。

这时候找到互动白板服务,点击开启就行。因为我的已经开启了,所以显示的是配置按钮。

在这里插入图片描述

使用官网提供的代码模板

场景化窗口插件目前我们不需要从零开始建立的,声网提供了一个代码模板,基于此模板我们可以很轻松就能实现一个在互动白板上使用的插件。

模板地址:

https://github.com/netless-io/community-app-template

当搭建好开发环境后,便可以下载模板代码了,通过 Git 或者下载 Zip 都行。

需要注意 README.md 中的开发环境配置:

1、在 .env 文件里配置白板房间 UUID 和 Token请将本目录下的 .env.example 文件复制一份,重命名为 .env 或 .env.local 后,在里面填写必须的白板配置信息。你可以在 Netless Workshop 申请专用的白板配置。

2、执行 npm install 安装依赖

3、执行 npm start 进行本地开发

项目结构

笔者是基于 Vue 版本的插件模板进行开发的,直接打开项目,修改 src 里的内容即可,基本上和 Vue 开发一致。如果是通过 Git 命令拉取的代码,需要切换分支为 Vue 分支。

  • 项目结构如下:

在这里插入图片描述

  • playground 目录是基本不用修改的,我们实现的插件是在 src 目录中完成的。

  • index.ts 文件是我们插件的一些数据设置,比如插件名称。其他逻辑基本不用修改。

onst Sudoku: NetlessApp = {
  kind: "Sudoku",
  setup(context) {
    const box = context.getBox();
    box.mountStyles(styles);
    const $content = document.createElement("div");
    $content.className = "app-counter";
    box.mountContent($content);
    const app = createApp(App).provide("context", context);
    app.mount($content);
    context.emitter.on("destroy", () => {
      app.unmount();
    });
  },
};
export default Sudoku;

数独游戏规则

数独网格由 9x9 个空格组成。玩家只能使用数字 1 到 9,每个 3×3 宫只能包含数字 1 到 9,每一列只能包含数字 1 到 9,每一行只能包含数字 1 到 9,每个 3×3 宫、每一列或每一行中的每个数字只能使用一次。当所有数独网格都填入正确的数字时,游戏结束。(摘自网上)

数据同步核心思路

1、通过互动白板SDK提供的 createStorage 方法,初始化一个数独棋盘,并把数据存储起来,同时需要更新自己的 chessBoard。

const chessBoard = ref();
const context = inject<AppContext>("context");
const storage = context.createStorage("chessBoard", { chessBoard: ChessBoard.init() });
chessBoard.value = deepCopy(storage.state.chessBoard)

2、在 Vue 界面的 onMounted 回调函数中添加存储值的更新监听,这样玩家在填格子的时候广播了最新的格子数据,其他玩家就能收到更新的通知,然后重新渲染界面。

onMounted(() => {
  initAppData()
  storage.addStateChangedListener((diff) => {
    chessBoard.value = deepCopy(diff.chessBoard?.newValue)
    if (finish(chessBoard.value.gridItems)) {
      statistics(chessBoard.value.gridItems)
      finishTag.value = true
    }
  })
});

3、填格子的时候,通过 SDK 的 setState 方法去更新数独棋盘的数据。

if (e.data && e.data > 0) {
    grid.number = parseInt(e.data)
    grid.userId = uid.value
    grid.color = rgb
  } else {
    grid.number = 0
    grid.userId = ''
    grid.color = new Rgb(233, 233, 233)
  }
  storage.setState({ chessBoard: chessBoard.value })

数独游戏界面

笔者是优先实现这个互动游戏的核心功能,所以设计出的游戏界面比较简陋。

在这里插入图片描述

数独的数据结构

export class ChessBoard {
    gridItems: GridItem[][]
}

因为需要统计游戏结束后,各个玩家填写的个数,所以在更新格子数值的时候也记录一下是哪一位玩家填写了。default 字段表示该格子是自动生成的,不需要玩家填写了。

export class GridItem {
    number: number
    color: Rgb
    userId: string
    default: boolean
}

运行项目

点击工具栏最下方的按钮,可以找到我们实现的插件icon,然后点击即可打开。

在这里插入图片描述

打开插件后,会初始化创建一个数独题目,并且通过 createStorage 方法储存起来,所有进入房间的玩家都能拿到这个数据,后续数独的更新都会同步给玩家去修改。因为这个项目重点是学习一下插件开发与数据同步,所以游戏界面以及内容这些做的比较简单。

在这里插入图片描述

接下来就要打开多个网页并且输入 localhost:3000 进入我们的互动白板房间了,因为模板的uid是随机生成的,也就表示有不同的玩家进入了。

在这里插入图片描述

别的玩家填写后,其他玩家是不能再填这个格子的,最后游戏结束的时候,会统计各个玩家所填对的数字并展示。

在这里插入图片描述

游戏结束

在这里插入图片描述

总结

通过官方提供的场景化插件模板,我们很容易实现一些好玩的互动场景的功能。在这个简单的项目中,由于时间仓促,还没来得及优化得更好,后续有时间的时候笔者再打磨一下。比如不同玩家填写的数字以不同的颜色区分,增加限时机制等等。感兴趣的朋友一起来开发一些好玩的实时互动功能吧~


现注册声网 SDK,可获得每月免费 10000 分钟使用额度。如在开发过程中遇到疑问,可在声网开发者社区与官方工程师交流。

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

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

相关文章

第二十三周周报

学习内容&#xff1a; 修改ViTGAN代码 学习时间&#xff1a; 2.3-2.10 学习产出&#xff1a; 现在的效果 可以看到在700k左右fid开始上升&#xff0c;相比vitgan&#xff0c;改的vitgan鉴别器loss有所下降&#xff0c;但是fid没有降下来&#xff0c;最好为23.134&#xf…

Elasticsearch7.8.0版本进阶——分布式集群(水平扩容)

目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装&#xff08;win10环境&#xff09;1.2、Elasticsearch集群的安装&#xff08;linux环境&#xff09;二、水平扩容&#xff08;win10环境集群演示&#xff09;三、想要扩容超过 6 个节点怎么办3.1、主分片和副分片…

IDEA合并分支(从开发分支到测试分支)

IDEA合并分支(从开发分支到测试分支) 1、先在当前分支拉去最新的代码且提交自己的修改到远程分支上 2、切换到目标分支(你要合并到的分支上),test测试分支 3、进行分支合并,这里其实有3个选项比较常用 ①Compare with ‘test’ 与当前分支(test)比较,这个比较回弹出个窗口…

刷爆网络的ChatGpt,给大家搞来了。

最近chatgpt可谓是顶上了热搜&#xff0c;之前写代码的同学们应该都知道出了一款插件叫做 Copilot&#xff0c;这是一款可以帮你自动写代码的插件&#xff0c;只要输入你想要写的代码&#xff0c;比如写一个js轮播图之类的&#xff0c;立马就可以帮你生成。不仅如此&#xff0c…

随着攻击者适应绕过零信任,公司在苦苦挣扎

商业情报公司 Gartner 表示&#xff0c;零信任安全方法有望减少威胁并降低成功攻击的破坏性&#xff0c;但公司不应期望实施零信任原则会很容易或阻止大多数攻击。 虽然对零信任架构的兴趣很高&#xff0c;但目前只有大约 1% 的组织拥有满足零信任定义的成熟程序。 该公司还估…

论文投稿指南——中文核心期刊推荐(石油、天然气工业 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

【火电机组、风能、储能】高比例风电电力系统储能运行及配置分析(Matlab代码实现)

目录 摘 要 0 目标函数和约束条件 1 第一题 2 第二题 3 第三题 4 第四题&#xff1a;含高比例风电电力系统最小供电成本模型 6 第六题&#xff1a; 7 第七题&#xff1a; 8 所有题代码及文章详细讲解 9 结论&#xff1a; 10 参考文献 摘 要 高比例风电电力系统储…

JVM——运行期优化

目录一、分层编译&#xff08;TieredCompilation&#xff09;即时编译器&#xff08;JIT&#xff09;与解释器的区别逃逸分析二、方法内联&#xff08;Inlining&#xff09;三、反射优化一、分层编译&#xff08;TieredCompilation&#xff09; JVM 将执行状态分成了 5 个层次…

宜家EDI IFTMBC运输预定确认详解

IFTMBC是宜家与其供应商之间传输的符合EDIFACT标准的报文&#xff0c;在此前的文章如何读懂EDIFACT报文中&#xff0c;我们已经对EDIFACT做了详细的解读。在供应商发给宜家IFTMBF运输预定请求后&#xff0c;宜家会回复IFTMBC运输预订确认给供应商。 本文将从供应商接收宜家发送…

【Java|golang】1798. 你能构造出连续值的最大数目

给你一个长度为 n 的整数数组 coins &#xff0c;它代表你拥有的 n 个硬币。第 i 个硬币的值为 coins[i] 。如果你从这些硬币中选出一部分硬币&#xff0c;它们的和为 x &#xff0c;那么称&#xff0c;你可以 构造 出 x 。 请返回从 0 开始&#xff08;包括 0 &#xff09;&a…

预处理和宏

1.预处理的基本概念 C语言对源程序处理的四个步骤&#xff1a;预处理、编译、汇编、链接。 预处理是在程序源代码被编译之前&#xff0c;由预处理器&#xff08;Preprocessor&#xff09;对程序源代码进行的处理。这个过程并不对程序的源代码语法进行解析&#xff0c;但它会把…

EL表达式

EL的概念JSP表达式语言&#xff08;EL&#xff09;使得访问存储在JavaBean中的数据变得非常简单。EL的作用用于替换作用域对象.getAttribute("name");3. EL的应用&#xff08;获取基本类型、字符串&#xff09;既可以用来创建算术表达式也可以用来创建逻辑表达式。在…

stm32f407探索者开发板(十四)——IO引脚复用和映射

文章目录一、端口复用二、STM32F4的端口复用映射原理三、复用功能映射设置四、端口复用配置过程一、端口复用 端口复用和重映射都是和单片机的I/O口有关系&#xff0c;端口复用是将一个I/O赋予多个功能&#xff0c;通过设置I/O的工作模式来切换不同的功能。重映射是将某些I/O口…

【运维有小邓】特权用户监视

解决方案简介&#xff1a; 使用EventLog Analyzer进行特权用户监控和审核内部用户活动报表企业IT网络的特权用户&#xff08;系统管理员、网络管理员和数据库管理员&#xff09;拥有比普通网络用户更多的权力。他们负责保持系统可用性。他们将有权创建新的用户配置文件并分配权…

PCIE总线

PCIE总线记录描述PCI分类与速度PCIE连接拓扑与角色PCIE接口定义PCIE数据传输方式与中断在PCIE中有两种数据传输方式&#xff1a;PCIE中断&#xff1a;PCIE协议栈与工作流程PCIE地址空间分类实例分析PCIE两种访问方式描述 PCI-Express(peripheral component interconnect expre…

Python调用API接口,实现人脸识别

人生苦短&#xff0c;我用Python 在开始之前&#xff0c;先问问大家&#xff1a; 什么是百度Aip模块&#xff1f; 百度AI平台提供了很多的API接口供开发者快速的调用运用在项目中 本文写的是使用百度AI的**在线接口SDK模块&#xff08;baidu-aip&#xff09;**进行实现人脸识…

K100多功能嵌入吞吐式电动发卡读写一体机|读卡器技术选型问答

K100多功能嵌入吞吐式电动发卡读写一体机|读卡器技术是一款带卡槽&#xff0c;支持150张标准卡存放&#xff0c;电动式发卡、读写一体&#xff0c;支持磁条卡读卡&#xff0c;发卡&#xff1b;支持符合ISO7816协议的接触式芯片卡发卡&#xff0c;读写卡&#xff1b;支持符合ISO…

【C++详解】——vector类

&#x1f4d6; 前言&#xff1a;本期介绍vector类。 目录&#x1f552; 1. vector的介绍&#x1f552; 2. vector的使用&#x1f558; 2.1 定义&#x1f558; 2.2 iterator&#x1f558; 2.3 空间增长&#x1f558; 2.4 增删查改&#x1f552; 2. vector的模拟实现&#x1f558…

Springboot+ssm微空间私人定向共享文件资料系统java

目 录 1绪论 1 1.1项目研究的背景 1 1.2开发意义 1 1.3项目研究现状及内容 5 1.4论文结构 5 2开发技术介绍 7 2.1 B/S架构 7 2.2 MySQL 介绍 7 2.3 MySQL环境配置 7 2.4 Java语言简介 8 2.5Jsp技术 8 3系统分析 9 3.1可行性分析 9 3.1…

Android Studio 编译C/C++生成.so文件

前期准备&#xff1a;下载NDK、CMake方法一&#xff1a;使用AndroidStudio自动创建NativeC/C 项目创建新项目创建项目后&#xff0c;会默认生成两个文件和相关默认配置.若创建好C项目后报错&#xff0c;则需要配置一下NDK路径如果上图配置页面显示无法配置&#xff0c;则需要手…