Skip to content

Instantly share code, notes, and snippets.

@dmitryshelomanov
Last active July 7, 2021 22:10
Show Gist options
  • Save dmitryshelomanov/d44c3100ab2bdde346595c2bf9b1f7fe to your computer and use it in GitHub Desktop.
Save dmitryshelomanov/d44c3100ab2bdde346595c2bf9b1f7fe to your computer and use it in GitHub Desktop.
import { createCharacter } from "@lib/pixi"
import { AnimatedIcons } from "@lib/pixi/icons"
import { root } from "@lib/root"
import { merge } from "effector"
import * as PIXI from "pixi.js"
import { GROUND_Y, HERO_X, TARGET_X } from "../constants"
import { attachEffect } from "../lib"
const { createEvent } = root
export function createPVEController({ app }: { app: PIXI.Application }) {
const animation = createEvent<string>()
const targetAnimation = createEvent<string>()
const attackCompleted = createEvent()
const targetAttackCompleted = createEvent()
const showEffect = createEvent<{
target: "hero" | "target"
type: "counter"
isDebuff?: boolean
value: string
}>()
function createStage() {
const container = new PIXI.Container()
const state = {
icons: [] as AnimatedIcons[],
character: createCharacter({
x: HERO_X,
y: GROUND_Y,
animation,
attackCompleted,
}),
target: createCharacter({
x: TARGET_X,
y: GROUND_Y,
animation: targetAnimation,
attackCompleted,
isTarget: true,
}),
}
container.addChild(state.character.sprite)
container.addChild(state.target.sprite)
app.stage.addChild(container)
state.icons.forEach((it) => {
container.addChild(it.sprite)
})
function subscribeToTicker() {
const buffRemove = showEffect.watch((params) => {
attachEffect({
...params,
addSprite: (it) => {
container.addChild(it.sprite)
state.icons.push(it)
},
})
})
function ticker() {
const currentIcons = [...state.icons]
state.character.update()
state.target.update()
currentIcons.forEach((it) => {
if (it.state.removed) {
container.removeChild(it.sprite)
state.icons = state.icons.filter((icon) => icon !== it)
} else {
it.update()
}
})
}
const stageTicker = app.ticker.add(ticker)
return () => {
buffRemove()
stageTicker.remove(ticker)
state.character.unsubscribe()
state.target.unsubscribe()
container.removeChild(state.character.sprite)
container.removeChild(state.target.sprite)
}
}
return {
character: state.character,
attackCompleted,
subscribeToTicker,
}
}
return {
animation,
targetAnimation,
attackCompleted: merge([attackCompleted, targetAttackCompleted]),
createStage,
showEffect,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment