为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript游戏开发又火了!——《虚空之声》中的轻量级游戏项目

一款激动人心的游戏开发项目,包括一个 π/42 理论。
原帖来自 community.aws (原始帖子链接)

GitHub 仓库地址是 https://github.com/Pengeszikra/flogon-galaxy

摘要(太长没看)

也许这个小程序塞进了太多的信息。当我们处在创意的高峰时,这种情况就会出现。当然这只是个概念验证阶段的代码,我将继续在许多方向上探索。

试试这个:F L O G O N - G A L A X Y,我在手机、平板电脑和浏览器上测试过,甚至包括我电视上的基本浏览器。

设备演示介绍:

我的办公桌就是在这里,这个程序就是在上面创建并在不同设备上运行的。

游戏玩法 纯JavaScript游戏制作

该项目采用最小依赖原则构建,剔除了不必要的框架,同时注重效率。

我的转折点是:
在我的工作中,我遇到了8GB内存对一个旧的React应用来说不够用来构建的困境。DevOps团队通过在虚拟构建服务器上设置16GB的RAM解决了这个问题。就在那一瞬间,我立刻对现代JavaScript框架和编译器失去了信心。

但这种状况要求非常严格,再加上这次黑客马拉松的要求是要使用一些强大的 AWS 云 API 来扩展我的游戏功能几乎无限。对于发布,也需要一个最小构建环境。即使是对本地测试不需编译的代码,选择 pnpm 和 vite 组合也是非常好的,因为它们支持热重载,这对开发时间来说至关重要。

最后我可以将依赖降到最低,这样也能带来非常快的加载时间。关于最低依赖详情,你可以查看下面的内容或直接跳过。

图片描述
点击此处查看图片

打破依赖的链条

项目中的package.json文件

      "scripts": {
        "build": "vite build",
        "client": "vite",
        "server": "pnpm node src/services/dbServer.js",
        // 本地开发命令:
        "start": "pnpm run server & pnpm run client"
      },
      "dependencies": {
        // 用于 AWS DynamoDB 的最小依赖项
        "@aws-sdk/client-dynamodb": "^3.0.0",
        "@aws-sdk/lib-dynamodb": "^3.0.0",
        "cors": "^2.8.5",
        "dotenv": "^16.4.1",
        "express": "^5.0.1"
      },
      "devDependencies": {
        // Tailwind
        "autoprefixer": "^10.4.20",
        "postcss": "^8.4.49",
        "tailwindcss": "^3.4.16",
        // JSDoc 也需要,不过只是开发依赖。
        "typescript": "5.7.2",
        // 构建:
        "vite": "^6.0.3",
        // PWA
        "vite-plugin-pwa": "^0.21.1"
      }

全屏 恢复

Vite 把整个项目切成尽可能小的块,处理得很到位。
因为这个项目是由松散耦合的 HTML 页面构成的。

    > pnpm build

    dist/registerSW.js                               0.13 kB
    dist/manifest.webmanifest                        0.36 kB
    dist/assets/manifest-B2xQAFIn.json               0.58 kB │ gzip: 0.26 kB
    dist/credit.html                                 0.99 kB │ gzip: 0.46 kB
    dist/adventure.html                              0.99 kB │ gzip: 0.46 kB
    dist/library.html                                1.01 kB │ gzip: 0.47 kB
    dist/ship.html                                   1.03 kB │ gzip: 0.51 kB
    dist/card.html                                   1.03 kB │ gzip: 0.49 kB
    dist/fit.html                                    1.14 kB │ gzip: 0.61 kB
    dist/work.html                                   1.28 kB │ gzip: 0.55 kB
    dist/mine.html                                   1.34 kB │ gzip: 0.62 kB
    dist/story.html                                  1.36 kB │ gzip: 0.63 kB
    dist/index.html                                  1.38 kB │ gzip: 0.68 kB
    dist/deal.html                                   1.63 kB │ gzip: 0.70 kB
    dist/marker.html                                 2.01 kB │ gzip: 0.86 kB
    dist/travel.html                                 2.03 kB │ gzip: 0.85 kB
    dist/index.html                                  2.10 kB │ gzip: 0.91 kB
    dist/throw.html                                  6.14 kB │ gzip: 1.81 kB
    dist/assets/style-5bcm0AOV.css                  19.64 kB │ gzip: 4.44 kB
    dist/assets/marker-a3K9PoX8.css                 20.43 kB │ gzip: 4.75 kB
    dist/assets/ui-elements-C42piOfa.js              0.52 kB │ gzip: 0.20 kB
    dist/assets/old-bird-soft-Cet9K-fd.js            0.64 kB │ gzip: 0.40 kB
    dist/assets/targetSystem-C6rfYONd.js             0.70 kB │ gzip: 0.17 kB
    dist/assets/index-DPcikNFZ.js                    0.70 kB │ gzip: 0.47 kB
    dist/assets/modulepreload-polyfill-B5Qt9EMX.js   0.71 kB │ gzip: 0.40 kB
    dist/assets/story-BYdjpAbD.js                    0.71 kB │ gzip: 0.50 kB
    dist/assets/credit-B_lCQp87.js                   0.92 kB │ gzip: 0.58 kB
    dist/assets/shoot-9YV2jSCs.js                    1.11 kB │ gzip: 0.20 kB
    dist/assets/work-AxYhedTL.js                     1.24 kB │ gzip: 0.59 kB
    dist/assets/adventure-mfPAHVPp.js                1.26 kB │ gzip: 0.74 kB
    dist/assets/fencer-CBOzlVSn.js                   1.51 kB │ gzip: 0.76 kB
    dist/assets/ship-DzKwFTHn.js                     1.57 kB │ gzip: 0.79 kB
    dist/assets/library-iOGeQgd2.js                  1.69 kB │ gzip: 0.87 kB
    dist/assets/concept-1YqRBMyf.js                  1.70 kB │ gzip: 0.84 kB
    dist/assets/travel-BjKxB5xP.js                   1.70 kB │ gzip: 0.84 kB
    dist/assets/GalaxyRoute-Czkip2Wg.js              1.77 kB │ gzip: 0.85 kB
    dist/assets/asset-DRNybFKp.js                    2.01 kB │ gzip: 0.50 kB
    dist/assets/card-BxPOIcVT.js                     3.05 kB │ gzip: 1.03 kB
    dist/assets/mine-txzynpoG.js                     3.08 kB │ gzip: 1.33 kB
    dist/assets/marker-CDmeMeHZ.js                   3.08 kB │ gzip: 1.43 kB
    dist/assets/throw-CtACwOyr.js                    7.86 kB │ gzip: 2.68 kB
    dist/assets/deal-ptFW1zND.js                    10.26 kB │ gzip: 3.93 kB
    ✓ 构建成功,耗时 1.16 秒

    PWA v0.21.1
    模式       generateSW
    预缓存     41 个项目 (110.77 KiB)

全屏进入,退出全屏

PWA & 响应式

一个渐进式网页应用(PWA)的设置确保了Flogon Galaxy在移动设备、桌面和嵌入式浏览器上高效运行。TailwindCSS灵活地处理了设计。但主要的问题是PWA的设置。起初,我求助于Amazon Q,但那解决方案导致了我的整个程序的外观和感觉被破坏,因为它生成了一个错误的服务工作者,导致浏览器卡住了,所以我尝试修复它时,即使进行了完整的回滚,错误依然存在——多亏了Amazon Q /dev功能,可以轻松地审查和回滚修改,我也尝试了ChatGPTo1的帮助,但同样没有成功。问题在于需要在Chrome浏览器中重置服务工作者。这次事件后,我通过向AI提出正确的问题找到了解决方案:
为什么不可以让Vite在构建过程中自动生成PWA相关内容呢?
将这个任务交给vite-plugin-pwa并进行正确配置,问题就解决了。

图片描述

这个程序最大的帮助是我的 Markdown 编辑器:marker,它也是一个测试不同宽高比的利器,而宽高比是自适应设计的基本问题。

JSDoc(JSDoc注释)

一个常常被低估的JSDoc是未编译/依赖最少的JS开发的重要支柱。JSDoc 宣扬。总结一下,这个项目证明了JSDoc可以达到与TypeScript相同的效果,而不需要那种依赖项(只是开发依赖项)。最终,JavaScript 仍然可以通过严格的文档规范保持其可读性和可维护性。使用JSDoc不仅确保了代码的清晰度,还能提供编辑器提示,即使没有TypeScript也不例外。

不需3D引擎的3D技术

通过使用 CSS 变换,我们实现了伪三维效果,同时保持了高性能和低依赖性。基于这种 CSS 设置的纸牌游戏应用,Tailwind 不支持这些属性。

        #desk {
          transform-style: preserve-3d;
          transform:
            perspective(70vw)
            rotateX(40deg)
            rotateY(0deg)
            rotateZ(0deg)
            scale(.55)
            translateZ(0rem)
            translateY(5rem)
            translateX(-8rem);
          pointer-events: none;
        }

全屏 进 全屏 退

所有的卡片都贴在 #desk 上,这样你就能看到它们是3D的。

我的AI小队

我的开发在这种情况下没有AI团队的帮助是无法完成的。

这里是我列出的AI团队成员:

  • Amazon Q :代码高手
  • ChatGPT :项目助手,歌词创作,编码
  • Midjourney :视觉创作
  • Suno :音频轨道
  • Revoicer :配音
  • HailuoAI :片段处理
  • Clipdrop :去除背景
  • DreamAI :视觉生成训练

没有这些工具的帮助,这个项目在严格的时间框架内是无法实现的:

2024.06.27 -> alien-solitaire : 基于 React 的纸牌游戏,为 dev.to 的挑战而制作
2024.07.06 -> pure-web-ccg : 开始了我的纯网页项目工作
2024.12.14 -> flogon-board : 同时我发现了一个 Reddit 黑客马拉松活动,
Flogon 系列的第一个游戏,加上精灵编辑器
2024.12.29 -> flogon-galaxy : 开始专注于这个项目

在这个项目上我只有两周时间,时间非常紧张。但多亏了这些帮助,Flogon Galaxy 已经达到了技术演示的阶段。

Amazon Q

对我而言,Amazon Q 在思考期(大概在十一月)非常有帮助——那时我使用 Amazon Q 创建了大约 15 个小游戏。这极大地帮助我快速尝试和测试不同的点子。在后来的实现阶段,/dev 命令是我解决各种任务的超级帮手,包括 DynamoDB 的实现,虽然我对 DynamoDB 还不太熟悉,但很快就搞定了这些问题。

我在Amazon Q上不喜欢的是过多的额外提问,比如:“你还有其他问题要问吗?”在我看来这完全没有必要。相反,只需要显示下一个聊天输入行,如果我在那里输入内容就表示我继续对话,就不用再点击额外的按钮了。

图片描述。你可以通过点击链接查看图片。

DynamoDB 和标记

在这个项目的早期阶段:2023年十一月,我创建了一个 Markdown 视图的 Web 组件,并在其中附带了一个简单的文本框。我最初的目标只是做一个非常基础的 Markdown 查看器,但在我实现了一些代码块的简单语法高亮和 iframe 功能之后,一个全新的世界展现在我面前。

你可以通过这个链接测试这个程序:
M A R K E R

试试把它粘贴进去。

它不能理解其他编程语言,只是HTML/JS/JSDoc的混合配置,确实需要一个扩展插件,但作为概念验证(POC),运行速度还不错。

表格、列表、加粗等都不管用,但是真正厉害的是嵌入URL。

    {%url%}

    // 或

    {%url%aspect-ratio}

    例如:

    {%.%16/9} // 启动标准宽高比的程序,比如

    {%deal.html%16/9} // 开始纸牌游戏

    // 或

    {%deal%16/9} // 也启动纸牌游戏。

    // 一个秘密的老程序可以通过这种方式启动:

    {%throw%1/1}

    // 这是我之前在Reddit上的黑客马拉松提交。 
    // 这是Flogon的Throw to Match游戏的另一个版本。

点击此处全屏显示 点击此处退出全屏

已将AWS DynamoDB包含在这个标记中

但这只是一个局部的好用法,不过因为我用它来快速保存和加载一个 Markdown 文件。只需按 ESC,然后在输入行输入:e:rpg.md,这会尝试从 DynamoDB 加载 rpg.md。但要实现这一点,需要将你的 DynamoDB 凭证添加到 .env 文件中,如下所示:

AWS_ACCESS_KEY_ID = "AKI........" # AWS 访问密钥 ID
AWS_SECRET_ACCESS_KEY = "4Qr8........" # AWS 密钥
AWS_REGION = "eu-north-1" # AWS 区域
DYNAMO_TABLE = "storage-0392" # Dynamo 表名
PORT = 3000 # 端口号
API = "http://localhost" # API 地址

全屏进入,退出全屏

当然,为了做到这一点,你需要有一个 AWS 账户并创建 DynamoDB,这样做非常有好处。

这个程序里我还有一个开发工具:

精灵编辑器
    {%throw%1/1}

进入全屏,退出全屏

    按 `z` 开始编辑精灵,
    `c` - 移动框,
    `v` - 选择一个精灵,
    `w` - 缩小竖直方向,
    `s` - 放大竖直方向,
    `a` - 缩小水平方向,
    `d` - 放大水平方向,
    `[` 或 `]` - 更改精灵表单页,

全屏模式 退出

// 可以在 Chrome 的开发者工具中使用 JavaScript 代码将精灵图数据复制出来:
copy(JSON.parse(localStorage.getItem('-shoot-') || '{}'));

进入全屏模式 退出全屏

你可以在这个repo里找到我的代码:(https://github.com/Pengeszikra/flogon-galaxy)

这让我考虑使用像函数这样的框架吗?

正如我一开始说的那样,我试着不使用任何框架,但我需要一个状态管理,这对于像纸牌游戏这样的复杂应用来说是非常重要的部分,因为那里会发生许多事件。一个易于替换的状态就是反应式状态。这里有一个最简单的实现方式。同样重要的是,这种状态处理并不与任何视图耦合,就像在React中那样。并且这种状态处理并不一定在每个文件中都使用。

信号驱动的状态管理

一个自定义信号系统取代了外部状态库,提供了细粒度的反应能力,并且几乎没有任何开销。这个单一功能解决了游戏中必不可少的状态管理需求。我还创建了一个更“高级”的函数:zignal,它能够处理深层次的代理状态管理,但在这种情况下过于复杂了点。所以我选择了更简单的那个(系统)。

    /**

* @type {<T>(watcher?: Function) => (state?: T | object) => T}
     */
    export const 信号 = (观察者 = () => { }) => (状态 = {}) => {
      return new Proxy(状态, {
        get: (目标, 属性) => 目标[属性],
        set: (目标, 属性, 值) => {
          目标[属性] = (值 !== null && typeof 值 === 'object')
            ? 信号(观察者)(值)
            : 值
            ;
          观察者(目标, 属性, 值);
          return true;
        },
      });
    };

点击开启全屏,点击关闭全屏

JSX 模板

我意识到在某个时刻,没有 JSX,我需要为每个 DOM 元素手动添加标签,这真的非常痛苦。这就是我为什么拿出我那个很久以前写的轻量级 JSX 渲染系统来驱动 UI 交互,而无需使用 React,保持简单和控制。五年前我读过一篇关于 JSX 的博客,并写了一个简单的 JSX 处理函数。现在是时候将那段代码拿出来,并借助 AI 和 Vite 来处理 JSX 文件了。经过几轮调整后,它现在完美适应了我的程序。我不需要写测试,实际运行的代码就是最好的帮助。

这里的重要部分是 vite.config.js:

      esbuild: {
        jsxFactory: 'fencer', // 将自定义 `fencer` 函数用作 JSX 工厂
        jsxFragment: 'Fragment', // 可选,如果你使用 JSX 片段(比如 `<>...</>`)
      },

全屏模式 退出全屏

不完美的工作流

就像你所见,开发过程中并不是追求立即的完美,而是采用迭代、适应性的流程来指导开发。这让我能自然地将创意想法融入游戏中。所以我并不怕犯错,而是看看哪些部分可以在期限内搞定。我觉得很多开发者都会这么干,而不是在某个问题上卡壳了。

福隆的不为人知的故事

我最大的问题是:我不必向你描述关于弗洛贡的故事。
所以这一章至少让你了解了一些关于弗洛贡的基本信息。
请听一下关于弗洛贡特有的梦境旅行能力以及宇宙未被发现的物质因韦兹的讨论。

我们现在还无法到达最近的恒星系统。但第一次接触给了我们一个机会,达到难以想象的距离。主要问题在于,弗洛贡人既不是技术官僚主义者也不是资本家,他们不像我们一样被距离和可能的地方所困扰。所以很难理解我们之间有什么共同点。

看看这张图。

所以弗洛贡使用的技术和其他生物有些不同,因为他们中的有些甚至能变成物品。并不是每个弗洛贡都能进行梦境旅行,也不是每个弗洛贡都能达到那样的变形——但普通的变形很常见。这就是为什么有时候会披上布,有时候则不会。我们还不知道他们探索过多少恒星系统或星系。

但我们的科学家从沃拉碎片的弗洛贡那里收集到了一个奇怪的理论。这是一个任何人都可以读取的隐藏代码:只需要计算出π中的42个波动标记的距离。

关于 π/42 的理论

让我们深入了解Flogon宇宙背后的数学奥秘,其中π和数字42是理解宇宙共鸣的关键所在。Wora Shard甚至为此写了一首歌。

沃拉·沙德

值得思考的问题是。简单的回答是,她只是一名地下朋克金属歌手,迷失在反抗的回声里——直到那晚,她梦到了那片无垠的未知。

刚才她还在地球上。下一刻,她却在一个遥远的外星球醒来,周围是人类无法理解的谜团。她迷失且困惑,可能会永远迷失下去……如果不是遇到了有经验的弗洛贡船长约格达,他觉得她的到来很不寻常。

历经险象环生的星际之旅,穿越未知的世界和未言的危险,Yogdar 带她回到了家。但有些事情变了。Wora 不再只是个歌手——她成了穿梭于领域的旅者,一个触摸了她几乎无法理解的宇宙织物的梦想者。

而这……才是我们故事真正的起点。

滚动字幕

我的另一个大额债务是片尾字幕名单。因为在这一开发过程中,这看起来像是一个人的独角戏,有AI的帮助。但整个AI的事情对我们来说都是学习。所以任何通过AI界面提出的内容或想法,无论是内容、想法还是任何通过AI实现的材料,都只是向人类知识库提问而已。
同样重要的是,要在这份名单中特别提到那些启发了我并在我刺激的开发过程中保持我精神振奋的特定的人。感谢你们,片尾字幕会在冻结版本后出现。

图片描述

未来计划:

项目冻结结束后,我将开始专注于福龙故事线,这些故事线不幸地并不适合这个项目。我们与福龙之间的联系真的非常有趣。从技术上讲,这将是一个多人版本的游戏,包括卡牌收集、太空贸易和飞船建造功能,这些游戏已经被打磨得很完美了。

让你的梦想实现!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消