编写包含局域网通信功能和物理引擎效果的WebGL场景

 一、执行效果:

1、正确配置服务并访问页面后:

world、a、b三个用户存在于同一场景中(在实际应用时应该分别使用不同的显示设备),a、b是普通用户,在场景中用一个球体表示,world是裁判用户,不在场景中显示实体。场景中心有一副扑克牌,裁判用户能够看到牌面,而普通用户只能看到卡背。每个用户可使用WASD、空格、Shift和鼠标控制自身的移动,其位置和姿态变化能够被其他用户实时感知。

2、world用户测试物理引擎:

world用户点击鼠标左键可以向光标方向发射具有物理效果的小方块,小方块在接触到场景边界或其他物理对象时将发生碰撞。

3、抓牌同步

普通用户(这里以a为例),点击牌堆时将从牌堆抓取卡牌,其他用户将能实时围观这一动作,卡牌到达a的手中后将显示卡面。

4、出牌同步

a用户按一下Alt键切换光标控制模式,点击一张手牌,被选中的手牌将显示橙色边框,再按Alt键则准星变为橙色,在橙色准星状态下点击左键,将带有物理效果的红桃2打出(为了显示的更明显加大了卡片的反弹系数)

5、整体场景

二、服务端部署与前端访问方法:

1、从https://github.com/ljzc002/CardSimulate或https://down.51cto.com/data/2461249下载工程

2、下载安装h2数据库软件,将playground.mv.db和playground.trace.db放入h2文件夹的同级目录,复制完毕后启动数据库。这个数据库中保存了初始的用户身份信息(TB_USER)、卡牌属性信息(TB_UINTTYPE)和用户掌控卡牌信息(TB_USERUNIT)。

如我的h2数据库最外层目录为h2-2017-06-10,其内为h2文件夹的同级目录。

这个数据库的JDBC驱动类为org.h2.Driver,URL为jdbc:h2:tcp://127.0.0.1/../../playground,用户名密码均为playground。

3、首先确保系统支持64位JDK1.8。将从Github下载的代码放入已有的SpringBoot2工程,或者用IntelliJ IDEA 打开从51CTO下载的完整工程(其中前端代码并非最新,可从Github替换),等待IntelliJ IDEA根据pom.xml自动安装依赖,导入完成后的工程结构如下图:

这里我使用SpringBoot进行包管理,用Netty实现WebSocket功能,用SpringBoot的内置Tomcat处理http请求,用druid作为数据源,读者也可以考虑用其他方式实现这些功能。

4、端口配置

这里默认使用8181作为http监听端口,用2323作为WebSocket监听端口,可以在application.yml文件中修改后端监听配置,可在login.html和KingoftheHill2.html中修改前端的默认访问端口。

5、打包和启动

在playground目录下执行mvn clean package或执行package.bat将工程打包为一个jar包。

执行java -jar ./target/netty_test01.jar或startjar.bat启动刚才生成的jar包(这个jar包包括了运行所需的所有依赖,可以剪切到其他目录启动)

出现“Netty开始监听:2323”,且无报错信息说明服务启动成功。

6、在与服务器处于同一网段的设备上,用Chrome浏览器访问http://127.0.0.1:8181/HTML/login.html(IP和端口号要根据实际情况修改),打开用户登录页面。

输入用户名密码,如果之前不存在此用户则以此用户名密码新建用户,如果已存在此用户名则尝试以此密码登录。

为了方便操作,这里使用非常宽松的身份验证规则,一次登录成功后即在浏览器本地存储中建立一个不会过期的token,凭此token这个浏览器将可以不受限制的随时访问全部前后端资源,一个浏览器也可以同时存储多个用户的token,以支持一机多开。特别强调此种身份验证不适用于需要保密的场合。

这里认为本系统的用户之间相互熟悉、相互信任,且假设用户之间能够及时高效的进行线下沟通,身份验证只是为了方便多用户的合作分工而设。

需要注意的是浏览器对每个IP和端口都建立独立的本地存储,所以更换IP和端口后需要重新登录,但原用户的信息(比如控制的单位)仍然不变(保存在数据库中)。

7、导航页面:

这是一个参考时下流行的信息系统导航页结构,用原生JavaScript编写的导航页面,登录时填写的信息以window.location.hash的形式传递进来,即使关闭此导航页,用户也将一直在数据库中保持激活状态,随时可以再次连接,直到点击右上角的“退出登录”按钮,用户才会在数据库中被置为不可用。

导航菜单栏内容在Index.js的InitMenu方法中定义:

复制代码
1 var arr_user = [ 2                 ["测试菜单","./PAGE/chat.html","bg/pic_test","test","unique"], 3                 ["WS初始化测试","./PAGE/KingoftheHill2.html","bg/pic_test","test","unique"], 4                 ["在新窗口中打开","./PAGE/OpenWindow.html"5                     ,"bg/pic_test","test","unique"] 6             ];
复制代码

数组中的参数分别表示菜单名、菜单对应url、菜单所属菜单组的图标、菜单所属的菜单组、这种菜单只能打开一个,在实际使用时可以考虑从数据库按用户权限进行菜单加载。

8、点击“在新窗口中打开”菜单,打开真正的WebSocket页面,这里使用world用户进行所有的物理引擎计算和动画计算,普通用户只向world提交操作请求以及渲染world的计算结果,所以在运行时需要先打开world用户的WebSocket页,再打开其他用户的WebSocket页(但登录顺序没有要求)。

关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信