excalibur-ui

0.0.0-4 • Public • Published

excalibur-ui

⚠️ very much a work in progress ⚠️

Render UI in Excalibur.js games using JSX with SolidJS. It is recommended to be familiar with Solid before using this library.

Installation

excalibur-ui requires either Babel or Vite to compile the JSX.

Babel

npm install excalibur-ui solid-js babel-preset-solid

Update your .babelrc file:

{
  "presets": [
    [
      "babel-preset-solid",
      {
        "moduleName": "excalibur-ui",
        "generate": "universal"
      }
    ]
  ]
}

Vite

npm install excalibur-ui solid-js vite-plugin-solid

Update your vite config file:

import { defineConfig } from 'vite'
import solidPlugin from 'vite-plugin-solid'

export default defineConfig({
  plugins: [
    solidPlugin({
      solid: {
        moduleName: 'excalibur-ui',
        generate: 'universal',
      },
    }),
  ],
})

Usage

UI can be rendered either on a Scene or Entity, and should be called once during onInitialize.

import { renderUI } from 'excalibur-ui'

class Scene extends ex.Scene {
  onInitialize() {
    renderUI(this, () => {
      return (
        <ex-text
          text="Hello World!"
          pos={ex.vec(100, 100)}
          color="#ffffff"
          font={{
            size: 50,
            family: 'Arial',
          }}
        />
      )
    })
  }
}

class Actor extends ex.Actor {
  onInitialize() {
    renderUI(this, () => {
      return (
        <ex-text
          text="Hello World!"
          pos={ex.vec(100, 100)}
          color="#ffffff"
          font={{
            size: 50,
            family: 'Arial',
          }}
        />
      )
    })
  }
}

Using state

Since excalibur-ui is build on top of Solid, you can use signals and effects the same way you would in Solid components.

You may want to manage state at the entity/scene level using class properties, so excalibur-ui provides a useValue hook that will provide a signal that is updated every frame. You can use this to get values from the parent entity/scene.

import { useValue } from 'excalibur-ui'

class Actor extends ex.Actor {
  onInitialize() {
    this.pos = ex.vec(100, 100)

    renderUI(this, () => {
      const pos = useValue(() => this.pos)

      return (
        <ex-text
          text="Hello World!"
          pos={pos()}
          color="#ffffff"
          font={{
            size: 50,
            family: 'Arial',
          }}
        />
      )
    })
  }
}

HTML elements

All HTML elements are supported and render on top of the game canvas.

import { useValue } from 'excalibur-ui'

class Actor extends ex.Actor {
  onInitialize() {
    this.pos = ex.vec(100, 100)

    renderUI(this, () => {
      const screenPos = useValue(() =>
        this.scene.engine.worldToScreenCoordinates(this.pos),
      )

      return (
        <div
          style={{
            position: 'absolute',
            top: `${screenPos().x}px`,
            left: `${screenPos().y}px`,
            color: 'white',
          }}
        >
          hello world
        </div>
      )
    })
  }
}

Excalibur elements

There's a lot missing here, but currently you can use:

  • ex-view
  • ex-graphic
  • ex-text
  • ex-rectangle

and these will render as native Excalibur entities onto the scene.

class Scene extends ex.Scene {
  onInitialize() {
    renderUI(this, () => {
      return (
        <ex-view pos={ex.vec(100, 100)}>
          <ex-graphic
            graphic={new ex.Circle({ radius: 5, color: ex.Color.Red })}
          />
          <ex-text
            text="Hello World!"
            pos={ex.vec(100, 100)}
            color="#ffffff"
            font={{
              size: 50,
              family: 'Arial',
            }}
          />
          <ex-rectangle
            pos={ex.vec(100, 300)}
            color="#ff4400"
            width={140}
            height={80}
          />
        </ex-view>
      )
    })
  }
}

Dependencies (1)

Dev Dependencies (12)

Package Sidebar

Install

npm i excalibur-ui

Weekly Downloads

0

Version

0.0.0-4

License

ISC

Unpacked Size

72.6 kB

Total Files

17

Last publish

Collaborators

  • mattjennings