🗡️Excalibur v0.30.0 发布!

今天,我们很高兴地宣布推出迄今为止最大、最好的 Excalibur.js 版本!我们有很多成就要谈,也有很多感谢要说!

立即安装最新版本!查看完整发行说明

npm install excalibur@0.30.1

项目健康

从高层次来看:

  • 非常感谢我们的赞助商和赞助者
  • Github 上有 1.8k 颗星!给我们一颗星吧!
  • excaliburjs.com 每月平均页面浏览量为 15k
  • 此版本中 OSS 项目的贡献者数量创下了历史记录 代码文档问题和讨论 Discord 讨论
  • Discord 社区规模迅速扩大
  • 2 位新核心贡献者 Matt Jennings Justin Young
  • 订阅 Excalibur.js 新闻通讯
  • 订阅 Excalibur.js YouTube 频道以观看即将推出的视频
  • 此外,我们还在明尼苏达州布卢明顿的 2D Con 举办了我们的首次现场活动!今年春天我们将参加 VGM Con!

    全新“Excalibird”教程

    在此版本中,我们添加了一个受 Flappy Bird 启发的全新教程。这是从头开始构建的,旨在帮助您像我们一样编写 excalibur 游戏。本教程旨在构建一个可持续的项目结构,可以随着您的游戏设计而发展。查看完整源代码并立即试用。非常感谢 discord 用户 `.rodgort` 提供的所有有用反馈。

    新的快速入门

    您是否知道我们有一个 Excalibur CLI 可以帮助您快速启动游戏?查看我们的新快速入门指南,以创纪录的速度使用您喜欢的前端技术(包括 vanilla.js)完成您的新项目。

    npx create-excalibur@latest

    我们已将支持此 CLI 的所有 Excalibur.js 模板更新至最新和最好的版本!

    你知道社区成员 Manu Hernandez 创造了这个吗?在 Discord 上向他表示感谢吧!

    生活质量

    浏览器扩展

    新的 Excalibur.js 开发工具扩展可在 Firefox 和 Chrome 中使用

    如果你想做出贡献,我们有一个关于此扩展的功能愿望清单,

    开发 Excalibur 构建

    我们正在发布新的 `excalibur.development.js` 版本,该版本增加了调试输出,以捕获开发过程中的常见问题。例如,如果您忘记将 Actor 添加到场景中(我经常遇到这种情况)!

    const orphan = new ex.Actor({
        name: 'orphaned'
    });
    
    // OOOPS! I forgot to add orphan Actor to a Scene
    warning in console about orphaned actor

    当“NODE_ENV=production”时,这些额外的警告将被删除,以供您进行产品构建!

    这个重要的生活品质功能是由 Matt Jennings 添加的!

    静态调试绘制 API

    现在,您可以使用 ex.Debug.* API 进行调试绘制,而无需了解图形上下文。只有当引擎处于调试模式“ex.Engine.isDebug”时,这些绘制才可见。

    这非常适合检查你的点、射线、线等是否在你期望的位置!

    马特·詹宁斯 (Matt Jennings) 提出了另一个出色的功能创意。

    onPreUpdate(engine: ex.Engine, elapsedMs: number): void {
        this.vel = ex.Vector.Zero;
    
        this.graphics.use('down-idle');
        if (engine.input.keyboard.isHeld(ex.Keys.ArrowRight)) { ... }
        if (engine.input.keyboard.isHeld(ex.Keys.ArrowLeft)) { ... }
        if (engine.input.keyboard.isHeld(ex.Keys.ArrowUp)) { ... }
        if (engine.input.keyboard.isHeld(ex.Keys.ArrowDown)) { ... }
    
        ex.Debug.drawRay(new ex.Ray(this.pos, this.vel), { distance: 100, color: ex.Color.Red });
    }

    新样品

    微小战术

    战术游戏的高保真示例,具有多级别、AI 和寻路功能!

    https://github.com/excaliburjs/sample-tropics

    果冻套头衫

    受“超级马里奥世界”启发的具有跳跃物理的平台游戏的高保真样本!

    https://github.com/excaliburjs/sample-jelly-jumper

    神剑鸟

    这是流行手机游戏 Flappy Bird 的一个示例克隆。

    https://github.com/excaliburjs/sample-excalibird/

    路径寻找

    使用 A* 和 Dijkstra 的寻路插件进行采样!

    https://github.com/excaliburjs/sample-pathfinding

    使用 HTML/CSS/JS 的 UI

    如何使用 Excalibur 代码构建原始 html/css/js UI 的示例。主要要点是将 HTML 层放在画布层上方并将其用于 UI。

    https://github.com/excaliburjs/sample-html

    JSFXR

    这是一个快速演示项目,使用 Excalibur-JSFXR 插件创建、存储和播放生成的声音效果!

    https://github.com/excaliburjs/sample-jsfxr

    新模板

    查看我们用于构建移动和桌面游戏的全新 Tauri v2 和 Capacitor.js 模板!

    Tauri 带有一个漂亮的 Rust 后端,所以如果您喜欢的话,它可能是用于访问所有应用商店的东西。

    Capacitor.js 是 Cordova 的精神继承者,提供了许多跨平台插件,可同时为 iOS 和 Android 应用程序构建。

    性能,性能,性能

    此版本确实非常注重全面提高 Excalibur 的性能。社区成员 Autsider 在这方面提供了巨大帮助。

  • 新的图像渲染器,绘图性能提升 2 倍
  • 新的“稀疏哈希网格”碰撞空间数据结构可提高碰撞性能
  • 代码优化,尽可能消除热循环中的分配,减少 JavaScript GC 暂停,提高引擎的整体速度
  • ECS 优化加速实体查询
  • 我们还有一款新的 Excalibur Bunnymark,它可以对渲染器进行强调,我可以在 Surface Pro 笔记本电脑上以 30fps 的速度达到 100k!

    新功能

    这个版本充满了新的酷炫内容,其中很多都是通过 discord 上的社区讨论直接设计的!

    查看所有变更的完整发布说明

    SVG 和 Canvas 中的 ImageSource

    您现在可以从 SVG 文字字符串、SVG 文件和 HTML Canvas 元素中获取图像!这增加了可用于制作游戏的图像的灵活性。此外,SVG 和 Canvas 非常棒 🤘

    const svgExternal = new ex.ImageSource('../images/arrows.svg');
    const svg = (tags: TemplateStringsArray) => tags[0];
    
    const svgImage = ex.ImageSource.fromSvgString(svg`
      
      
      
    `);
    
    const myCanvas = document.createElement('canvas')!;
    myCanvas.width = 100;
    myCanvas.height = 100;
    const ctx = myCanvas.getContext('2d')!;
    ctx.fillStyle = ex.Color.Black.toRGBA();
    ctx.fillRect(20, 20, 50, 50);
    
    const canvasImage = ex.ImageSource.fromHtmlCanvasElement(myCanvas);

    GPU 颗粒

    GPU 粒子让您能够以较低的开销发射大量粒子。它们具有与 CPU 粒子相同的 API。

    var particles = new ex.GpuParticleEmitter({
      pos: ex.vec(100, 0),
      z: 1,
      emitterType: ex.EmitterType.Circle,
      maxParticles: 100_000,
      particle: {
        acc: ex.vec(0, 200),
        minSpeed: 1,
        maxSpeed: 5,
        opacity: 0.7,
        life: 7000,
        maxSize: 5,
        minSize: 5,
        startSize: 15,
        endSize: 1,
        beginColor: ex.Color.White,
        endColor: ex.Color.Transparent
      },
      radius: 600,
      emitRate: 1000,
      isEmitting: true
    });

    幻灯片场景转换

    新的 `ex.Slide` 场景转换,可以滑动当前屏幕的屏幕截图:`上`、`下`、`左` 或 `右`。您可以选择添加 `ex.EasingFunction`,默认情况下为 `ex.EasingFunctions.Linear`。想想塞尔达传说地牢房间转换

    game.goToScene('otherScene', {
        destinationIn: new ex.Slide({
          duration: 1000,
          easingFunction: ex.EasingFunctions.EaseInOutCubic,
          slideDirection: 'up'
        })
      });

    贝塞尔曲线和 Actor.actions.curveTo/curveBy 动作

    我们有贝塞尔曲线!!!!长期以来的请求和期望,我们现在可以使用贝塞尔曲线和新的 curveTo 和 curveBy 动作来移动演员。

    const start1 = ex.vec(500, 500);
    const dest = ex.vec(500, 100);
    const cp1 = ex.vec(100, 300);
    const cp2 = ex.vec(150, 800);
    
    // Curve object for sampling points
    const curve = new ex.BezierCurve({
      controlPoints: [start1, cp1, cp2, dest],
      quality: 10
    });
    
    var points: ex.Vector[] = [];
    const drawCurve = () => {
      points.length = 0;
      for (let i = 0; i < 100; i++) {
        points.push(curve.getPoint(i / 100));
      }
    };
    drawCurve();
    
    // Use the curve action to move along a curve
    actor.actions.repeatForever((ctx) => {
      ctx.curveTo({
        controlPoints: [cp1, cp2, dest],
        duration: 5000,
        mode: 'uniform'
      });
      ctx.curveTo({
        controlPoints: [cp2, cp1, start1],
        duration: 5000,
        mode: 'uniform'
      });
    });

    快闪行动

    我们现在有一个方便的闪光动作,可用于在演员的图形上闪烁颜色。这对于受到伤害的事物或您需要向玩家指示某事时非常有用。

    actor.actions.flash(ex.Color.White, 1000)

    九片精灵

    新的`ex.NineSlice` `Graphic` 可用于创建任意可调整大小的矩形区域,可用于创建 UI、背景和其他可调整大小的元素。

    var nineSlice = new ex.NineSlice({
        width: 300,
        height: 100,
        source: inputTile,
        sourceConfig: {
          width: 64,
          height: 64,
          topMargin: 5,
          leftMargin: 7,
          bottomMargin: 5,
          rightMargin: 7
        },
        destinationConfig: {
          drawCenter: true,
          horizontalStretch: ex.NineSliceStretch.Stretch,
          verticalStretch: ex.NineSliceStretch.Stretch
        }
      });
    
      actor.graphics.add(nineSlice);

    查看演示

    nine slice demo

    平铺精灵和动画

    适用于平铺精灵和动画的全新便捷类型 `ex.TiledSprite` 和 `ex.TiledAnimation`

    const tiledGroundSprite = new ex.TiledSprite({
        image: groundImage,
        width: game.screen.width,
        height: 200,
        wrapping: {
          x: ex.ImageWrapping.Repeat,
          y: ex.ImageWrapping.Clamp
        }
      });
    
      const tilingAnimation = new ex.TiledAnimation({
        animation: cardAnimation,
        sourceView: {x: 20, y: 20},
        width: 200,
        height: 200,
        wrapping: ex.ImageWrapping.Repeat
      });

    完整的 GIF 图像规范支持

    我们现在支持大多数 gif 规范,并可以将 gif 文件解析为资源!

    var gif: ex.Gif = new ex.Gif('./loading-screen.gif');
    var gif2: ex.Gif = new ex.Gif('./sword.gif');
    var gif3: ex.Gif = new ex.Gif('./stoplight.gif');
    var loader = new ex.Loader([gif, gif2, gif3]);
    game.start(loader).then(() => {
      var stoplight = new ex.Actor({
        x: game.currentScene.camera.x + 120,
        y: game.currentScene.camera.y,
        width: gif3.width,
        height: gif3.height
      });
      stoplight.graphics.add(gif3.toAnimation());
      game.add(stoplight);
    
      var sword = new ex.Actor({
        x: game.currentScene.camera.x - 120,
        y: game.currentScene.camera.y,
        width: gif2.width,
        height: gif2.height
      });
      sword.graphics.add(gif2.toAnimation());
      game.add(sword);
    
      var loading = new ex.Actor({
        x: game.currentScene.camera.x,
        y: game.currentScene.camera.y,
        width: gif2.width,
        height: gif2.height
      });
      loading.graphics.add(gif.toAnimation());
      game.add(loading);
    });

    GPU 垃圾回收

    Excalibur 现在会监视 60 秒内未绘制的纹理,并将其从 GPU 中卸载。这对于随时间推移拥有大量不同资产的大型游戏来说至关重要。

    协程改进

  • 嵌套协程
  • 可等待
  • 自定义时间表
  • 停止/启动/恢复
  • 卡利本游戏

    Excalibur.js 贡献者提供咨询服务!您可以聘请我们进行游戏开发、定制开发或支持!如果您有兴趣,请查看我们当前的产品列表 https://caliburn.games/products/

    Caliburn Games 的目标是用 TypeScript 构建友好的游戏,并支持 Excalibur.js 社区和开源项目。

    光辉的未来

    我们对 Excalibur.js 的未来感到非常兴奋和乐观,我们对 2025 年有很多很酷的计划。我们重申我们对成为一个开源项目的承诺,我们将永远开源,永远不会改变 BSD 的许可证。

    新事业

  • 请关注 Excalibur 课程 @ https://excaliburjs.tv,我们正在发布一些免费和付费课程选项。
  • 我们正在构建一个开源“Excalibur Studio”可视化编辑器,这是为了进一步实现我们的使命,即让尽可能多的人参与游戏开发。编辑器将采用按需付费模式,0 美元完全可以接受。我们不希望收入成为人们参与游戏制作的障碍。
  • Caliburn Games 将在各种平台上发布游戏,敬请期待 2025 年的精彩内容!如果您有兴趣聘请我们来帮助您开发游戏,也请联系我们!
  • 公路圣剑 v1

    我们的计划是在 2025 年初发布 v1 的候选版本,核心引擎已经达到了我们非常满意的程度。从 v0.30.0 到 v1.0.0,API 不会有太大变化。

    很多人询问有关 WebGPU 的问题,我们将等待渲染器的实现,直到 API 的标准化稳定下来,并且 WebGPU 实现在浏览器中默认启用。

    下一步计划:

  • 性能更佳!
  • 物理增强!绳索!逆运动学!
  • 服务器上的无头圣剑
  • 输入映射和 A11y 改进
  • 2D 照明支持
  • 谢谢

    我们已经在 Excalibur.js 上工作了十多年,这很有趣

    圣剑!!!

    Cal 的 GIF 由 discord 用户“hintoflime”提供