网管小贾 / sysadm.cc
我有一哥们“烧鸡”,大名白赞记。
光听名字就感觉挺大气是吧,其实和我一样就是个不起眼的普通90后。
虽说这小子年纪轻轻,人却比较怀旧,尤其痴迷红白机之类的复古游戏(当然我也喜欢)。
很奇怪的是到现在好像有两个月没见着这小子了,没成想前两天在菜市场门口给撞上了。
搁以前只要一打照面这小子铁定三句话不离游戏,不过这回好像有点不一样了。
我一瞅他购物袋里那一片绿油油就大概知道怎么回事了。
果不其然,这小子一上来就和我吐槽最近过得有多惨,然后又怀念上以前那小日子有多美。
以前划水摸鱼、带薪拉屎,想怎么玩就怎么玩,别提多得劲了,可如今日薄西山、今非昔比,好日子是一去不复返啊!
自从换了新东家,不但工作忙得脚后跟直打后脑勺,而且上下班通勤时间都比原先拉长了好多。
这小子一顿扒拉扒拉,直言少壮不努力,老大徒伤悲,这整得都没空玩游戏了。
我去,这小嘴儿巴巴的,我愣是插不上话!
得,江山易改,这本性难移啊,我一瞅这小子还这副德性,硬是把想劝慰的话又给咽了回去。
好么,接着听这小子闲聊扒拉,结果他告诉我,还好有时还能偷懒玩一会在线红白机游戏。
“只要打开浏览器就行,不用安装任何软件,随时随地方便非常。”
“哦,是么,还能这么玩?呵呵...”,我得配合尬笑一下,做出我非常好奇的样子接着听他吹。
我心想他说的这个在线红白机游戏我知道,就是通过 Web 网页呈现,并且可以和正常模拟器一样地玩游戏。
这个我是见过,没啥新鲜,瞧这小子眉飞色舞那得瑟样......
不知道是不是我当时的表情演技有点过劲儿,他顿了一下,冷不丁地问了我一句:“这玩意挺好挺方便,你有空也玩两把哈!只是不知道这玩意是啥原理,怎么给整出来的,挺牛叉滴!”
俗话说,言者无心,听者有意!
过后三言两语我打发了这小子,事后在回家的路上我就琢磨了,是哈,这玩意是怎么做到只要打开网页就能玩红白机游戏的呢?
JSNES带着疑问,我打开了电脑开始在网上搜索,心里正猜测这个红白机在线玩功能是不是基于 JS 的,还是说有其他高深的知识在里面。
果然很快我找到了 Github 上的一个项目:JSNES 。
https://github.com/bfirsh/jsnes
作者 bfirsh 大神还有一个个人主页:
https://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 上查看吧。
截图:
在线演示:
<平台所限,请跳转至以下链接体验~>
https://www.sysadm.cc/index.php/youxisuipian/986-how-to-make-an-online-fc-nes-game-system-of-the-web-version复杂一些的 JSNES项目不知道前面的例子各位小伙伴感觉如何?
我估计会有人吐槽,还是有 BUG ,不能换游戏,不能调画面,不能改按键,不能......
哎,总之那只是个简单的不能再简单的示例程序,更加复杂的功能肯定是没有的啊!
想要拥有这些高级而复杂的功能,要么你会写代码给加上去,要么只能寄希望于大神恩赐了。
不过还好,我这儿找到一位大神 dafeiyu ,他有个项目实现了比较复杂一些的在线游戏功能。
https://gitee.com/feiyu22/jsnes
当然了,和前面 bfirsh 类似,并不是将源代码拉过来就能用的,还是要进行一番改造。
万幸的是,dafeiyu 已经做了很多工作,项目的安装也变得比较简单,只要将几个文件夹复制下来就行了。
具体怎么做,我们接着往下看!
首先,将项目打包下载。
将压缩包中的三个文件夹( lib 、 roms 、 src )解压出来。
lib - 库文件roms - 游戏文件src - 在线游戏源码及脚本其中我们主要需要修改 src 文件夹内的主网页文件 index.html ,最多再改一改界面脚本 ui.js ,其他的文件基本上不需要大动。
和前一小节一样,最后还是要找个 Web 服务器,让它跑一跑看看。
建议用我写的 VBRichClient4WebServer.exe 程序,绿色环保双击直接就能用,已将其打包到文末下载中。
虽说这个代码基本能用,但小毛病实在太多了,我精力和水平有限,改了一些地方,比如放大缩小功能等等。
我将最终改好的演示示例放在这儿,大家试玩一下。
截图:
在线演示:
<平台所限,请跳转至以下链接体验~>
https://www.sysadm.cc/index.php/youxisuipian/986-how-to-make-an-online-fc-nes-game-system-of-the-web-version总体来讲 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 。
下载链接:https://pan.baidu.com/s/1sDzcmVxSnP5sqXNKAs7dxw
提取码:<关注公众号,发送 000986>
动图演示用法
需要向小伙伴们说一下,我打包的这些程序并非完美版本,仍然还有修改增加功能的余地,请有余力的小伙伴自行调整吧。
另外需要注意的是,程序并不是支持所有的 ROM 游戏,原因有待研究。
关于 JsNes 如果我的文章有什么错误,或者你有好的想法和建议,欢迎留言评论。
最后,请各位排好队,点赞、关注、分享转发。
对了,谁有葱借我点,刚菜场忘记买了,回家又要被骂了......
将技术融入生活,打造有趣之故事。
网管小贾 / sysadm.cc