Flash 重生 | Ruffle 使用指南
使用 Ruffle 项目运行 Flash 的 swf 文件,让经典游戏和动画在现代浏览器上重获新生。
唠唠闲话
2020 年底,Adobe Flash Player 正式停止更新和支持,那些曾经陪伴我们成长的经典 Flash 游戏和动画似乎注定要被时代遗忘。从 4399 小游戏到 QQ 宠物,这些曾经的网络文化标志物,都因为 Flash 的消逝而逐渐淡出人们的视野。
像 Q 宠这样在 2018 年就已经停服的游戏,许多人对它们的怀念之情愈加浓厚。而随着人工智能的发展,虚拟现实的兴起,相信未来会有更多的人希望重温这些经典。但现在,借助 Ruffle 开源项目,我们有机会让这些经典的 Flash 作品再次闪耀。
Ruffle 教程
Ruffle 是什么?
Ruffle 是一个基于 Rust 开发的开源项目,旨在无缝地在所有现代操作系统和浏览器上运行 Flash 内容,无需任何额外操作。通过 Ruffle,无论是经典游戏还是动画,都可以在现代环境中运行。
Ruffle 是一个非常活跃的开源项目,当前已有 11473 个 commit,162 个贡献者,且每天都在更新,对 Flash 的支持也越来越完善。
插件客户端
无论是 Windows、macOS(支持 M1/M2 芯片)还是 Linux,都可以在 Ruffle 官网 找到并下载相应的客户端。不过对于 Windows 用户,如果是在本地运行 Flash,更推荐直接下载 Flash Player。
对于希望在浏览器中直接体验 Flash 内容的用户,Ruffle 也提供了 Chrome、Firefox、Edge 和 Safari 的浏览器扩展插件。安装后,当访问包含 SWF 文件的网站时,Ruffle 会自动介入,使这些内容得以在现代浏览器上运行。
嵌入网页
如果希望让用户能直接访问带 flash 游戏的网页,且无需安装插件,可以将 Ruffle 添加到网站中。作为示例,我们先写一个简单的 HTML 页面,并引入 Ruffle:
下图 html 文件定义了一个全屏的容器,其中 container 放置游戏页面。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>游戏名称</title>
<link rel="stylesheet" href="style.css">
<style>
/* 确保html和body元素占满整个屏幕 */
html, body {
height: 100%;
margin: 0;
overflow: hidden; /* 隐藏滚动条 */
}
/* 使容器和Ruffle播放器全屏和自适应 */
#container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#container ruffle-player {
flex-shrink: 0; /* 防止播放器被压缩 */
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="//unpkg.com/@ruffle-rs/ruffle"></script>
<script>
window.addEventListener('load', async () => {
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
const container = document.getElementById('container');
container.appendChild(player);
player.load('game.swf');
});
</script>
</body>
</html>
代码中的这段 JavaScript 代码,用于引入 ruffle 脚本并加载游戏。
<script src="//unpkg.com/@ruffle-rs/ruffle"></script>
<script>
window.addEventListener('load', async () => {
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
const container = document.getElementById('container');
container.appendChild(player);
player.load('game.swf');
});
</script>
第一行通过 https://unpkg.com/@ruffle-rs/ruffle
引入脚本,第二段 js 代码创建一个 Ruffle 播放器,并加载游戏,游戏文件为 game.swf
。
如果网络访问 unpkg.com 慢,可以在下载页 选择 Web Package,下载到网站目录,然后用相对路径加载:
<script src="path/to/ruffle.js"></script>
当然,也可以使用自定义的 CDN 资源,比如写个 Nginx 脚本分享 /var/www/cdn
目录下的内容
server{
listen 80;
server_name cdn.example.com;
index index.html index.htm;
add_header 'Access-Control-Allow-Origin' *;
location / {
root /var/www/cdn;
try_files $uri $uri/ =404;
}
}
这里加上一行 add_header 'Access-Control-Allow-Origin' *;
以避免跨域问题。
跨域问题
通常,为了加速网站的访问,我们会将游戏文件和 Ruffle 插件托管在如七牛云这样的流量分发平台上,但这可能会触发跨域资源共享(CORS)问题。跨域问题的发生是因为出于安全考虑,浏览器限制了一个源(如你的网站)如何访问另一个源(如 CDN)的资源。如果不正确配置 CORS,浏览器将阻止你的网页请求这些资源,导致游戏或动画无法加载。
例如,将 swf 游戏文件托管七牛云加速访问,如果没有适当设置 CORS,就会看到类似下图的错误:
为了解决这个问题,需在托管资源的服务器上设置适当的 CORS 策略,比如前边 Nginx 的配置。而对于七牛云,可以参考跨域资源共享设置指南。
播放器配置
接下来,我们详细介绍 Ruffle 播放器的一些配置选项,这些选项可以帮助你更好地控制 Flash 内容的加载和显示。
多文件游戏
如果你的 Flash 游戏由多个 swf 文件组成,并且这些文件之间有相互调用关系,你需要在 Ruffle 的配置中设置 base
参数。
例如,如果你的游戏主文件是 game.swf
,而它依赖于同一目录下的其他 swf 文件,你可以这样配置 Ruffle:
<script>
window.addEventListener('load', async () => {
window.RufflePlayer.config = {
base: "your/path" // 指定 swf 文件的基础路径
};
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
const container = document.getElementById('container');
container.appendChild(player);
player.load('your/path/game.swf');
});
</script>
这样,Ruffle 会从指定的 your/path
路径加载 game.swf
和它依赖的其他 swf 文件,而不是从当前目录下查找。类似地,如果游戏文件以链接形式获取,前边 base
也需要相应修改。
修改内嵌字体
内嵌字体乱码是 Ruffle 被吐槽较多的一个问题,但去年年底 Ruffle 更新了一个特性:Add defaultFonts and fontSources config options,支持修改字体。
按官方文档的说法,支持对 Flash 默认三类字体的替换:
There are 3 default fonts in Flash, _sans _serif and _typewriter - in Ruffle they are normally all set to Noto Sans, but you can replace it such as:
window.RufflePlayer.config = {
fontSources: ["fonts.swf"], // load up fonts here
defaultFonts: {
sans: ["Caveat"], // then replace them here.
// serif: ["Font Name 1", "Font Name 2"], // Multiple fonts can be provided
// typewriter: ["Noto Sans"], // typewriter is normally a monospace font
}
}
具体地,先按照官网的图文教程,将字体转换为 swf 文件,然后在 Ruffle 配置中指定它们。
目前,第一步需单独用 Animate 软件进行操作转化。这里我按教程将“站酷快乐体”转化成了 swf 文件,支持中文字符。可通过如下配置引用,亲测有效:
window.RufflePlayer.config = {
fontSources: ["https://cdn.wzhecnu.cn/adventure/myfont.swf"], // load up fonts here
defaultFonts: {
sans: ["站酷快乐体2016修订版"], // then replace them here.
},
}
效果对比图:
Ruffle 后续会考虑对字体文件的直接支持,比如使用 .ttf
文件。
For now we only support SWFs containing fonts, but in the future we’ll allow actual font files too (such as ttf).
页面放缩
和 flash Player 不同,Ruffle 的右键没有控制缩放的选项,这些需在代码中设置。
举个例子,设置“显示全部”,以及强制缩放:
window.RufflePlayer.config = {
scale: "showAll",
forceScale: true
}
这样可以避免主画面太小,以及出现画面外辅助用的素材。
更多设置
以上的播放器设置可以整合到一块:
<script src="//unpkg.com/@ruffle-rs/ruffle"></script>
<script>
window.addEventListener('load', async () => {
window.RufflePlayer.config = {
fontSources: ["https://cdn.wzhecnu.cn/adventure/myfont.swf"], // load up fonts here
defaultFonts: {
sans: ["站酷快乐体2016修订版"], // then replace them here.
},
scale: "showAll",
forceScale: true,
base: "your/path" // 设置CDN基路径
}
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
const container = document.getElementById('container');
container.appendChild(player);
player.load('your/path/xmxd.swf');
});
</script>
更多选项请参考 Ruffle 使用教程:Using Ruffle。实际上,可以先下载 Ruffle 的客户端,在本地调试后,将客户端里修改的参数填写到配置里。
相关链接
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)