Commit b31c944e authored by timel's avatar timel

feat: chaining animation

parent 52e966b5
...@@ -20,6 +20,7 @@ declare global { ...@@ -20,6 +20,7 @@ declare global {
var myExtraDeckCodes: number[]; var myExtraDeckCodes: number[];
enum Report { enum Report {
Move = "move", Move = "move",
Chaining = "chaining",
} }
interface Console { interface Console {
color: ( color: (
......
...@@ -22,6 +22,7 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => { ...@@ -22,6 +22,7 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => {
const target = cardStore.find(location); const target = cardStore.find(location);
if (target) { if (target) {
target.chainIndex = matStore.chains.length; target.chainIndex = matStore.chains.length;
eventBus.emit(Report.Chaining, target.uuid);
} else { } else {
console.warn(`<Chaining>target from ${location} is null`); console.warn(`<Chaining>target from ${location} is null`);
} }
......
...@@ -10,7 +10,13 @@ import { useConfig } from "@/config"; ...@@ -10,7 +10,13 @@ import { useConfig } from "@/config";
import { cardStore, CardType, messageStore } from "@/stores"; import { cardStore, CardType, messageStore } from "@/stores";
import { interactTypeToString } from "../../utils"; import { interactTypeToString } from "../../utils";
import { moveToDeck, moveToGround, moveToHand, moveToOutside } from "./springs"; import {
moveToDeck,
moveToGround,
moveToHand,
moveToOutside,
chaining,
} from "./springs";
const NeosConfig = useConfig(); const NeosConfig = useConfig();
...@@ -50,8 +56,12 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -50,8 +56,12 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
case REMOVED: case REMOVED:
await moveToOutside({ card: state, api }); await moveToOutside({ card: state, api });
break; break;
case TZONE:
// TODO: 衍生物直接消散
break;
} }
}; };
useEffect(() => { useEffect(() => {
move(state.zone); move(state.zone);
}, []); }, []);
...@@ -62,14 +72,17 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => { ...@@ -62,14 +72,17 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
/** 动画序列的promise,当不是undefined,就说明现在这个卡有动画 */ /** 动画序列的promise,当不是undefined,就说明现在这个卡有动画 */
let animation: Promise<void> | undefined = undefined; let animation: Promise<void> | undefined = undefined;
eventBus.on(Report.Move, (uuid) => { eventBus.on(Report.Move, (uuid: string) => {
if (uuid === state.uuid) { if (uuid === state.uuid) {
if (animation) { const p = move(state.zone);
// 当前有动画,move等当前动画完成之后再播放 animation = animation ? animation.then(() => p) : p;
animation = animation.then(() => move(state.zone)); }
} else { });
animation = move(state.zone);
} 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 "./moveToDeck";
export * from "./toGround"; export * from "./moveToGround";
export * from "./toHand"; export * from "./moveToHand";
export * from "./toOutside"; export * from "./moveToOutside";
export * from "./chaining";
import { easings } from "@react-spring/web"; import { easings } from "@react-spring/web";
import { ygopro } from "@/api"; import { ygopro } from "@/api";
import { cardStore, type CardType, isMe } from "@/stores"; import { type CardType, isMe, cardStore } from "@/stores";
import { matConfig } from "../../utils"; import { matConfig } from "../../utils";
import { SpringApi } from "./types"; import { SpringApi } from "./types";
......
import { type SpringConfig, type SpringRef } from "@react-spring/web"; import { type SpringConfig, type SpringRef } from "@react-spring/web";
export const asyncStart = <T extends {}>(api: SpringRef<T>) => { export const asyncStart = <T extends {}>(api: SpringRef<T>) => {
return (p: Partial<T> & { config: SpringConfig }) => return (p: Partial<T> & { config?: SpringConfig }) =>
new Promise((resolve) => { new Promise((resolve) => {
api.start({ api.start({
...p, ...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