diff --git a/packages/client/src/components/Fog/styles.scss b/packages/client/src/components/Fog/styles.scss
index 0848cbb5..8e6b9a01 100644
--- a/packages/client/src/components/Fog/styles.scss
+++ b/packages/client/src/components/Fog/styles.scss
@@ -1,10 +1,10 @@
.mi-map-fog {
position: absolute;
z-index: 10;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- background: radial-gradient(circle closest-side at 50% 50%, #00000000 200px, #000000ff 80%);
+ left: -150vw;
+ top: -150vh;
+ width: 300vw;
+ height: 300vh;
+ background: radial-gradient(circle closest-side at 50% 50%, #00000000 200px, #000000ff 24%);
pointer-events: none;
}
\ No newline at end of file
diff --git a/packages/client/src/components/Map/index.tsx b/packages/client/src/components/Map/index.tsx
index 7193b0a2..53caf9df 100644
--- a/packages/client/src/components/Map/index.tsx
+++ b/packages/client/src/components/Map/index.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useRef } from 'react';
+import React, { useMemo, useRef, useState } from 'react';
import { IPlayer } from '../Player';
import MapCell, { ICellClassCache, ICoordinate } from '../MapCell';
import './styles.scss';
@@ -22,6 +22,8 @@ const Map = (props: IProps) => {
const { width, height, vertexCoordinate, data = [], players, curId, onPlayerMove } = props;
const { x: startX, y: startY } = vertexCoordinate;
+ const [prevActionCoordinate, setPrevActionCoordinate] = useState({ x: -1, y: -1});
+
const staticData = useMemo(() => {
return Array(height).fill(0).map(() => Array(width).fill(0));
}, [width, height]);
@@ -35,7 +37,11 @@ const Map = (props: IProps) => {
const playerData = useMemo(() => {
const obj = {};
players.forEach((player) => {
- obj[`${player.x}-${player.y}`] = player;
+ if (obj[`${player.x}-${player.y}`]) {
+ obj[`${player.x}-${player.y}`].push(player)
+ } else {
+ obj[`${player.x}-${player.y}`] = [player];
+ }
});
return obj;
}, [players]);
@@ -71,9 +77,11 @@ const Map = (props: IProps) => {
x,
y
}}
+ prevActionCoordinate={prevActionCoordinate}
+ onExeAction={setPrevActionCoordinate}
mapData={data}
cellClassCache={cellClassCache.current}
- player={playerData[`${x}-${y}`]}
+ players={playerData[`${x}-${y}`]}
onMoveTo={onMoveTo}
/>
)
diff --git a/packages/client/src/components/Map/styles.scss b/packages/client/src/components/Map/styles.scss
index d83d4621..46a88032 100644
--- a/packages/client/src/components/Map/styles.scss
+++ b/packages/client/src/components/Map/styles.scss
@@ -7,7 +7,6 @@
height: 100%;
.mi-map-content {
- border: 1px solid;
width: $cellSize * 24;
}
diff --git a/packages/client/src/components/MapCell/index.tsx b/packages/client/src/components/MapCell/index.tsx
index 16409276..b3ace795 100644
--- a/packages/client/src/components/MapCell/index.tsx
+++ b/packages/client/src/components/MapCell/index.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
import { CellType } from '../../constants';
import { getCellClass, isMovable } from '@/utils';
import './styles.scss';
@@ -27,12 +27,18 @@ interface IProps {
coordinate: ICoordinate,
mapData: number[][];
cellClassCache: ICellClassCache;
- player?: IPlayer;
+ players?: IPlayer[];
onMoveTo: (ICoordinate) => void;
+ prevActionCoordinate: ICoordinate;
+ onExeAction: (ICoordinate) => void;
}
const MapCell = (props: IProps) => {
- const { coordinate: { x, y}, mapData, cellClassCache, player, onMoveTo } = props;
+ const { coordinate: { x, y}, mapData, cellClassCache, players, onMoveTo, onExeAction, prevActionCoordinate } = props;
+
+ const [menuVisible, setMenuVisible] = useState(false);
+ const [activePlayerId, setActivePlayerId] = useState(-1);
+
if (!cellClassCache[`${y}-${x}`]) {
cellClassCache[`${y}-${x}`] = getCellClass(mapData, { x, y});
}
@@ -40,16 +46,49 @@ const MapCell = (props: IProps) => {
const { transforms, classList } = cellClassCache[`${y}-${x}`];
const onContextMenu = (e) => {
+ onExeAction({ x, y});
e.preventDefault();
const curMapDataType = mapData[y][x];
- if (isMovable(curMapDataType) && !player) {
+ if (isMovable(curMapDataType)) {
onMoveTo({ x, y});
}
+ }
+
+ const onClick = () => {
+ onExeAction({ x, y});
+ if (!players || players?.length === 0) {
+ return;
+ }
+ setMenuVisible(true);
+ setActivePlayerId(players[0].id)
+ }
+ const exeAction = (e, action) => {
+ e.stopPropagation();
+ setMenuVisible(false);
+ switch (action) {
+ case 'move':
+ onMoveTo({x, y});
+ break;
+ case 'info':
+ break;
+ case 'attack':
+ break;
+ }
}
+ useEffect(() => {
+ if (prevActionCoordinate.x !== x || prevActionCoordinate.y !== y) {
+ setMenuVisible(false);
+ }
+ }, [prevActionCoordinate.x, prevActionCoordinate.y])
+
return (
-
+
{
classList.map((item, index) => {
@@ -67,8 +106,47 @@ const MapCell = (props: IProps) => {
})
}
+
+ {
+ players && players.map((player) =>
)
+ }
{
- player &&
+ menuVisible && (
+
+ {
+ players?.length > 1 && (
+
+ {
+ players?.slice(0, 3).map((player) => {
+ return (
+ - {
+ setActivePlayerId(player.id);
+ e.stopPropagation();
+ }}
+ >{player.username}
+ )
+ })
+ }
+
+ )
+ }
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ )
}
);
diff --git a/packages/client/src/components/MapCell/styles.scss b/packages/client/src/components/MapCell/styles.scss
index 312a34a9..7df77bae 100644
--- a/packages/client/src/components/MapCell/styles.scss
+++ b/packages/client/src/components/MapCell/styles.scss
@@ -13,4 +13,43 @@
background: url("/src/assets/wall/wall_#{$i}.png") no-repeat center 100% / cover;
}
}
+
+ .mi-cell-user-menu {
+ position: absolute;
+ z-index: 20;
+ left: 100%;
+ top: 0;
+ display: flex;
+
+ li {
+ margin-bottom: 4px;
+ }
+
+ .mi-cell-username-list {
+ margin-right: 10px;
+
+ li {
+ padding-left: 10px;
+ width: 144px;
+ height: 44px;
+ font-size: 24px;
+ line-height: 42px;
+ color: #fff;
+ background: rgba(0, 0, 0, 0.8);
+ border-radius: 5px;
+
+ &.active {
+ text-shadow: #000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0;
+ border: 1px solid #000;
+ background: #FED982;
+ }
+ }
+ }
+
+ .mi-btn {
+ font-size: 24px;
+ width: 136px;
+ height: 46px;
+ }
+ }
}
\ No newline at end of file
diff --git a/packages/client/src/components/Player/index.tsx b/packages/client/src/components/Player/index.tsx
index d1bfa875..a82df1d7 100644
--- a/packages/client/src/components/Player/index.tsx
+++ b/packages/client/src/components/Player/index.tsx
@@ -1,5 +1,7 @@
import React from 'react';
import './styles.scss';
+import { CurIdMockData } from '@/mock/data';
+import Fog from '@/components/Fog';
export interface IPlayer {
x: number;
@@ -13,6 +15,9 @@ const Player = (props: IPlayer) => {
{props.username}
+ {
+ props.id === CurIdMockData &&
+ }
);
};
diff --git a/packages/client/src/config/index.ts b/packages/client/src/config/index.ts
index 9d7aad61..3f2f7bad 100644
--- a/packages/client/src/config/index.ts
+++ b/packages/client/src/config/index.ts
@@ -1,4 +1,9 @@
export const MapConfig = {
visualWidth: 24,
visualHeight: 16,
+}
+
+export const LimitSpace = {
+ x: ~~(MapConfig.visualWidth / 2),
+ y: ~~(MapConfig.visualHeight / 2)
}
\ No newline at end of file
diff --git a/packages/client/src/mock/data.ts b/packages/client/src/mock/data.ts
index 2ec559a2..8302e53c 100644
--- a/packages/client/src/mock/data.ts
+++ b/packages/client/src/mock/data.ts
@@ -36,7 +36,19 @@ export const PlayersMockData: IPlayer[] = [
username: 'other',
x: 18,
y: 10,
- }
+ },
+ {
+ id: 6,
+ username: 'other2',
+ x: 18,
+ y: 13,
+ },
+ {
+ id: 8,
+ username: 'other3',
+ x: 18,
+ y: 13,
+ },
];
export const CurIdMockData = 3;
\ No newline at end of file
diff --git a/packages/client/src/pages/game/index.tsx b/packages/client/src/pages/game/index.tsx
index 61dee144..ff14ad4d 100644
--- a/packages/client/src/pages/game/index.tsx
+++ b/packages/client/src/pages/game/index.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from "react";
import { useComponentValue } from "@latticexyz/react";
-import { MapConfig } from "@/config";
+import { LimitSpace, MapConfig } from "@/config";
import { loadMapData } from "@/utils";
import Map from "@/components/Map";
import UserAvatar from "@/components/UserAvatar";
@@ -12,7 +12,6 @@ import { IPlayer } from "@/components/Player";
import { uploadUserMove } from "@/service/user";
import { useMUD } from "@/mud/MUDContext";
import { getComponentValue } from "@latticexyz/recs";
-import Fog from "@/components/Fog";
import Battle from "@/components/Battle";
const Game = () => {
@@ -43,35 +42,29 @@ const Game = () => {
roomId = "000000",
} = location.state ?? {};
- const onKeyDown = (e) => {
- const mapData = mapDataRef.current;
- if (mapData.length === 0 || e.keyCode < 37 || e.keyCode > 40) {
- return;
- }
- switch (e.keyCode) {
- case 37:
- vertexCoordinate.x = Math.max(0, vertexCoordinate.x - 1);
- break;
- case 38:
- vertexCoordinate.y = Math.max(0, vertexCoordinate.y - 1);
- break;
- case 39:
- vertexCoordinate.x = Math.min(
- mapData[0].length - 1 - MapConfig.visualWidth,
- vertexCoordinate.x + 1
- );
- break;
- case 40:
- vertexCoordinate.y = Math.min(
- mapData.length - 1 - MapConfig.visualHeight,
- vertexCoordinate.y + 1
- );
- break;
- }
- setVertexCoordinate({
- ...vertexCoordinate,
- });
- };
+ // const onKeyDown = (e) => {
+ // const mapData = mapDataRef.current;
+ // if (mapData.length === 0 || e.keyCode < 37 || e.keyCode > 40) {
+ // return;
+ // }
+ // switch (e.keyCode) {
+ // case 37:
+ // vertexCoordinate.x = Math.max(0, vertexCoordinate.x - 1);
+ // break;
+ // case 38:
+ // vertexCoordinate.y = Math.max(0, vertexCoordinate.y - 1);
+ // break;
+ // case 39:
+ // vertexCoordinate.x = Math.min(mapData[0].length - 1 - MapConfig.visualWidth, vertexCoordinate.x + 1);
+ // break;
+ // case 40:
+ // vertexCoordinate.y = Math.min(mapData.length - 1 - MapConfig.visualHeight, vertexCoordinate.y + 1);
+ // break;
+ // }
+ // setVertexCoordinate({
+ // ...vertexCoordinate
+ // });
+ // };
const movePlayer = (paths, merkelData) => {
let pathIndex = 0;
@@ -79,6 +72,7 @@ const Game = () => {
(item) => item.id === curPlayer!.id
);
const interval = setInterval(() => {
+ triggerVertexUpdate(paths[pathIndex], players[curPlayerIndex]);
Object.assign(players[curPlayerIndex], paths[pathIndex]);
pathIndex++;
setPlayers([...players]);
@@ -89,6 +83,43 @@ const Game = () => {
// move(merkelData);
};
+ const triggerVertexUpdate = (cur, before) => {
+ const xDegree = cur.x - before.x;
+ const yDegree = cur.y - before.y;
+ const mapData = mapDataRef.current;
+ if (xDegree === 1) {
+ const limitExceeded = cur.x - vertexCoordinate.x > LimitSpace.x;
+ const lessBoundary =
+ vertexCoordinate.x + MapConfig.visualWidth < mapData[0].length - 1;
+ if (limitExceeded && lessBoundary) {
+ vertexCoordinate.x++;
+ }
+ } else if (xDegree === -1) {
+ const limitExceeded = cur.x - vertexCoordinate.x < LimitSpace.x;
+ const lessBoundary = vertexCoordinate.x > 0;
+ if (limitExceeded && lessBoundary) {
+ vertexCoordinate.x--;
+ }
+ } else if (yDegree === 1) {
+ const limitExceeded = cur.y - vertexCoordinate.y > LimitSpace.y;
+ const lessBoundary =
+ vertexCoordinate.y + MapConfig.visualHeight < mapData.length - 1;
+ if (limitExceeded && lessBoundary) {
+ vertexCoordinate.y++;
+ }
+ } else if (yDegree === -1) {
+ const limitExceeded = cur.y - vertexCoordinate.y < LimitSpace.y;
+ const lessBoundary = vertexCoordinate.y > 0;
+ if (limitExceeded && lessBoundary) {
+ vertexCoordinate.y--;
+ }
+ }
+
+ setVertexCoordinate({
+ ...vertexCoordinate,
+ });
+ };
+
useEffect(() => {
loadMapData().then((csv) => {
setRenderMapData(csv);
@@ -101,7 +132,7 @@ const Game = () => {
}, []);
return (
-
+
{
-
+ {/*
*/}