Lattice Workshop - Step 4.3

Add key bindings

Next step

To control the selected entity using the keyboard, we add a actionDirection method, which gets the position of the currently selected entity and calls the action method with the coord in the specified direction.

Then we add keybindings to the InputSystem by using the input.onKeyPress method provided by @latticexyz/phaser-middleware.

Files changed (2) hide show
  1. client/src/Game.ts +23 -2
  2. client/src/systems/InputSystem.ts +21 -1
client/src/Game.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { createWorld, Entity } from "@latticexyz/mobx-ecs";
1
+ import { createWorld, Entity, exists, getComponentValue, Has } from "@latticexyz/mobx-ecs";
2
2
  import { createMapping, loadEvents, setupContracts, setupMappings } from "../packages/lattice-eth-middleware";
3
3
  import { setupPhaser } from "@latticexyz/phaser-middleware";
4
4
  import {
@@ -20,6 +20,7 @@ import { createTextureSystem } from "./systems/TextureSystem";
20
20
  import { createAppearanceSystem } from "./systems/AppearanceSystem";
21
21
  import { Coord } from "./types";
22
22
  import { createInputSystem } from "./systems/InputSystem";
23
+ import { Directions } from "./constants";
23
24
 
24
25
  export async function createGame(contractAddress: string, privateKey: string, chainId: number, personaId: number) {
25
26
  const world = createWorld();
@@ -93,6 +94,26 @@ export async function createGame(contractAddress: string, privateKey: string, ch
93
94
  async function action(entity: Entity, target: Coord) {
94
95
  await txExecutor.sendTx((contract) => contract.action(entity, target));
95
96
  }
97
+ function actionDirection(direction: keyof typeof Directions) {
98
+ // Get the currently selected entity
99
+ const selected = exists([Has(Selected)]);
100
+ if (selected == undefined) {
101
+ console.warn("No entity selected");
102
+ return;
103
+ }
104
+
105
+ // Get the currently selected entity's position
106
+ const currentPosition = getComponentValue(Position, selected);
107
+ if (!currentPosition) {
108
+ console.warn("Entity has no position");
109
+ return;
110
+ }
111
+
112
+ // Execute an action at the coord in the given direction
113
+ const delta = Directions[direction];
114
+ const newPosition = { x: currentPosition.x + delta.x, y: currentPosition.y + delta.y };
115
+ action(selected, newPosition);
116
+ }
96
117
 
97
118
  const context = {
98
119
  world,
@@ -102,7 +123,7 @@ export async function createGame(contractAddress: string, privateKey: string, ch
102
123
  signer,
103
124
  txExecutor,
104
125
  personaId,
105
- api: { spawn, action },
126
+ api: { spawn, action, actionDirection },
106
127
  };
107
128
 
108
129
  /*****************************************
client/src/systems/InputSystem.ts CHANGED
@@ -7,10 +7,30 @@ export function createInputSystem(context: Context) {
7
7
  const {
8
8
  components: { OwnedBy, Selected, Position },
9
9
  phaser: { input, map: tilemap },
10
- api: { spawn },
10
+ api: { spawn, actionDirection },
11
11
  signer,
12
12
  } = context;
13
13
 
14
+ input.onKeyPress(
15
+ (keys) => keys.has("W") || keys.has("UP"),
16
+ () => actionDirection("Up")
17
+ );
18
+
19
+ input.onKeyPress(
20
+ (keys) => keys.has("A") || keys.has("LEFT"),
21
+ () => actionDirection("Left")
22
+ );
23
+
24
+ input.onKeyPress(
25
+ (keys) => keys.has("S") || keys.has("DOWN"),
26
+ () => actionDirection("Down")
27
+ );
28
+
29
+ input.onKeyPress(
30
+ (keys) => keys.has("D") || keys.has("RIGHT"),
31
+ () => actionDirection("Right")
32
+ );
33
+
14
34
  input.click$
15
35
  .pipe(
16
36
  map((pointer) => ({ x: pointer.worldX, y: pointer.worldY })), // Map pointer to pointer pixel cood