diff --git a/src/components/map/MapInteraction.js b/src/components/map/MapInteraction.js
index a55e3c1..8f89ecc 100644
--- a/src/components/map/MapInteraction.js
+++ b/src/components/map/MapInteraction.js
@@ -18,8 +18,6 @@ import MapStageContext, {
import AuthContext from "../../contexts/AuthContext";
import SettingsContext from "../../contexts/SettingsContext";
import KeyboardContext from "../../contexts/KeyboardContext";
-import { PlayerUpdaterContext } from "../../contexts/PlayerContext";
-import PartyContext from "../../contexts/PartyContext";
function MapInteraction({
map,
@@ -180,8 +178,6 @@ function MapInteraction({
const auth = useContext(AuthContext);
const settings = useContext(SettingsContext);
- const player = useContext(PlayerUpdaterContext);
- const party = useContext(PartyContext);
const mapInteraction = {
stageScale,
@@ -223,19 +219,15 @@ function MapInteraction({
/>
{/* Forward auth context to konva elements */}
-
-
-
-
-
-
- {mapLoaded && children}
-
-
-
-
-
-
+
+
+
+
+ {mapLoaded && children}
+
+
+
+
diff --git a/src/components/party/Party.js b/src/components/party/Party.js
index 45eee01..b766946 100644
--- a/src/components/party/Party.js
+++ b/src/components/party/Party.js
@@ -17,12 +17,12 @@ import useSetting from "../../helpers/useSetting";
import PartyContext from "../../contexts/PartyContext";
import {
PlayerUpdaterContext,
- PlayerStateWithoutPointerContext,
+ PlayerStateContext,
} from "../../contexts/PlayerContext";
function Party({ gameId, stream, partyStreams, onStreamStart, onStreamEnd }) {
const setPlayerState = useContext(PlayerUpdaterContext);
- const playerState = useContext(PlayerStateWithoutPointerContext);
+ const playerState = useContext(PlayerStateContext);
const partyState = useContext(PartyContext);
const [fullScreen] = useSetting("map.fullScreen");
diff --git a/src/contexts/PlayerContext.js b/src/contexts/PlayerContext.js
index 4a756da..c3c1cca 100644
--- a/src/contexts/PlayerContext.js
+++ b/src/contexts/PlayerContext.js
@@ -9,10 +9,6 @@ import { getRandomMonster } from "../helpers/monsters";
export const PlayerStateContext = React.createContext();
export const PlayerUpdaterContext = React.createContext(() => {});
-/**
- * Store the player state without the pointer data to prevent unnecessary updates
- */
-export const PlayerStateWithoutPointerContext = React.createContext();
export function PlayerProvider({ session, children }) {
const { userId } = useContext(AuthContext);
@@ -23,7 +19,6 @@ export function PlayerProvider({ session, children }) {
nickname: "",
timer: null,
dice: { share: false, rolls: [] },
- pointer: { position: { x: 0, y: 0 }, visible: false },
sessionId: null,
userId,
},
@@ -94,27 +89,10 @@ export function PlayerProvider({ session, children }) {
};
});
- const [playerStateWithoutPointer, setPlayerStateWithoutPointer] = useState(
- playerState
- );
- useEffect(() => {
- const { pointer, ...state } = playerState;
- if (
- !playerStateWithoutPointer ||
- !compare(playerStateWithoutPointer, state)
- ) {
- setPlayerStateWithoutPointer(state);
- }
- }, [playerState, playerStateWithoutPointer]);
-
return (
-
- {children}
-
+ {children}
);
diff --git a/src/network/NetworkedMapPointer.js b/src/network/NetworkedMapPointer.js
index afa4374..9494eba 100644
--- a/src/network/NetworkedMapPointer.js
+++ b/src/network/NetworkedMapPointer.js
@@ -2,24 +2,23 @@ import React, { useState, useContext, useEffect, useRef } from "react";
import { Group } from "react-konva";
import AuthContext from "../contexts/AuthContext";
-import PartyContext from "../contexts/PartyContext";
-import { PlayerUpdaterContext } from "../contexts/PlayerContext";
import MapPointer from "../components/map/MapPointer";
import { isEmpty } from "../helpers/shared";
import { lerp, compare } from "../helpers/vector2";
-// Send pointer updates every 33ms
-const sendTickRate = 100;
+// Send pointer updates every 50ms (20fps)
+const sendTickRate = 50;
-let t = 0;
-
-function NetworkedMapPointer({ active, gridSize }) {
+function NetworkedMapPointer({ session, active, gridSize }) {
const { userId } = useContext(AuthContext);
- const setPlayerState = useContext(PlayerUpdaterContext);
- const partyState = useContext(PartyContext);
const [localPointerState, setLocalPointerState] = useState({});
+ const sessionRef = useRef(session);
+ useEffect(() => {
+ sessionRef.current = session;
+ }, [session]);
+
useEffect(() => {
if (userId && !(userId in localPointerState)) {
setLocalPointerState({
@@ -44,14 +43,15 @@ function NetworkedMapPointer({ active, gridSize }) {
if (counter > sendTickRate) {
counter -= sendTickRate;
- if (ownPointerUpdateRef.current) {
- const { position, visible } = ownPointerUpdateRef.current;
- console.log("send time", performance.now() - t);
- t = performance.now();
- setPlayerState((prev) => ({
- ...prev,
- pointer: { position, visible },
- }));
+ if (
+ ownPointerUpdateRef.current &&
+ sessionRef.current &&
+ sessionRef.current.socket
+ ) {
+ sessionRef.current.socket.emit(
+ "player_pointer",
+ ownPointerUpdateRef.current
+ );
ownPointerUpdateRef.current = null;
}
}
@@ -86,13 +86,9 @@ function NetworkedMapPointer({ active, gridSize }) {
const interpolationsRef = useRef({});
useEffect(() => {
// TODO: Handle player disconnect while pointer visible
- const interpolations = interpolationsRef.current;
- for (let player of Object.values(partyState)) {
- const id = player.userId;
- const pointer = player.pointer;
- if (!id) {
- continue;
- }
+ function handleSocketPlayerPointer(pointer) {
+ const interpolations = interpolationsRef.current;
+ const id = pointer.id;
if (!(id in interpolations)) {
interpolations[id] = {
id,
@@ -103,8 +99,6 @@ function NetworkedMapPointer({ active, gridSize }) {
!compare(interpolations[id].to.position, pointer.position, 0.0001) ||
interpolations[id].to.visible !== pointer.visible
) {
- console.log("receive time", performance.now() - t, pointer.position);
- t = performance.now();
const from = interpolations[id].to;
interpolations[id] = {
id,
@@ -119,14 +113,23 @@ function NetworkedMapPointer({ active, gridSize }) {
};
}
}
- }, [partyState]);
+
+ if (session.socket) {
+ session.socket.on("player_pointer", handleSocketPlayerPointer);
+ }
+
+ return () => {
+ session.socket.off("player_pointer", handleSocketPlayerPointer);
+ };
+ }, [session]);
// Animate to the peer pointer positions
useEffect(() => {
let request = requestAnimationFrame(animate);
- function animate(time) {
+ function animate() {
request = requestAnimationFrame(animate);
+ const time = performance.now();
let interpolatedPointerState = {};
for (let interp of Object.values(interpolationsRef.current)) {
if (!interp.from || !interp.to) {