如何在 React Three Fiber / ThreeJs 上交换元素

how to swap elements on React Three Fiber / ThreeJs

我有这个 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 link 在这里:https://github.com/iagokrt/board-game-threejs 我正在为董事会想出一个愚蠢的逻辑。

这个问题比Whosebug的标准答案复杂得多,所以我只回答了一部分。动画部分对我来说是最有趣的,所以我解决了那个问题。

如果您想交换棋盘上的立方体,您必须根据它们的 x,y 位置设置动画。所以我将 x,y 坐标添加到 useSpring,它将使用语言环境 属性。您必须在要在网格位置 属性.

中使用它们的位置添加插值函数
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