我有这个Card组件,单击它会激活并扩展块。想要点击一个,然后点击另一个,他们切换位置。类似于:
// Initial Board
1,1,1,1,
2,2,2,2,
3,3,3,3,
4,4,4,4,
并且不在同一个号码的线上。行、列或主对角线。待完成块的订购,如:
// win condition for Board
1, 2, 3, 4,
4, 3, 2, 1,
2, 1, 4, 3,
3, 4, 1, 2,
// the Card component
const Card = ({locale, args, color, speed}) => {
const mesh = useRef(null)
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4]: [1,1,1],
})
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={locale}
ref={mesh}>
<boxBufferGeometry attach='geometry' args={args} />
<MeshWobbleMaterial attach='material' color={color} speed={speed} factor={0.6} />
</a.mesh>
)
}
// its rendering inside Canvas from react-three-fiber
<Card locale={[-2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[0, 1, -2]} color={'navy'} speed={6} />
<Card locale={[2, 1, -2]} color={'navy'} speed={6} />
<Card locale={[4, 1, -2]} color={'navy'} speed={6} />
<Card locale={[-2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[0, 3, -2]} color={'teal'} speed={3} />
<Card locale={[2, 3, -2]} color={'teal'} speed={3} />
<Card locale={[4, 3, -2]} color={'teal'} speed={3} />
<Card locale={[-2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[0, 5, -2]} color={'blue'} speed={9} />
<Card locale={[2, 5, -2]} color={'blue'} speed={9} />
<Card locale={[4, 5, -2]} color={'blue'} speed={9} />
<Card locale={[-2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[0, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[2, -1, -2]} color={'aqua'} speed={2} />
<Card locale={[4, -1, -2]} color={'aqua'} speed={2} />
github链接在这里:https://github.com/iagokrt/board-game-threejs我正在为董事会想出一个愚蠢的逻辑。
这个问题比标准的stackerflow答案复杂得多,所以我只回答其中的一部分。动画部分对我来说是最有趣的,所以我解决了这个问题。
如果你想在棋盘上交换立方体,你必须根据它们的x,y位置设置动画。所以我在useSpring中添加了x,y坐标,它将使用locale属性。必须在网格位置特性中要使用插值函数的位置添加插值函数。
const Card = ({ locale, args, color, speed }) => {
const mesh = useRef(null);
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
// expand state of the mesh. change size on click event
const [expand, setExpand] = useState(false);
const props = useSpring({
scale: expand ? [1.4, 1.4, 1.4] : [1, 1, 1],
xy: [locale[0], locale[1]]
});
return (
<a.mesh
onClick={() => setExpand(!expand)}
scale={props.scale}
castShadow
position={props.xy.interpolate((x, y) => [x, y, locale[2]])}
ref={mesh}
>
<boxBufferGeometry attach="geometry" args={args} />
<MeshWobbleMaterial
attach="material"
color={color}
speed={speed}
factor={0.6}
/>
</a.mesh>
);
};
这样,如果您更改Card组件的区域设置属性,则它将为新位置设置动画。
我创造了一个小例子。我在计时器中更改了区域设置,您可以看到它与动画互换。
https://codesandbox.io/s/react-tree-fiber-board-5mbns?file=/src/App.js