0.1.4 • Published 8 months ago

alchemy-engine v0.1.4

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

:alembic: alchemy engine

👾 Easily make 2D browser games with pixi.js

:sparkles: Features

  • Reactive - Re-render view when state changes
  • Pooling - Create all game object up front - in render never add or remove game objects
  • Timer - Run logic every X ticks
  • Animations
  • Debug overlay
  • Keyboard input
  • Sounds
  • Sprite sheet generation
  • Scenes
  • CLI - Create project and components
  • CI - Workflows to build, test and deploy to itch.io
  • Screen shake
  • 100% Type-Safe
  • Batteries included (get started using one CLI command)
  • Uses vite for a super fast and modern dev server

:no_good: Out of scope

Getting started

npx alchemy-engine@latest create <game-name>

Module API

create

sprite

import { sprite } from 'alchemy-engine'

sprite(container, textures['./square-1'])

animatedSprite

import { animatedSprite } from 'alchemy-engine'

animatedSprite(container, [textures['./square-1']])

text

import { text } from 'alchemy-engine'

text(container, textStyle, 'Hello world')

htmlText

import { htmlText } from 'alchemy-engine'

htmlText(container, textStyle, 'Hello world')

bitmapText

import { bitmapText } from 'alchemy-engine'

bitmapText(container, textStyle, 'Hello world')

container

import { container } from 'alchemy-engine'

container(_container)

graphics

import { graphics } from 'alchemy-engine'

graphics(container)

rectangle

import { rectangle } from 'alchemy-engine'

rectangle(container, { x: 0, y: 0, width: 10, height: 10 })

event

onClick

import { onClick } from 'alchemy-engine'

onClick(container, () => {
  console.log('Clicked!')
})

onHover

import { onHover } from 'alchemy-engine'

onHover(container, {
  onOver() {
    console.log('Hovered!')
  },
  onOut() {
    console.log('Not hovered!')
  },
})

sync

sync

syncPosition

keys

arrowKeys

Constants for all arrow keys

import { arrowKeys } from 'alchemy-engine'

export const keys = ['a', 'w', 's', 'd', ...arrowKeys] as const

position

TODO

getAllChildren

TODO

getAllLeafChildren

TODO

debug

logObject

Nicely log a Pixi object. Set label property for best result.

import { logObject } from 'alchemy-engine'

const sprite = new Sprite()
sprite.label = 'sprite'
logObject(sprite)

boundsToString

Enables easier logging of sprite bounds

import { boundsToString } from 'alchemy-engine'

console.log(boundsToString(sprite))

contains

Check if a point is within the bounds of an object

import { contains } from 'alchemy-engine'

if (contains(sprite, { x: 1, y: 1 })) {
  // point is within bounds of sprite
}

intersects

Check if the bounds of two objects are intersecting

import { intersects } from 'alchemy-engine'

if (intersects(sprite1, sprite2)) {
  // sprites are intersecting
}

type guards

isAnimatedSprite

import { isAnimatedSprite } from 'alchemy-engine'

if (isAnimatedSprite(sprite)) {
  // sprite is of type AnimatedSprite
}

loadDataFromImage

This function can be used to for example load a level from image data

import { loadDataFromImage } from 'alchemy-engine'
import map from '~/public/asset/map.png?url'

const { pixels, width, height } = await loadDataFromImage(map)
console.log(pixels)
// ['255-255-255', '0-0-0']

pool

Docs


Scene API

The arguments passed to a scene

{
  textures,
  container,
  input,
  state,
  timer,
  sound,
  app,
  timer,
  useScreenShake,
}: Scene

textures

An object containing all textures by name

Record<TextureName, Texture>
function myScene({ textures, container }: Scene) {
  sprite(container, textures['./square1'])
}

getTextures

Get multiple textures

function myScene({ getTextures, container }: Scene) {
  const textures = getTextures(['./texture-1', './texture-2'])
  animatedSprite(container, textures)
}

useScreenShake

Enable the use of screen shake

const screenShake = useScreenShake(container)
screenShake.add(0.5)

animate

  • sine
  • easeOut
  • easeIn

These functions all require an onUpdate and duration argument

Optionally you can pass a startValue (default: 0) and endValue (default: 1)

util

  • center

app

The Pixi Application instance

music

Record<MusicName, Howl>

sound

Record<SoundName, Howl>

setScene

setScene('mainMenu')

global

timer

A timer that doesn't get cancelled when changing scenes

container

A scene specific Pixi container. Will be destroyed when scene is changed.

state

Set state to trigger sync and subscribe functions

subscribe, subscribeKey, proxy

Re-exported from valtio

timer

delay

// Wait 100 updates
await delay(100)

repeatUntil

Execute a callback every update until duration is reached

await repeatUntil(3, (time, deltaTime) => {})

repeatEvery

Execute a callback forever every interval updates

Returns a cancel function

const cancel = repeatEvery(3, (time, deltaTime) => {})

input

debouncedKey

debouncedKey(
  // Key id
  'd',
  // Callback
  () => {
    s.position.x += 1
  },
  // Delay between key presses
  10,
)

isKeyDown

Check if a key is currently being pressed

repeatEvery(1, () => {
  if (isKeyDown(['a', 'ArrowLeft'])) {
    s.position.x -= 1
  }
  if (isKeyDown(['d', 'ArrowRight'])) {
    s.position.x += 1
  }
})

random

There is a built-in seedable random module.

To set the seed, pass it in to createGame

The module uses the same API as park-miller, with some additions:

chance(percentage) => boolean


CLI

create

npx alchemy-engine@latest create <game-name>

dev

Start the dev server. Listens to changes to source code, sprite, src/public/asset/sound and src/public/asset/music folders.

npx alchemy-engine@latest dev

sprite

Generate sprite sheet

npx alchemy-engine@latest sprite

sound

Load sounds

npx alchemy-engine@latest sound
0.1.4

8 months ago

0.1.2

8 months ago

0.1.3

8 months ago

0.1.0

9 months ago

0.1.1

9 months ago

0.0.30

1 year ago

0.0.31

1 year ago

0.0.32

1 year ago

0.0.26

1 year ago

0.0.27

1 year ago

0.0.28

1 year ago

0.0.29

1 year ago

0.0.25

1 year ago

0.0.23

2 years ago

0.0.24

1 year ago

0.0.21

2 years ago

0.0.22

2 years ago

0.0.20

2 years ago

0.0.18

2 years ago

0.0.19

2 years ago

0.0.15

2 years ago

0.0.16

2 years ago

0.0.17

2 years ago

0.0.14

2 years ago

0.0.13

2 years ago

0.0.12

2 years ago

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago