Commit b31c944e authored by timel's avatar timel

feat: chaining animation

parent 52e966b5
Pipeline #21961 passed with stages
in 19 minutes and 3 seconds
......@@ -20,6 +20,7 @@ declare global {
var myExtraDeckCodes: number[];
enum Report {
Move = "move",
Chaining = "chaining",
}
interface Console {
color: (
......
......@@ -22,6 +22,7 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => {
const target = cardStore.find(location);
if (target) {
target.chainIndex = matStore.chains.length;
eventBus.emit(Report.Chaining, target.uuid);
} else {
console.warn(`<Chaining>target from ${location} is null`);
}
......
......@@ -10,7 +10,13 @@ import { useConfig } from "@/config";
import { cardStore, CardType, messageStore } from "@/stores";
import { interactTypeToString } from "../../utils";
import { moveToDeck, moveToGround, moveToHand, moveToOutside } from "./springs";
import {
moveToDeck,
moveToGround,
moveToHand,
moveToOutside,
chaining,
} from "./springs";
const NeosConfig = useConfig();
......@@ -50,8 +56,12 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
case REMOVED:
await moveToOutside({ card: state, api });
break;
case TZONE:
// TODO: 衍生物直接消散
break;
}
};
useEffect(() => {
move(state.zone);
}, []);
......@@ -62,14 +72,17 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
/** 动画序列的promise,当不是undefined,就说明现在这个卡有动画 */
let animation: Promise<void> | undefined = undefined;
eventBus.on(Report.Move, (uuid) => {
eventBus.on(Report.Move, (uuid: string) => {
if (uuid === state.uuid) {
if (animation) {
// 当前有动画,move等当前动画完成之后再播放
animation = animation.then(() => move(state.zone));
} else {
animation = move(state.zone);
}
const p = move(state.zone);
animation = animation ? animation.then(() => p) : p;
}
});
eventBus.on(Report.Chaining, (uuid: string) => {
if (uuid === state.uuid) {
const p = chaining({ card: state, api });
animation = animation ? animation.then(() => p) : p;
}
});
......
import { easings } from "@react-spring/web";
import { ygopro } from "@/api";
import { type CardType, isMe, matStore } from "@/stores";
import { matConfig } from "../../utils";
import { SpringApi } from "./types";
import { asyncStart } from "./utils";
/** 发动效果的动画 */
export const chaining = async (props: { card: CardType; api: SpringApi }) => {
const { card, api } = props;
const current = api.current[0].get();
if (card.zone === ygopro.CardZone.HAND) {
await asyncStart(api)({
y: current.y + (matStore.isMe(card.controller) ? -1 : 1) * 200, // TODO: 放到config之中
rz: 0,
});
await asyncStart(api)({ y: current.y, rz: current.rz });
} else {
await asyncStart(api)({ z: 200 });
await asyncStart(api)({ z: current.z });
}
};
export * from "./toDeck";
export * from "./toGround";
export * from "./toHand";
export * from "./toOutside";
export * from "./moveToDeck";
export * from "./moveToGround";
export * from "./moveToHand";
export * from "./moveToOutside";
export * from "./chaining";
import { easings } from "@react-spring/web";
import { ygopro } from "@/api";
import { cardStore, type CardType, isMe } from "@/stores";
import { type CardType, isMe, cardStore } from "@/stores";
import { matConfig } from "../../utils";
import { SpringApi } from "./types";
......
import { type SpringConfig, type SpringRef } from "@react-spring/web";
export const asyncStart = <T extends {}>(api: SpringRef<T>) => {
return (p: Partial<T> & { config: SpringConfig }) =>
return (p: Partial<T> & { config?: SpringConfig }) =>
new Promise((resolve) => {
api.start({
...p,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment