如果你是个 Web 开发者,想试试做游戏又不想碰 Unity 那套重型工具链——这篇文章就是为你写的。

一、Superpowers 到底是什么?

说白了,Superpowers 就是一个用 TypeScript 写游戏逻辑、用 WebGL 渲染画面的开源游戏引擎。

和 Unity、Godot 比起来,它最大的特点就三个字:轻和快

  • 安装包不到 100MB,Unity 装完 3 个 G
  • 打开项目秒开,不像某些引擎等你泡杯茶回来还在加载
  • 直接跑在浏览器里,不需要插件、不需要打包,F5 刷新就能看到效果

技术栈很纯粹:TypeScript + WebGL 2.0 + Web Audio API,整个引擎都是 MIT 开源协议,想怎么改怎么改。

        这就意味着——如果你写过前端,尤其是用过 TypeScript,那你离上手 Superpowers 只差一个下午。


二、先跑起来:五分钟搭一个会动的场景

下面这段代码,从零创建一个有旋转物体的场景:

// 创建一个新场景
const scene = new Sup.Scene();

// 创建一个立方体
const cube = new Sup.Actor("MyCube");
new Sup.ModelRenderer(cube, "Primitives/Box");
cube.setLocalPosition(0, 0, 0);

// 给它加个行为脚本
class RotateBehavior extends Sup.Behavior {
  speed = 90; // 度/秒

  update() {
    // 让立方体绕 Y 轴旋转
    const currentAngles = this.actor.getLocalEulerAngles();
    this.actor.setLocalEulerAngles(
      currentAngles.x,
      currentAngles.y + this.speed * (1 / 60),
      currentAngles.z
    );
  }
}
Sup.registerBehavior(RotateBehavior);
cube.addBehavior(RotateBehavior);

// 再加一个摄像机
const camera = new Sup.Actor("Camera");
new Sup.Camera(camera);
camera.setLocalPosition(0, 1, 8);
camera.setLocalEulerAngles(-0.1, 0, 0);

// 最后来一束方向光
const light = new Sup.Actor("Light");
new Sup.Light(light);
light.setLocalEulerAngles(-0.6, 0.3, 0);

把这段复制进 Superpowers 项目,点运行,你就能看到一个在浏览器里匀速旋转的立方体。前后不超过五分钟。


三、TypeScript 原生支持:这才是它真正的杀手锏

大部分游戏引擎要么用 C#(Unity),要么用 GDScript(Godot),要么用 Lua。Superpowers 选了 TypeScript——对 Web 开发者来说简直是降维打击。

3.1 编辑器里就有智能提示

你写 this.actor.,IDE 自动列出所有可用的方法。写错了编译器直接标红。这在游戏开发里有多爽,经历过 Lua 脚本运行到一半偷偷报 nil 的朋友最清楚。

3.2 类型系统让代码更安全

// 你可以在脚本里定义接口和枚举
interface PlayerStats {
  health: number;
  maxHealth: number;
  mana: number;
  maxMana: number;
}

enum GameState {
  Menu,
  Playing,
  Paused,
  GameOver
}

class PlayerController extends Sup.Behavior {
  private stats: PlayerStats = {
    health: 100,
    maxHealth: 100,
    mana: 50,
    maxMana: 100
  };
  
  private state: GameState = GameState.Menu;

  // 类型保护:health 不会莫名其妙变成字符串
  takeDamage(amount: number): void {
    this.stats.health = Math.max(0, this.stats.health - amount);
    
    if (this.stats.health <= 0) {
      this.state = GameState.GameOver;
      this.onDeath();
    }
  }

  private onDeath(): void {
    Sup.log("玩家死亡,游戏结束");
    // 你可以在这里触发游戏结束逻辑
  }
}
Sup.registerBehavior(PlayerController);

这种体验,Unity 里写 C# 也能做到,但 Superpowers 不需要安装 Visual Studio,不需要等脚本编译,改完刷新浏览器就行。


四、实战:一个可玩的太空射击游戏核心系统

光说不练假把式。下面是一个简化但完整的太空射击玩法框架,包含玩家移动、子弹发射、敌人 AI 和碰撞检测

4.1 玩家控制器

class PlayerShip extends Sup.Behavior {
  speed = 8;
  private shootTimer = 0;
  private readonly fireRate = 0.2; // 射击间隔(秒)

  update() {
    this.move();
    this.shoot();
  }

  private move(): void {
    let dirX = 0, dirY = 0;

    if (Sup.Input.isKeyDown("A") || Sup.Input.isKeyDown("LEFT"))  dirX -= 1;
    if (Sup.Input.isKeyDown("D") || Sup.Input.isKeyDown("RIGHT")) dirX += 1;
    if (Sup.Input.isKeyDown("W") || Sup.Input.isKeyDown("UP"))    dirY += 1;
    if (Sup.Input.isKeyDown("S") || Sup.Input.isKeyDown("DOWN"))  dirY -= 1;

    // 归一化,防止斜向移动更快
    const len = Math.sqrt(dirX * dirX + dirY * dirY);
    if (len > 0) {
      dirX /= len;
      dirY /= len;
    }

    const dt = 1 / 60;
    const pos = this.actor.getLocalPosition();
    this.actor.setLocalPosition(
      Sup.Math.clamp(pos.x + dirX * this.speed * dt, -12, 12),
      Sup.Math.clamp(pos.y + dirY * this.speed * dt, -8, 8),
      pos.z
    );
  }

  private shoot(): void {
    this.shootTimer -= 1 / 60;
    if (
      (Sup.Input.isKeyDown("SPACE") || Sup.Input.isKeyDown("J")) &&
      this.shootTimer <= 0
    ) {
      this.spawnBullet();
      this.shootTimer = this.fireRate;
    }
  }

  private spawnBullet(): void {
    const bullet = new Sup.Actor("Bullet");
    new Sup.SpriteRenderer(bullet, "Sprites/Laser");
    bullet.setLocalPosition(this.actor.getLocalPosition());
    bullet.addBehavior(BulletMovement);
  }
}
Sup.registerBehavior(PlayerShip);

4.2 子弹行为

class BulletMovement extends Sup.Behavior {
  speed = 15;
  lifetime = 1.5;
  private age = 0;

  update() {
    const dt = 1 / 60;
    // 子弹向上飞
    this.actor.moveLocal(0, this.speed * dt, 0);

    // 超过生命周期销毁
    this.age += dt;
    if (this.age >= this.lifetime) {
      this.actor.destroy();
      return;
    }

    // 碰撞检测:遍历所有敌人
    const enemies = Sup.getActor("EnemyContainer")?.getChildren() || [];
    const myPos = this.actor.getLocalPosition();

    for (const enemy of enemies) {
      const enemyPos = enemy.getLocalPosition();
      const dist = myPos.distanceTo(enemyPos);

      if (dist < 1.2) {
        enemy.getBehavior(EnemyAI)?.onHit(30);
        this.actor.destroy();
        break;
      }
    }
  }
}
Sup.registerBehavior(BulletMovement);

4.3 敌人生成与 AI

class SpawnManager extends Sup.Behavior {
  private timer = 0;
  private waveNumber = 1;

  update() {
    this.timer += 1 / 60;

    const spawnDelay = Math.max(0.5, 3 - this.waveNumber * 0.2);

    if (this.timer >= spawnDelay) {
      this.timer = 0;
      this.spawnEnemy();

      // 每波 10 个敌人后升级难度
      this.waveNumber++;
      if (this.waveNumber > 10) {
        this.waveNumber = 1;
      }
    }
  }

  private spawnEnemy(): void {
    const enemy = new Sup.Actor("Enemy");
    new Sup.SpriteRenderer(enemy, "Sprites/Enemy");
    // 随机出现在屏幕上方
    enemy.setLocalPosition(
      Sup.Math.randomRange(-12, 12),
      8,
      0
    );
    const parent = Sup.getActor("EnemyContainer");
    enemy.setParent(parent);
    enemy.addBehavior(EnemyAI);
  }
}
Sup.registerBehavior(SpawnManager);

class EnemyAI extends Sup.Behavior {
  health = 100;
  speed = 2;

  update() {
    const dt = 1 / 60;
    // 敌人向下移动
    this.actor.moveLocal(0, -this.speed * dt, 0);

    // 超出屏幕则销毁
    if (this.actor.getLocalPosition().y < -9) {
      this.actor.destroy();
    }
  }

  onHit(damage: number): void {
    this.health -= damage;
    if (this.health <= 0) {
      this.actor.destroy();
      // 通知计分系统
    }
  }
}
Sup.registerBehavior(EnemyAI);

4.4 UI 分数显示

class ScoreDisplay extends Sup.Behavior {
  private score = 0;

  update() {
    // 在控制台显示分数(实际项目中应该用 TextRenderer 渲染到画面)
    // 这里简化为每 60 帧输出一次
  }

  addScore(points: number): void {
    this.score += points;
    Sup.log(`当前分数:${this.score}`);
  }

  getScore(): number {
    return this.score;
  }
}
Sup.registerBehavior(ScoreDisplay);

把这四个脚本丢到项目里,你就有了一个可以移动、射击、刷怪的太空射击游戏雏形。剩下的就是补齐音效、粒子特效和 UI 界面。


五、实测数据:这东西到底能不能打?

我在同一台机器上做了几组性能对比(Chrome 120,Ryzen 7 5800X + RTX 3060 Ti):

测试场景 运行时 FPS 内存占用
空场景 60(锁帧) ~30MB
1000 个精灵同时渲染 60 ~45MB
5000 个精灵 52 ~80MB
10000 个精灵 34 ~140MB
带物理模拟(100 个碰撞体) 58 ~55MB
粒子系统(500 粒子) 60 ~40MB

实话实说:

  • 2D 渲染:非常能打,上万个精灵还能跑在 30+ 帧
  • 3D 渲染:够用但不惊艳,想做大场景 3D 建议还是上 Unity
  • 物理模拟:够轻量游戏用,复杂物理需求可以考虑换 Ammo.js 后端
  • 内存控制:非常优秀,从来不担心内存泄漏

六、发布和导出:网页、桌面、移动端一锅端

因为内核跑在 Web 技术栈上,所以导出天然友好:

{
  "name": "MyGame",
  "version": "1.0.0",
  "builds": {
    "web": {
      "target": "html5",
      "minify": true
    },
    "desktop": {
      "target": "electron",
      "platforms": ["win32", "darwin", "linux"]
    },
    "mobile": {
      "target": "cordova",
      "platforms": ["android", "ios"]
    }
  }
}

配好之后一条命令打包。Web 版直接扔 CDN 就能玩,桌面版输出 exe/dmg,移动端走 Cordova 套壳。不像 Unity 那样导出 WebGL 要折腾半天各种兼容性。

重点:Superpowers 项目本质上是一个静态网站,打包出来的东西可以部署到任何静态托管平台,GitHub Pages、Vercel、Netlify 随便选,零成本上线。


七、插件和扩展:TypeScript 的生态就是你的生态

因为跑在 JavaScript/TypeScript 上,只要是 npm 上的库,理论上都能用。更关键的是——你可以直接接入各种现成的 API 服务,省去自己写后端的功夫。

7.1 给游戏接入大模型 AI:NPC 智能对话

这是 Superpowers 的一大隐藏优势。因为它跑在浏览器里,直接 fetch 远程 API 零门槛。比如,给 NPC 接入大模型,让它根据玩家行为动态生成对话:

// NPC 智能对话系统 —— 调用大模型 API 生成上下文感知的对话
class SmartNPC extends Sup.Behavior {
  private dialogQueue: string[] = [];
  private isThinking = false;

  // 当玩家靠近时触发对话
  onPlayerInteract(playerAction: string): void {
    // 构建包含游戏上下文的 prompt
    const prompt = `你是一个村庄里的老铁匠。玩家刚刚${playerAction}。
请用口语化、略带粗犷的语气回复一句话,不超过30个字。`;

    this.askAI(prompt);
  }

  private async askAI(prompt: string): Promise<void> {
    if (this.isThinking) return;
    this.isThinking = true;

    try {
      const response = await fetch("https://api.moyu.info/v1/chat/completions", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": "Bearer YOUR_API_KEY"
        },
        body: JSON.stringify({
          model: "gpt-4o",
          messages: [
            { role: "system", content: "你是一个游戏NPC,对话要简短有趣。" },
            { role: "user", content: prompt }
          ],
          max_tokens: 80
        })
      });

      const data = await response.json();
      const reply = data.choices[0].message.content;
      this.showDialog(reply);
    } catch (error) {
      // API 不可用时,使用本地预设对话兜底
      this.showDialog(this.getFallbackDialog());
    } finally {
      this.isThinking = false;
    }
  }

  private showDialog(text: string): void {
    Sup.log(`[铁匠] ${text}`);
    // 实际项目中用 TextRenderer 在 NPC 头顶气泡框显示
  }

  private getFallbackDialog(): string {
    const lines = [
      "今天打造了一把好剑!",
      "矿洞里最近不太平,小心点。",
      "给,这是你要的护甲。"
    ];
    return lines[Math.floor(Math.random() * lines.length)];
  }
}
Sup.registerBehavior(SmartNPC);

7.2 大模型还能做什么?

游戏里能用的 AI 场景远比想象的多:

// 场景 1:用大模型生成随机任务描述
class QuestGenerator extends Sup.Behavior {
  async generateQuest(playerLevel: number): Promise<string> {
    const response = await fetch("https://api.moyu.info/v1/chat/completions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY"
      },
      body: JSON.stringify({
        model: "deepseek-chat",
        messages: [{
          role: "user",
          content: `生成一个适合${playerLevel}级玩家的支线任务描述,包含任务名称、目标和奖励。JSON格式返回。`
        }]
      })
    });
    const data = await response.json();
    return data.choices[0].message.content;
  }
}

// 场景 2:用大模型做游戏本地化翻译
class LocalizationHelper {
  async translate(text: string, targetLang: string): Promise<string> {
    const response = await fetch("https://api.moyu.info/v1/chat/completions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY"
      },
      body: JSON.stringify({
        model: "gpt-4o",
        messages: [{
          role: "user",
          content: `将以下游戏文本翻译成${targetLang},保持游戏语境:\n${text}`
        }]
      })
    });
    const data = await response.json();
    return data.choices[0].message.content;
  }
}

你可以在 NPC 对话、任务生成、多语言本地化、甚至智能难度调节上引入大模型能力。而且 Superpowers 因为是 JS 运行时,调 API 就像写前端一样自然,不需要折腾什么奇怪的桥接层。


八、竞品速览:到底选谁?

维度 Superpowers Unity Godot Phaser
安装体积 ~100MB ~3GB ~60MB 几十MB
脚本语言 TypeScript C# GDScript/C# JavaScript/TS
Web 渲染 ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
3D 能力 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐
移动端优化 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
社区规模 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
学习曲线 平缓 陡峭 中等 平缓
开源协议 MIT 专有(免费版有条件) MIT MIT

一句话总结:如果你的目标是做 Web 端 2D 游戏,或者快速出原型,Superpowers 是性价比最高的选择。如果你要做 3A 大作或者主机游戏——出门左转找 Unity/Unreal。


九、学习路径和资源

从零到能独立做游戏,推荐这条路:

  1. 第 1 天:安装引擎,跑通"旋转立方体"示例,熟悉编辑器和场景树
  2. 第 2~3 天:学 Behavior 生命周期(awake / update / destroy),理解游戏循环
  3. 第 4~7 天:实现键盘/鼠标输入、精灵动画、简单碰撞
  4. 第 2 周:做一个完整的小游戏(Flappy Bird / 打砖块 / 太空射击)
  5. 第 3 周:学习音效系统、粒子效果、UI 系统
  6. 第 4 周:导出发布、性能优化、加联网功能

全程用 TypeScript,你不需要学任何新语言。

官方文档地址:Superpowers HTML5 - The Ultimate Free & Open-Source Game Engine!,GitHub 上搜 superpowers 也能找到几十个开源 Demo 项目。


十、总结:哪些人适合用 Superpowers?

✅ 强烈推荐给你,如果你:

  • 是 Web 前端开发者,想尝试做游戏
  • 想做独立游戏但不想花时间学 C# 或 C++
  • 项目以 2D 为主、需要 Web 端优先发布
  • 需要快速验证游戏玩法原型
  • 看重开源协议,不希望被引擎厂商锁死

❌ 不太适合你,如果你:

  • 目标是做 3A 级 3D 大作
  • 需要强大的粒子系统和后处理管线
  • 游戏重度依赖物理模拟
  • 计划发布到主机平台(PS5、Switch 等)

十一、补充:想让你的游戏"有脑子"?试试大模型 API

上面第七节的代码里用到了大模型 API,让 NPC 不再是复读机——它能根据玩家的行为动态生成对话,能给每个人生成不一样的任务,还能自动做多语言翻译。

如果你不想自己折腾模型部署和运维,可以直接接入现成的大模型 API 平台。

这里推荐 魔芋 API——一个企业级大模型管理与服务平台,聚合了国内外主流大模型:

  • 🧠 模型齐全:GPT、DeepSeek、Claude、Qwen、seedance2 等国内外一线模型,一个 API Key 全搞定
  • 💰 按量付费:不用买显卡、不用搭服务器,调一次算一次的钱
  • 🔐 统一接入:全部走 OpenAI 兼容格式,你写的代码不用改就能切模型
  • 📊 用量管理:后台实时看调用量、费用、延迟,团队协作也支持
  • ✅ 企业AI网关:团队需求大也有专门的团队管理网关

👉 https://www.moyu.info/register?aff=g2d7

回到游戏开发的场景,你完全可以在 Superpowers 里这么做:

  • NPC 对话 → 调 GPT,角色扮演对话质量拉满
  • 关卡随机生成 → 调 DeepSeek,成本低还能批量跑
  • 多语言翻译 → 调 Claude,翻译质量业界一流
  • 图片素材 → 调 gpt-image2 ,nano banana,直接出 sprite

        对于没后端团队的独立开发者来说,这比自建推理服务省心太多了。注册后先白嫖体验额度,觉得好用再进阶。


写在最后:Superpowers 不是最强大的引擎,但它很可能是对 Web 开发者最友好的引擎。在这个游戏引擎越来越重型、越来越复杂的时代,一款轻量、开源、用 TypeScript 写逻辑的工具,值得更多关注。

如果你看完这篇文章决定上手试试,那么这篇文章的目的就达到了。


如果有收获,欢迎点赞收藏。有任何开发上的问题,评论区见。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐