Commit 6b669d0a authored by Chunchi Che's avatar Chunchi Che

Merge branch 'dev/chains0607' into 'main'

连锁优化

See merge request !380
parents 069dd0a3 f2f8c8d8
Pipeline #27899 passed with stages
in 8 minutes and 35 seconds
...@@ -32,39 +32,6 @@ ...@@ -32,39 +32,6 @@
opacity: 0.5; opacity: 0.5;
} }
} }
.triangle {
display: none;
--color: red;
position: absolute;
transition: 0.3s;
transform: scale(1.2);
.triangle-atom {
width: 20px;
height: 5px;
background-color: red;
position: absolute;
&:last-of-type {
transform: rotate(90deg);
transform-origin: 2.5px 2.5px;
}
}
&:nth-of-type(1) {
left: 0;
}
&:nth-of-type(2) {
transform: rotate(90deg);
right: 0;
}
// &:nth-of-type(3) {
// transform: rotate(180deg);
// right: 0;
// bottom: 0;
// }
// &:nth-of-type(4) {
// transform: rotate(270deg);
// bottom: 0;
// }
}
} }
// 下面应该和moveToOutside、moveToGround对应 // 下面应该和moveToOutside、moveToGround对应
...@@ -152,7 +119,9 @@ ...@@ -152,7 +119,9 @@
.block.glowing { .block.glowing {
--shadow-color: #13a1ff; --shadow-color: #13a1ff;
box-shadow: 0 0 3px 3px var(--shadow-color), 0 0 25px 2px #0099ff87; box-shadow:
0 0 3px 3px var(--shadow-color),
0 0 25px 2px #0099ff87;
background: var(--shadow-color); background: var(--shadow-color);
border-radius: 2px; border-radius: 2px;
.triangle { .triangle {
......
...@@ -37,7 +37,6 @@ const BgBlock: React.FC< ...@@ -37,7 +37,6 @@ const BgBlock: React.FC<
[styles.glowing]: glowing, [styles.glowing]: glowing,
})} })}
> >
{<DecoTriangles />}
{<DisabledCross disabled={disabled} />} {<DisabledCross disabled={disabled} />}
{<BgChain {...chains} />} {<BgChain {...chains} />}
</div> </div>
...@@ -103,6 +102,9 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => { ...@@ -103,6 +102,9 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => {
const removed = op ? snap[REMOVED].op : snap[REMOVED].me; const removed = op ? snap[REMOVED].op : snap[REMOVED].me;
const extra = op ? snap[EXTRA].op : snap[EXTRA].me; const extra = op ? snap[EXTRA].op : snap[EXTRA].me;
const getN = (zone: ygopro.CardZone) =>
cardStore.at(zone, meController).length;
const genChains = (states: Snapshot<BlockState[]>) => { const genChains = (states: Snapshot<BlockState[]>) => {
const chains: number[] = states.flatMap((state) => state.chainIndex); const chains: number[] = states.flatMap((state) => state.chainIndex);
chains.sort(); chains.sort();
...@@ -115,25 +117,37 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => { ...@@ -115,25 +117,37 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => {
<BgBlock <BgBlock
className={styles.banish} className={styles.banish}
glowing={!op && glowingBanish} glowing={!op && glowingBanish}
chains={{ chains: genChains(removed), banish: true, op }} chains={{
chains: genChains(removed),
op,
nBelow: getN(REMOVED),
}}
/> />
<BgBlock <BgBlock
className={styles.graveyard} className={styles.graveyard}
glowing={!op && glowingGraveyard} glowing={!op && glowingGraveyard}
chains={{ chains: genChains(grave), graveyard: true, op }} chains={{
chains: genChains(grave),
op,
nBelow: getN(GRAVE),
}}
/> />
<BgBlock <BgBlock
className={styles.field} className={styles.field}
onClick={() => onBlockClick(field.interactivity)} onClick={() => onBlockClick(field.interactivity)}
disabled={field.disabled} disabled={field.disabled}
highlight={!!field.interactivity} highlight={!!field.interactivity}
chains={{ chains: field.chainIndex, field: true, op }} chains={{ chains: field.chainIndex, op }}
/> />
<BgBlock className={styles.deck} chains={{ chains: [] }} /> <BgBlock className={styles.deck} chains={{ chains: [] }} />
<BgBlock <BgBlock
className={classnames(styles.deck, styles["extra-deck"])} className={classnames(styles.deck, styles["extra-deck"])}
glowing={!op && glowingExtra} glowing={!op && glowingExtra}
chains={{ chains: genChains(extra), extra: true, op }} chains={{
chains: genChains(extra),
op,
nBelow: getN(EXTRA),
}}
/> />
</div> </div>
); );
...@@ -165,17 +179,6 @@ const onBlockClick = (placeInteractivity: PlaceInteractivity) => { ...@@ -165,17 +179,6 @@ const onBlockClick = (placeInteractivity: PlaceInteractivity) => {
} }
}; };
const DecoTriangles: React.FC = () => (
<>
{Array.from({ length: 2 }).map((_, i) => (
<div className={styles.triangle} key={i}>
<div className={styles["triangle-atom"]} />
<div className={styles["triangle-atom"]} />
</div>
))}
</>
);
const DisabledCross: React.FC<{ disabled: boolean }> = ({ disabled }) => ( const DisabledCross: React.FC<{ disabled: boolean }> = ({ disabled }) => (
<div <div
className={classnames(styles["disabled-cross"], { className={classnames(styles["disabled-cross"], {
......
...@@ -10,8 +10,7 @@ const { HAND } = ygopro.CardZone; ...@@ -10,8 +10,7 @@ const { HAND } = ygopro.CardZone;
export const HandChain: React.FC = () => { export const HandChain: React.FC = () => {
const snap = useSnapshot(placeStore.inner); const snap = useSnapshot(placeStore.inner);
const me = snap[HAND].me; const { me, op } = snap[HAND];
const op = snap[HAND].op;
const genChains = (states: Snapshot<BlockState[]>) => { const genChains = (states: Snapshot<BlockState[]>) => {
const chains: number[] = states.flatMap((state) => state.chainIndex); const chains: number[] = states.flatMap((state) => state.chainIndex);
......
...@@ -16,14 +16,17 @@ section.mat { ...@@ -16,14 +16,17 @@ section.mat {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
// perspective: var(--perspective); perspective: var(--perspective);
}
.camera,
.camera * {
// 所有元素加入同一个三维渲染上下文:https://acgtofe.com/posts/2013/09/css-3d-transform
transform-style: preserve-3d;
} }
.plane { .plane {
transform: translateX(0) translateY(0) translateZ(0) transform: translateX(0) translateY(0) translateZ(0)
rotateX(var(--plane-rotate-x)); rotateX(var(--plane-rotate-x));
width: fit-content; width: fit-content;
perspective: var(--perspective);
} }
} }
...@@ -34,6 +37,4 @@ section.mat { ...@@ -34,6 +37,4 @@ section.mat {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
transform-style: preserve-3d;
} }
...@@ -52,7 +52,7 @@ const _matConfigWithUnit: Record<string, [number, UNIT]> = { ...@@ -52,7 +52,7 @@ const _matConfigWithUnit: Record<string, [number, UNIT]> = {
COL_GAP: [10, UNIT.PX], COL_GAP: [10, UNIT.PX],
CARD_RATIO: [5.9 / 8.6, UNIT.NONE], CARD_RATIO: [5.9 / 8.6, UNIT.NONE],
HAND_MARGIN_TOP: [0, UNIT.PX], HAND_MARGIN_TOP: [0, UNIT.PX],
HAND_CIRCLE_CENTER_OFFSET_Y: [2000, UNIT.PX], HAND_CIRCLE_CENTER_OFFSET_Y: [6000, UNIT.PX],
HAND_CARD_HEIGHT: [130, UNIT.PX], HAND_CARD_HEIGHT: [130, UNIT.PX],
HAND_MAT_OFFSET_Y: [140, UNIT.PX], // 手卡离场地的偏移 HAND_MAT_OFFSET_Y: [140, UNIT.PX], // 手卡离场地的偏移
DECK_OFFSET_X: [140, UNIT.PX], DECK_OFFSET_X: [140, UNIT.PX],
......
...@@ -2,31 +2,18 @@ ...@@ -2,31 +2,18 @@
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
min-width: 8rem;
max-width: 10rem;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
z-index: 2;
pointer-events: none; pointer-events: none;
} }
.banish,
.graveyard {
left: 70%;
}
.field,
.extra-deck {
right: 130%;
}
.op { .op {
transform: rotate(180deg); transform: rotate(180deg);
} }
.chain { .chain {
position: relative; transform: translateZ(calc(var(--n) * 1px + 3px));
width: 50%; width: 50%;
height: 50%; height: 50%;
display: flex; display: flex;
......
...@@ -8,38 +8,30 @@ const { assetsPath } = useConfig(); ...@@ -8,38 +8,30 @@ const { assetsPath } = useConfig();
export interface ChainProps { export interface ChainProps {
chains: readonly number[]; chains: readonly number[];
banish?: boolean; nBelow?: number; // 浮在该区域最上方一张卡的上面,需要感知有多少卡
graveyard?: boolean;
extra?: boolean;
field?: boolean;
op?: boolean; op?: boolean;
} }
/* 这里有个妥协的实现:墓地,除外区,额外卡组的连锁图标会被卡片遮挡,原因不明, /* 这里有个妥协的实现:墓地,除外区,额外卡组的连锁图标会被卡片遮挡,原因不明,
* 因此这里暂时采取移动一个身位的方式进行解决。最好的解决方案应该是UI上连锁图标和 * 因此这里暂时采取移动一个身位的方式进行解决。最好的解决方案应该是UI上连锁图标和
* 场地解耦。 */ * 场地解耦。 */
export const BgChain: React.FC<ChainProps> = ({ export const BgChain: React.FC<ChainProps> = ({ chains, nBelow = 1, op }) => (
chains,
banish,
graveyard,
extra,
field,
op,
}) => (
<div <div
className={classnames(styles.container, { className={classnames(styles.container, {
[styles.banish]: banish,
[styles.graveyard]: graveyard,
[styles["extra-deck"]]: extra,
[styles.field]: field,
[styles.op]: op, [styles.op]: op,
})} })}
style={{
// @ts-ignore
"--n": nBelow,
}}
> >
{chains.map((chain) => ( {/* 暂时只适配最后的连锁,不然肯定会出现错位 */}
<div className={styles.chain} key={chain}> {!!chains.length &&
<img src={`${assetsPath}/chain.png`} /> [Math.max(...chains)].map((chain) => (
<div className={styles.text}>{chain}</div> <div className={styles.chain} key={chain}>
</div> <img src={`${assetsPath}/chain.png`} />
))} <div className={styles.text}>{chain}</div>
</div>
))}
</div> </div>
); );
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