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

Merge branch 'dev/chains0607' into 'main'

连锁优化

See merge request !380
parents 069dd0a3 f2f8c8d8
......@@ -32,39 +32,6 @@
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对应
......@@ -152,7 +119,9 @@
.block.glowing {
--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);
border-radius: 2px;
.triangle {
......
......@@ -37,7 +37,6 @@ const BgBlock: React.FC<
[styles.glowing]: glowing,
})}
>
{<DecoTriangles />}
{<DisabledCross disabled={disabled} />}
{<BgChain {...chains} />}
</div>
......@@ -103,6 +102,9 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => {
const removed = op ? snap[REMOVED].op : snap[REMOVED].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 chains: number[] = states.flatMap((state) => state.chainIndex);
chains.sort();
......@@ -115,25 +117,37 @@ const BgOtherBlocks: React.FC<{ op?: boolean }> = ({ op }) => {
<BgBlock
className={styles.banish}
glowing={!op && glowingBanish}
chains={{ chains: genChains(removed), banish: true, op }}
chains={{
chains: genChains(removed),
op,
nBelow: getN(REMOVED),
}}
/>
<BgBlock
className={styles.graveyard}
glowing={!op && glowingGraveyard}
chains={{ chains: genChains(grave), graveyard: true, op }}
chains={{
chains: genChains(grave),
op,
nBelow: getN(GRAVE),
}}
/>
<BgBlock
className={styles.field}
onClick={() => onBlockClick(field.interactivity)}
disabled={field.disabled}
highlight={!!field.interactivity}
chains={{ chains: field.chainIndex, field: true, op }}
chains={{ chains: field.chainIndex, op }}
/>
<BgBlock className={styles.deck} chains={{ chains: [] }} />
<BgBlock
className={classnames(styles.deck, styles["extra-deck"])}
glowing={!op && glowingExtra}
chains={{ chains: genChains(extra), extra: true, op }}
chains={{
chains: genChains(extra),
op,
nBelow: getN(EXTRA),
}}
/>
</div>
);
......@@ -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 }) => (
<div
className={classnames(styles["disabled-cross"], {
......
......@@ -10,8 +10,7 @@ const { HAND } = ygopro.CardZone;
export const HandChain: React.FC = () => {
const snap = useSnapshot(placeStore.inner);
const me = snap[HAND].me;
const op = snap[HAND].op;
const { me, op } = snap[HAND];
const genChains = (states: Snapshot<BlockState[]>) => {
const chains: number[] = states.flatMap((state) => state.chainIndex);
......
......@@ -16,14 +16,17 @@ section.mat {
flex-direction: column;
justify-content: 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 {
transform: translateX(0) translateY(0) translateZ(0)
rotateX(var(--plane-rotate-x));
width: fit-content;
perspective: var(--perspective);
}
}
......@@ -34,6 +37,4 @@ section.mat {
display: flex;
justify-content: center;
align-items: center;
transform-style: preserve-3d;
}
......@@ -52,7 +52,7 @@ const _matConfigWithUnit: Record<string, [number, UNIT]> = {
COL_GAP: [10, UNIT.PX],
CARD_RATIO: [5.9 / 8.6, UNIT.NONE],
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_MAT_OFFSET_Y: [140, UNIT.PX], // 手卡离场地的偏移
DECK_OFFSET_X: [140, UNIT.PX],
......
......@@ -2,31 +2,18 @@
position: relative;
width: 100%;
height: 100%;
min-width: 8rem;
max-width: 10rem;
display: flex;
justify-content: center;
align-items: center;
z-index: 2;
pointer-events: none;
}
.banish,
.graveyard {
left: 70%;
}
.field,
.extra-deck {
right: 130%;
}
.op {
transform: rotate(180deg);
}
.chain {
position: relative;
transform: translateZ(calc(var(--n) * 1px + 3px));
width: 50%;
height: 50%;
display: flex;
......
......@@ -8,38 +8,30 @@ const { assetsPath } = useConfig();
export interface ChainProps {
chains: readonly number[];
banish?: boolean;
graveyard?: boolean;
extra?: boolean;
field?: boolean;
nBelow?: number; // 浮在该区域最上方一张卡的上面,需要感知有多少卡
op?: boolean;
}
/* 这里有个妥协的实现:墓地,除外区,额外卡组的连锁图标会被卡片遮挡,原因不明,
* 因此这里暂时采取移动一个身位的方式进行解决。最好的解决方案应该是UI上连锁图标和
* 场地解耦。 */
export const BgChain: React.FC<ChainProps> = ({
chains,
banish,
graveyard,
extra,
field,
op,
}) => (
export const BgChain: React.FC<ChainProps> = ({ chains, nBelow = 1, op }) => (
<div
className={classnames(styles.container, {
[styles.banish]: banish,
[styles.graveyard]: graveyard,
[styles["extra-deck"]]: extra,
[styles.field]: field,
[styles.op]: op,
})}
style={{
// @ts-ignore
"--n": nBelow,
}}
>
{chains.map((chain) => (
<div className={styles.chain} key={chain}>
<img src={`${assetsPath}/chain.png`} />
<div className={styles.text}>{chain}</div>
</div>
))}
{/* 暂时只适配最后的连锁,不然肯定会出现错位 */}
{!!chains.length &&
[Math.max(...chains)].map((chain) => (
<div className={styles.chain} key={chain}>
<img src={`${assetsPath}/chain.png`} />
<div className={styles.text}>{chain}</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