Commit e9e4d11c authored by Chunchi Che's avatar Chunchi Che

add attack animation

parent 5bbb6526
import { ygopro } from "@/api";
import { eventbus, Task } from "@/infra";
import { eventbus, sleep, Task } from "@/infra";
import { cardStore, fetchEsHintMeta } from "@/stores";
export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
......@@ -18,15 +18,16 @@ export default async (attack: ygopro.StocGameMessage.MsgAttack) => {
if (attack.direct_attack) {
await eventbus.call(Task.Attack, attacker.uuid, true);
} else {
const target = cardStore.at(
attack.target_location.zone,
attack.target_location.controller,
attack.target_location.sequence
await eventbus.call(
Task.Attack,
attacker.uuid,
false,
attack.target_location
);
await eventbus.call(Task.Attack, attacker.uuid, false, target);
}
} else {
console.warn(`<Attack>attacker from ${attack.attacker_location} is null`);
}
await sleep(1000);
};
......@@ -100,7 +100,9 @@ export const Card: FC<{ idx: number }> = React.memo(({ idx }) => {
target?: ygopro.CardLocation
) => {
if (uuid === state.uuid) {
await attack({ card: state, api, target, directAttack });
await addToAnimation(() =>
attack({ card: state, api, target, directAttack })
);
}
}
);
......
// 暂时先简单实现攻击动画,后面有时间再慢慢优化
import { easings } from "@react-spring/web";
import { ygopro } from "@/api";
import { CardType } from "@/stores";
import { CardType, isMe } from "@/stores";
import { matConfig } from "../../utils";
import { SpringApi } from "./types";
import { asyncStart } from "./utils";
const { BLOCK_WIDTH, BLOCK_HEIGHT_M, BLOCK_HEIGHT_S, COL_GAP, ROW_GAP } =
matConfig;
export const attack = async (props: {
card: CardType;
api: SpringApi;
target?: ygopro.CardLocation;
directAttack: boolean;
target?: ygopro.CardLocation;
}) => {
// TODO
const { card, api, directAttack, target } = props;
const current = api.current[0].get();
let x = current.x;
let y = current.y;
if (directAttack) {
// 直接攻击
y = BLOCK_HEIGHT_M.value + BLOCK_HEIGHT_S.value;
if (isMe(card.location.controller)) {
y = -y;
}
} else if (target) {
// 攻击`target`
const { controller, sequence } = target;
if (sequence > 4) {
// 额外怪兽区
x = (sequence > 5 ? 1 : -1) * (BLOCK_WIDTH.value + COL_GAP.value);
y = 0;
} else {
x = (sequence - 2) * (BLOCK_WIDTH.value + COL_GAP.value);
y = BLOCK_HEIGHT_M.value + ROW_GAP.value;
}
// 往下偏移半个卡位
y -= BLOCK_HEIGHT_M.value / 2;
if (!isMe(controller)) {
x = -x;
y = -y;
}
} else {
console.error(`<Spring/Attack>directAttack is false and target is null.`);
return;
}
// 先浮空
await asyncStart(api)({
z: 200,
});
// 后撤半个卡位
await asyncStart(api)({
y:
current.y +
(BLOCK_HEIGHT_M.value / 2) * (isMe(card.location.controller) ? 1 : -1),
});
// 加速前冲
await asyncStart(api)({
x,
y,
config: {
easing: easings.easeInOutSine,
},
});
// 减速归位
await asyncStart(api)({
x: current.x,
y: current.y,
z: current.z,
config: {
easing: easings.easeInOutQuad,
},
});
};
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