24
2024
03
01:05:32

网页版的在线红白机游戏,怎么做到的?

JSNES

带着疑问,我打开了电脑开始在网上搜索,心里正猜测这个红白机在线玩功能是不是基于 JS 的,还是说有其他高深的知识在里面。

果然很快我找到了 Github 上的一个项目:JSNES 。

github.com/bfirsh/jsnes


作者 bfirsh 大神还有一个个人主页:

jsnes.org/


我们打开看看,简洁的全黑页面显得格外有内涵(花里胡哨你又说有艺术范),表格中简单罗列了几个用于演示的游戏。


随便点开一个游戏,比如 Concentration Room ,页面跳转并开始加载游戏。


不一会儿游戏加载完毕,我们就可以开始玩了。


在此期间点击右上角的 Controls 按钮可以调整修改自己惯用的按键。


很神奇对吧,操作也不复杂,很明显它就是基于 JavaScript 的一个 NES 模拟器。

那么这玩意怎么实现的呢?


关于 JSNES 的介绍倒是很简单,然而介绍页上面涉及到的诸如如何安装等等的 JS 理论知识却着实难倒了我,毕竟我只能算是半个野生程序员,稍微复杂一点的知识我就抓瞎了。

嗯,既然是 JS 写的,那么肯定是跑在浏览器上,我猜应该和服务端关系不大。

OK,那我们就来大胆一试吧!

测试 JSNES

怎么试?

我的思路很简单,就是将项目代码放到 Web 服务器上,然后用浏览器打开跑一跑看看,希望有门。


好,首先将 bfirsh/jsnes 源代码下载下来(文末统一下载)吧。


接着打开压缩包,找到文件夹 example ,将它释放出来备用。


这个 example 文件夹内有四个文件。

  • InterglacticTransmissing.nes - 演示游戏 ROM 文件

  • nes-embed.html - 网页文件

  • nes-embed.js - 自定义脚本文件

  • README.md - 说明文件


关于这四个文件,我们实际只用到前三个。

注意,除这三个文件之外呢,我们从 nes-embed.html 文件中可以看到,还需要引用 jsnes.min.js 文件。

<script type="text/javascript" src="https://unpkg.com/jsnes/dist/jsnes.min.js"></script>

这个文件就是 JSNES 实现的关键,我已经将它打包放到下载中了。


好,接下来我们需要修改一些代码,原先的演示示例存在很多 BUG ,以我现有的水平还不能将它们都搞定。

不过还好我修复了几个比较主要的地方,比如异步加载游戏时不显示的问题。


在页面文件 nes-embed.html 中有如下代码。

<script>window.onload = function(){nes_load_url("nes-canvas", "InterglacticTransmissing.nes");}</script>

这行代码的意思是在当前页面加载完成后再加载 nes 游戏并渲染到 canvas 上。

可是代码似乎还是有缺陷,涉及到使用原始代码来实现 AJAX 的异步提交,在使用 window.onload 时就不灵了,老是失败,游戏画面怎么也不显示。


此外还有修改按键功能的问题。

老外的按键习惯与我们有很大的不同,因此我们需要打开nes-embed.js 文件,将其中的按键修改为我们平时喜欢的使用方式。

设定按键的代码段如下:

function keyboard(callback, event){
    var player = 1;
    switch(event.keyCode){
        case 38: // UP
            callback(player, jsnes.Controller.BUTTON_UP); break;
        case 40: // Down
            callback(player, jsnes.Controller.BUTTON_DOWN); break;
        case 37: // Left
            callback(player, jsnes.Controller.BUTTON_LEFT); break;
        case 39: // Right
            callback(player, jsnes.Controller.BUTTON_RIGHT); break;
        case 65: // 'a' - qwerty, dvorak
        case 81: // 'q' - azerty
            callback(player, jsnes.Controller.BUTTON_A); break;
        case 83: // 's' - qwerty, azerty
        case 79: // 'o' - dvorak
            callback(player, jsnes.Controller.BUTTON_B); break;
        case 9: // Tab
            callback(player, jsnes.Controller.BUTTON_SELECT); break;
        case 13: // Return
            callback(player, jsnes.Controller.BUTTON_START); break;
        default: break;
    }
}


case 后面用于判断按键的数字是该按键的 ASCII 码,可以到官方查询。

https://www.ascii-code.com/

比如我们想将  、  、  、  设定为 W 、 S 、 A 、 D ,那么我们先要找到这几个按键的 ASCII 码,分别是十进制的 87 、 83 、 65 、 68 ,然后将它们写到代码中就可以了。


比如修正后的按键  ,应该是这样写。

case 87: // UP
    callback(player, jsnes.Controller.BUTTON_UP); break;


类似的 A 和 B 按钮也是一样操作,找相应 ASCII 码并修改为你喜欢的按钮。

具体我们可以参考 ASCII 码表来定位所要调用的按键。


最后我们需要找一个 Web 服务程序,什么 Apache 啊、Nginx 啊、IIS 啊,总之只要是 Web 服务器就行。

并且不需要具备任何动态脚本解释功能,原因很简单嘛,JS 在浏览器上就能跑。

不过说到的这些 Web 服务引擎总感觉有点重、不亲民啊,难道我还要特意去整这些玩意才能玩到游戏吗?


不知道算不算巧合,我在前不久使用 VBRichClient 做了一个简单的 Web 服务程序 VBRichClient4WebServer.exe 。

本来也没多想,这玩意功能超级简单用处不大,当玩具一样,没成想却在这儿就给派上用场了。

是的,有的小伙伴应该明白了,完全可以直接用我写的这个程序嘛,不用再费劲扒拉地去专门设定一个 Web 服务器了。


用法十分简单,绿色软件,双击打开就能用了(已打包到文末下载中)。

指定好根目录、 IP 地址和端口号,点击开启服务就能跑了。


最终经过我一番折腾,将它成功改造成了我想要的样子。

为了给小伙伴们更加真实的体验,同时我也将它放到了博客页面上,大家试玩一下看看。

如果你看不到以下内容,那么请点击原文链接或阅读原文,跳转到 www.sysadm.cc 上查看吧。


截图:


在线演示:

<平台所限,请跳转到以下链接体验~>

网管小贾 - 网页版的在线红白机游戏,怎么做到的?


复杂一些的 JSNES 项目

不知道前面的例子各位小伙伴感觉如何?

我估计会有人吐槽,还是有 BUG ,不能换游戏,不能调画面,不能改按键,不能......

哎,总之那只是个简单的不能再简单的示例程序,更加复杂的功能肯定是没有的啊!

想要拥有这些高级而复杂的功能,要么你会写代码给加上去,要么只能寄希望于大神恩赐了。


不过还好,我这儿找到一位大神 dafeiyu ,他有个项目实现了比较复杂一些的在线游戏功能。

gitee.com/feiyu22/jsnes


当然了,和前面 bfirsh 类似,并不是将源代码拉过来就能用的,还是要进行一番改造。

万幸的是,dafeiyu 已经做了很多工作,项目的安装也变得比较简单,只要将几个文件夹复制下来就行了。

具体怎么做,我们接着往下看!


首先,将项目打包下载。


将压缩包中的三个文件夹( lib 、 roms 、 src )解压出来。

  • lib - 库文件

  • roms - 游戏文件

  • src - 在线游戏源码及脚本


其中我们主要需要修改 src 文件夹内的主网页文件 index.html ,最多再改一改界面脚本 ui.js ,其他的文件基本上不需要大动。


和前一小节一样,最后还是要找个 Web 服务器,让它跑一跑看看。

建议用我写的 VBRichClient4WebServer.exe 程序,绿色环保双击直接就能用,已将其打包到文末下载中。


虽说这个代码基本能用,但小毛病实在太多了,我精力和水平有限,改了一些地方,比如放大缩小功能等等。

我将最终改好的演示示例放在这儿,大家试玩一下。


截图:


在线演示:

<平台所限,请跳转至以下链接体验~>

网管小贾 - 网页版的在线红白机游戏,怎么做到的?


总体来讲 dafeiyu 的代码基本的功能都有了,但还是无法和某些网站上的功能相比,例如支持双人、保存加载记录以及作弊码等等。

这些高级功能是如何实现的,有兴趣的话大家可以自行研究,如果以后我有新的突破那到时候再分享给大家吧。


容器化运行 JSNES

如果你不方便或实在懒得搭建 Web 服务,甚至连我写的 VBRichClient4WebServer 程序都不想用,那么也没啥,就问你有没有 Docker ?

好,你有 Docker ,那么恭喜你,JSNES 还可以做为容器跑服务的。

网上写得太复杂了,我将其大大简化了,只要你有现成的 Docker 就行。


首先我们先将镜像拉下来,如果网络不好拉不下来也别着急,我在文末下载中把镜像也打包进去了。

注意标签哈,不是 lastest ,而是 1.0.0 哦!

docker pull wangz2019/jsnes:1.0.0


接下来就可以直接运行镜像了。

对外暴露端口随便你指定,只要将 8081 改成你想要的就行。

docker run --rm -p 8081:80 --name jsnes -d wangz2019/jsnes:1.0.0


然后打开浏览器,在地址栏内输入以下网址,你自己看效果,我就不截图了。

http://服务器IP:8081/


哈哈,有没有成功打开?

好,要想关掉它也很简单,像下面这么干。

docker kill jsnes


整个过程简单粗暴,使用起来非常方便,只不过缺点就是里面的内容你不好改啊,这种仅适合体验。


写在最后

通过我自己的各种折腾测试,最后将凑合可用的程序给整理好打包,就放在这儿分享给小伙伴们吧!

声明:下载付费可以理解为付费阅读文章内容,如果你不想付费也完全没问题,但是无论付费与否,请尊重作者的辛苦劳动,谢谢理解和支持!


打包集中付费下载:

  • jsnes-bfirsh.7z - bfirsh 网管小贾修改版

  • jsnes-dafeiyu.7z - dafeiyu 网管小贾修改版

  • jsnes-master-bfirsh.zip - bfirsh 源码

  • jsnes-master-dafeiyu.zip - dafeiyu 源码

  • [Docker镜像]wangz2019_jsnes1.0.0.7z - 离线Docker镜像文件


基本用法:

1、运行 VBRichClient4WebServer.exe 程序。

2、将网管小贾修改版解压后释放到 VBRichClient4WebServer.exe 所在目录。

3、打开浏览器, bfirsh 版访问 http://ip:8888/nes-embed.html ,dafeiyu 版访问 http://ip:8888/src/index.html 。


下载链接:pan.baidu.com/s/1sDzcmV

提取码:<关注公众号,发送 000986>


动图演示用法


需要向小伙伴们说一下,我打包的这些程序并非完美版本,仍然还有修改增加功能的余地,请有余力的小伙伴自行调整吧。

另外需要注意的是,程序并不是支持所有的 ROM 游戏,原因有待研究。




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/5559.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: