0

我有这个 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 我想出了一个愚蠢的董事会逻辑。

4

1 回答 1

1

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

如果您想在板上交换立方体,您必须按它们的 x,y 位置设置动画。所以我将 x,y 坐标添加到 useSpring,它将使用 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 组件的 locale 属性,它将为新位置设置动画。

我创建了一个小例子。我在计时器中更改了语言环境,您可以看到它与动画交换。

https://codesandbox.io/s/react-tree-fiber-board-5mbns?file=/src/App.js

于 2020-07-20T08:52:03.970 回答