1.4.6 • Published 5 months ago

@axieinfinity/mixer v1.4.6

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

@axieinfinity/mixer

NPM version

A utility for rendering 2D Axie with support for accessories, animations.

Use @axieinfinity/mixer in your project

📦 Installation

npm install @axieinfinity/mixer

or with yarn

yarn add @axieinfinity/mixer

⚠️ Important Notes

  • This version does not include data by default. You must import the required JSON data files and call initAxieMixer before using the utility functions.
  • To render evolved parts, use version 1.4.1 or later.

🆕 Features

🚀 Example Usage

1. Initialize Mixer and Render an Axie

import {
  initAxieMixer,
  AxieBuilderResult,
  getAxieSpineFromGenes,
} from '@axieinfinity/mixer';
import GenesData from '@axieinfinity/mixer/dist/data/axie-2d-v3-stuff-genes.json';
import SamplesData from '@axieinfinity/mixer/dist/data/axie-2d-v3-stuff-samples.json';
import VariantsData from '@axieinfinity/mixer/dist/data/axie-2d-v3-stuff-variant.json';
import AnimationsData from '@axieinfinity/mixer/dist/data/axie-2d-v3-stuff-animations.json';

initAxieMixer(GenesData, SamplesData, VariantsData, AnimationsData);

const axieGenes512 = '0x20000000000003000181a09082040000000100040800800400000090086044020001000010008002000100100840450200010004186044020001001008808404';
const skipAnimation = false;

const meta = new Map();
meta.set('accessory-id', '2727'); // set accessory-id to axieId
meta.set('accessory-air', 'accessory-air1a');
meta.set('accessory-cheek', 'accessory-cheek1a');
meta.set('accessory-ground', 'accessory-ground1a');
meta.set('accessory-hip', 'accessory-hip1a');
meta.set('accessory-neck', 'accessory-neck1a');
meta.set('accessory-suit-off', 'true'); // set accessory-suit-off to true or false toggle mystic suit

const {
  skeletonDataAsset,
  combo,
  variant
}: AxieBuilderResult = getAxieSpineFromGenes(axieGenes512, meta, skipAnimation);

2. Displaying Accessories on an Axie

import { Assets } from 'pixi.js';
import { Spine } from 'pixi-spine';
import { ISkeletonData } from '@pixi-spine/base';

interface AccessoryFields {
  name: string;
  placement: string; // e.g., Air | Ground | Cheek
  key: string; // e.g., ground1a | air1d | cheek2a
}

const ACCESSORY_SPINES_URL = 'https://axiecdn.axieinfinity.com/mixer-stuffs/accessory-spines/v1';

function getSpineUrl(key: string): string {
  /*
  * e.g. https://axiecdn.axieinfinity.com/mixer-stuffs/accessory-spines/v1/air1b/air1b.json
  *      https://axiecdn.axieinfinity.com/mixer-stuffs/accessory-spines/v1/air1a/air1a.json
  * */
  return `${ACCESSORY_SPINES_URL}/${key}/${key}.json`;
}

class AccessoryModel {
  spine: Spine;
  data: AccessoryFields;

  constructor(data: AccessoryFields, spineData: ISkeletonData) {
    this.data = data;
    this.spine = new Spine(spineData);
    this.spine.scale.set(1, -1); // Flip vertically for correct orientation

    const animationName = spineData.animations[0]?.name;
    if (animationName) {
      this.spine.state.setAnimation(0, animationName, true);
    }
  }

  get slotName(): string {
    // e.g., body-air, body-ground, body-cheek, etc.
    return `body-${this.data.placement.toLowerCase()}`;
  }
}

async function main() {
  const axieSpine: Spine; // Assume axieSpine is already instantiated

  const groundAccessory: AccessoryFields = {
    name: "Snowman",
    placement: "Ground",
    key: "ground1a",
  };

  const airAccessory: AccessoryFields = {
    name: "Mr. Ube",
    placement: "Air",
    key: "air1d",
  };

  const cheekAccessory: AccessoryFields = {
    name: "Bloodmaw",
    placement: "Cheek",
    key: "cheek2a",
  };

  // Create accessory assets
  Assets.addBundle("accessories", {
    [groundAccessory.key]: getSpineUrl(groundAccessory.key),
    [airAccessory.key]: getSpineUrl(airAccessory.key),
    [cheekAccessory.key]: getSpineUrl(cheekAccessory.key),
  });

  // Load accessory assets
  const assets = await Assets.loadBundle("accessories");

  // Ground accessory
  const ground = new AccessoryModel(groundAccessory, assets[groundAccessory.key]);
  const groundSlotIndex = axieSpine.skeleton.findSlotIndex(ground.slotName);
  if (groundSlotIndex >= 0) {
    axieSpine.slotContainers[groundSlotIndex].addChild(ground.spine);
  }

  // Air accessory
  const air = new AccessoryModel(airAccessory, assets[airAccessory.key]);
  const airSlotIndex = axieSpine.skeleton.findSlotIndex(air.slotName);
  if (airSlotIndex >= 0) {
    axieSpine.slotContainers[airSlotIndex].addChild(air.spine);
  }

  // Cheek accessory
  const cheek = new AccessoryModel(cheekAccessory, assets[cheekAccessory.key]);
  const cheekSlotIndex = axieSpine.skeleton.findSlotIndex(cheek.slotName);
  if (cheekSlotIndex >= 0) {
    axieSpine.slotContainers[cheekSlotIndex].addChild(cheek.spine);
  }

  // continue with Pixi application ....
}

main();
1.4.6

5 months ago

1.4.4

10 months ago

1.4.3

10 months ago

1.4.1

1 year ago

1.4.0-beta.14

1 year ago

1.3.0-beta.2

2 years ago

1.3.0-beta.1

3 years ago

1.2.0

3 years ago

1.0.1

3 years ago

0.1.1

3 years ago

1.0.0

3 years ago