Lattice Workshop - Step 4.2

Select entities on click

Next step

We want to be able to select entities by clicking on them (to then be able to control the selected entity with the keyboard in the next step.)

To be able to mark an entity as selected we add a Selected component. Then we modify the click handler in the InputSystem to add the Selected component to the entity at the clicked coord if the player is already spawned.

We can verify the functionality by selecting an entity in the Lattice Launcher and observing the corresponding console log.

Files changed (2) hide show
  1. client/src/Game.ts +2 -0
  2. client/src/systems/InputSystem.ts +21 -2
client/src/Game.ts CHANGED
@@ -50,6 +50,7 @@ export async function createGame(contractAddress: string, privateKey: string, ch
50
50
  const Heart = createBoolComponent(world, "Heart");
51
51
  const Attack = createUintComponent(world, "Attack");
52
52
  const Life = createTupleComponent(world, "Life");
53
+ const Selected = createBoolComponent(world, "Selected");
53
54
 
54
55
  const components = {
55
56
  Position,
@@ -62,6 +63,7 @@ export async function createGame(contractAddress: string, privateKey: string, ch
62
63
  Heart,
63
64
  Attack,
64
65
  Life,
66
+ Selected,
65
67
  };
66
68
 
67
69
  /*****************************************
client/src/systems/InputSystem.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { Context } from "../types";
2
2
  import { map, filter } from "rxjs";
3
3
  import { pixelToWorldCoord } from "@latticexyz/phaser-middleware";
4
+ import { exists, Has, HasValue, removeComponent, setComponent } from "@latticexyz/mobx-ecs";
4
5
 
5
6
  export function createInputSystem(context: Context) {
6
7
  const {
8
+ components: { OwnedBy, Selected, Position },
7
9
  phaser: { input, map: tilemap },
8
10
  api: { spawn },
11
+ signer,
9
12
  } = context;
10
13
 
11
14
  input.click$
@@ -15,7 +18,23 @@ export function createInputSystem(context: Context) {
15
18
  filter((coord) => coord.x >= 0 && coord.y >= 0 && coord.x < tilemap.width && coord.y < tilemap.height) // Filter clicks outside the map
16
19
  )
17
20
  .subscribe((coord) => {
18
- console.log("Spawn at", coord);
19
- spawn(coord);
21
+ if (exists([HasValue(OwnedBy, { value: signer.address })]) == undefined) {
22
+ // If not spawned, spawn
23
+ console.log("Spawning at", coord);
24
+ spawn(coord);
25
+ } else {
26
+ // Else, select the entity below the cursor
27
+
28
+ // Remove the Selected component from the currently selected entity
29
+ const selectedEntity = exists([Has(Selected)]);
30
+ if (selectedEntity != undefined) removeComponent(Selected, selectedEntity);
31
+
32
+ // Add the Selected component to the entity below the cursor
33
+ const entityAtPos = exists([HasValue(Position, coord), HasValue(OwnedBy, { value: signer.address })]);
34
+ if (entityAtPos) {
35
+ console.log("Selected entity", entityAtPos, "at", coord);
36
+ setComponent(Selected, entityAtPos, {});
37
+ }
38
+ }
20
39
  });
21
40
  }