Moved pointer out of player state and into separate socket event
This commit is contained in:
parent
501fc4377c
commit
b13b46b17d
@ -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 */}
|
||||
<AuthContext.Provider value={auth}>
|
||||
<PlayerUpdaterContext.Provider value={player}>
|
||||
<PartyContext.Provider value={party}>
|
||||
<SettingsContext.Provider value={settings}>
|
||||
<KeyboardContext.Provider value={keyboardValue}>
|
||||
<MapInteractionProvider value={mapInteraction}>
|
||||
<MapStageProvider value={mapStageRef}>
|
||||
{mapLoaded && children}
|
||||
</MapStageProvider>
|
||||
</MapInteractionProvider>
|
||||
</KeyboardContext.Provider>
|
||||
</SettingsContext.Provider>
|
||||
</PartyContext.Provider>
|
||||
</PlayerUpdaterContext.Provider>
|
||||
<SettingsContext.Provider value={settings}>
|
||||
<KeyboardContext.Provider value={keyboardValue}>
|
||||
<MapInteractionProvider value={mapInteraction}>
|
||||
<MapStageProvider value={mapStageRef}>
|
||||
{mapLoaded && children}
|
||||
</MapStageProvider>
|
||||
</MapInteractionProvider>
|
||||
</KeyboardContext.Provider>
|
||||
</SettingsContext.Provider>
|
||||
</AuthContext.Provider>
|
||||
</Layer>
|
||||
</Stage>
|
||||
|
@ -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");
|
||||
|
@ -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 (
|
||||
<PlayerStateContext.Provider value={playerState}>
|
||||
<PlayerUpdaterContext.Provider value={setPlayerState}>
|
||||
<PlayerStateWithoutPointerContext.Provider
|
||||
value={playerStateWithoutPointer}
|
||||
>
|
||||
{children}
|
||||
</PlayerStateWithoutPointerContext.Provider>
|
||||
{children}
|
||||
</PlayerUpdaterContext.Provider>
|
||||
</PlayerStateContext.Provider>
|
||||
);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user