Git Product home page Git Product logo

alchemy's Introduction

โš—๏ธ alchemy engine

๐Ÿ‘พ Easily make 2D browser games with pixi.js

โœจ 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

๐Ÿ™… 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

alchemy's People

Contributors

sajmoni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

alchemy's Issues

Template: Add a settings screen

  • Enable setting sound level
  • Enable choosing language
  • Play sound on volume change
  • Nicer design
  • Improve Slider component
  • Easy to customize

Idea: "Lite" mode flag

Only includes the essentials

Could also be a console GUI where the user picks which features to include. All should be checked as default:

Ideas to be possible to exclude:

  • Translations
  • Electron

Enable parcel v2

Pixi's resource loader requires spritesheet files to be copied as is to the dist folder. Currently parcel-plugin-static-files-copy is used for this, but this won't work in v2. I need to figure out a new way to do this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.