February 22, 2023

Реактивный пикси

Иногда раз в неделю, бывает чаще, бывает реже, я пишу гиперказуалки на Pixi.js. Не доделываю обычно до конца, интересен больше процесс решения сложных ситуаций и поиск выхода: как красивее и проще всего решить конфликт архитектурный (да, я типа нахожу себе головоломки, вместо всяких игр-головоломок, я думаю такие люди как я и делают такие игры).

Но есть нерешенная проблема, что приходится придумывать геморойный велосипед как писать на Pixi не только функционально, но и реактивно. Не жду прям реакт рендера, но хочется, чтобы оно само красиво обновлялось.

Я долго делал обертку через
Ticker.shared.tick(() => {}) и придумывал как сделать это с
function useState<T>(value: T): [T, (value: T) => void] потому что нет реактивного обновление стейта у детей

А потом случайно наткнулся на React Pixi.
https://pixijs.io/pixi-react/stage/

Ох, сколько идей, это можно теперь делать типа игру на привычном компонентном подходе реактивном, но рисовать графику с пикси.


OLD

Есть вот такой пример (1), где мы создаем типа хук, но не хук, функцию, которая возвращает игрока и мы можем у его instance менять скорость, например каждую секунду увеличивать.

// My old variant with vanilla Pixi. js
export function PlayerShort0) {
  const sprite = Sprite.from("player.png");
  
  // init speed
  const [speed, setSpeed] = useState(0);
  
  const newProps = { setSpeed, speed };
  return Object. assign (sprite, newProps);
}

export function SceneShort() {
  const container = new Container();
  
  const player = PlayerShort();
  
  // update speed
  Ticker. shared. tick( (dt) = {
    player.setSpeed (Math. floor(dt));
  };
  
  // result speed
  console.log(player.speed);
  
  container. addChild (player);
}

Надо создавать отдельные инстансы, связывать методы, добавлять к контейнеру как в DOM

Так же както придумать, как обновлять стейт

NEW

(2)-ой вариант с ReactPixi, где мы контролируем скорость игрока верхнеуровнего, скорее всего делать надо както подругому, чтобы методы были более приватные и логическо относились друг к другу, но

// New variant with ReactPixi, React, Pixi. js
export function ReactScene() {
  // init speed
  const [playerSpeed, setPlayerSpeed] = React.useState(0)
  
  const i = ReactPixi.useIteration(1)
  // update speed
  setPlayerSpeed(i)  

  return (
    ‹Container>
      ‹Player speed={speed}>
    </Container>
  )
}

export function ReactPLayer({ speed }) {
  // result sped
  console.log(speed);
  return ‹Sprite image="player.png" />;
}

Зато теперь мы просто в дереве как в React используем Player и все, само снова нормально обновляется