Skip to content

Commit

Permalink
feat(templates/threejs): easier to use template (#2473)
Browse files Browse the repository at this point in the history
Co-authored-by: Fraser Scott <[email protected]>
  • Loading branch information
qbzzt and yonadaaa authored Mar 22, 2024
1 parent af74f91 commit e08b616
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 23 deletions.
2 changes: 1 addition & 1 deletion templates/threejs/packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@latticexyz/store-sync": "link:../../../../packages/store-sync",
"@latticexyz/utils": "link:../../../../packages/utils",
"@latticexyz/world": "link:../../../../packages/world",
"@react-three/fiber": "^8.12.0",
"@react-three/fiber": "^8.15.19",
"contracts": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
164 changes: 148 additions & 16 deletions templates/threejs/packages/client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,81 @@
import React from "react";
/* eslint-disable react/no-unknown-property */
// Workaround react-three-fiber types by disabling unknown properties:
// https://github.com/pmndrs/react-three-fiber/discussions/2487

import { Canvas, Color, ThreeElements, useThree } from "@react-three/fiber";
import { useComponentValue, useEntityQuery } from "@latticexyz/react";
import { getComponentValueStrict, Has } from "@latticexyz/recs";
import { useMUD } from "./MUDContext";
import { useKeyboardMovement } from "./useKeyboardMovement";

const Plane = (props: ThreeElements["mesh"]) => {
const Plane = () => {
return (
<mesh {...props}>
{/* eslint-disable-next-line react/no-unknown-property */}
<boxGeometry args={[10, 5, 10]} />
<meshStandardMaterial color="green" />
</mesh>
<>
<mesh position={[0, -1, 0]}>
<boxGeometry args={[20, 0.1, 20]} />
<meshStandardMaterial color="#000" opacity="0.9" transparent />
</mesh>

<mesh position={[0, 3, -10]}>
<boxGeometry args={[20, 5, 0.1]} />
<meshStandardMaterial color="#F00" opacity="0.5" transparent />
</mesh>

<mesh position={[10, 3, 0]}>
<boxGeometry args={[0.1, 5, 20]} />
<meshStandardMaterial color="#0F0" opacity="0.5" transparent />
</mesh>

<mesh position={[5, 2, 0]}>
<sphereGeometry args={[2, 10, 10]} />
<meshStandardMaterial color="#FF0" opacity="0.8" transparent />
</mesh>

<mesh position={[0, 2, 5]}>
<sphereGeometry args={[2, 10, 10]} />
<meshStandardMaterial color="#FF0" opacity="0.8" transparent />
</mesh>

<mesh position={[-5, 2, 0]}>
<sphereGeometry args={[2, 10, 10]} />
<meshStandardMaterial color="#FF0" opacity="0.8" transparent />
</mesh>

<mesh position={[0, 2, -5]}>
<sphereGeometry args={[2, 10, 10]} />
<meshStandardMaterial color="#FF0" opacity="0.8" transparent />
</mesh>

<mesh position={[5, 2, -5]}>
<sphereGeometry args={[1, 10, 10]} />
<meshStandardMaterial color="#008" opacity="0.8" transparent />
</mesh>

<mesh position={[5, 2, 5]}>
<sphereGeometry args={[1, 10, 10]} />
<meshStandardMaterial color="#008" opacity="0.8" transparent />
</mesh>

<mesh position={[-5, 2, -5]}>
<sphereGeometry args={[1, 10, 10]} />
<meshStandardMaterial color="#008" opacity="0.8" transparent />
</mesh>
</>
);
};

const Player = (props: ThreeElements["mesh"] & { color: Color }) => {
return (
<mesh {...props}>
{/* eslint-disable-next-line react/no-unknown-property */}
<boxGeometry args={[1, 2, 1]} />
<meshStandardMaterial color={props.color} />
</mesh>
<>
<mesh {...props}>
<boxGeometry args={[1, 2, 1]} />
<meshStandardMaterial color={props.color} />
</mesh>
<mesh {...props}>
<boxGeometry args={[1, 2, 1]} />
<meshStandardMaterial color={props.color} />
</mesh>
</>
);
};

Expand Down Expand Up @@ -58,7 +112,7 @@ const Scene = () => {
<ambientLight />
{/* eslint-disable-next-line react/no-unknown-property */}
<pointLight position={[10, 10, 10]} />
<Plane position={[0, -5, 0]} />
<Plane />
{players.map((p, i) => (
<Player
key={i}
Expand All @@ -72,10 +126,88 @@ const Scene = () => {

const styles = { height: "100vh" };

const Directions = () => {
return (
<>
<p>
You are the rectangular prism, moving around the scene. To move use <b>W</b>, <b>A</b>, <b>S</b>, and <b>D</b>.
You can also move up (<b>T</b>) and down (<b>G</b>).
</p>
</>
);
};

const PlayerInfo = () => {
const {
components: { Position },
network: { playerEntity },
} = useMUD();

const playerPosition = useComponentValue(Position, playerEntity);

if (!playerPosition) {
return (
<div style={{ backgroundColor: "black", color: "white" }}>
<table>
<tbody>
<tr>
<td>
<h2>Reading player position</h2>
</td>
<td>
<Directions />
</td>
</tr>
</tbody>
</table>
</div>
);
}

return (
<div style={{ backgroundColor: "black", color: "white" }}>
<table>
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<th>Coordinate</th>
<th>Value</th>
</tr>
<tr>
<th>x</th>
<td align="right">{playerPosition.x}</td>
</tr>
<tr>
<th>y</th>
<td align="right">{playerPosition.y}</td>
</tr>
<tr>
<th>z</th>
<td align="right">{playerPosition.z}</td>
</tr>
</tbody>
</table>
</td>
<td style={{ padding: 20 }}>
<Directions />
</td>
</tr>
</tbody>
</table>
</div>
);
};

export const App = () => {
return (
<Canvas style={styles}>
<Scene />
</Canvas>
<>
<PlayerInfo />
<Canvas style={styles}>
<Scene />
</Canvas>
</>
);
};
12 changes: 6 additions & 6 deletions templates/threejs/packages/client/src/useKeyboardMovement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ export const useKeyboardMovement = () => {

useEffect(() => {
const listener = (e: KeyboardEvent) => {
if (e.key === "ArrowUp") {
if (e.key === "w") {
moveBy(1, 0, 0);
}
if (e.key === "ArrowDown") {
if (e.key === "s") {
moveBy(-1, 0, 0);
}
if (e.key === "ArrowLeft") {
if (e.key === "a") {
moveBy(0, 0, -1);
}
if (e.key === "ArrowRight") {
if (e.key === "d") {
moveBy(0, 0, 1);
}
if (e.key === " ") {
if (e.key === "t") {
moveBy(0, 1, 0);
}
if (e.ctrlKey) {
if (e.key === "g") {
moveBy(0, -1, 0);
}
};
Expand Down

0 comments on commit e08b616

Please sign in to comment.