diff --git a/packages/client/src/components/Map/index.tsx b/packages/client/src/components/Map/index.tsx index 2818b5b2..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]); @@ -75,6 +77,8 @@ const Map = (props: IProps) => { x, y }} + prevActionCoordinate={prevActionCoordinate} + onExeAction={setPrevActionCoordinate} mapData={data} cellClassCache={cellClassCache.current} players={playerData[`${x}-${y}`]} diff --git a/packages/client/src/components/MapCell/index.tsx b/packages/client/src/components/MapCell/index.tsx index dc02937c..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'; @@ -29,10 +29,16 @@ interface IProps { cellClassCache: ICellClassCache; players?: IPlayer[]; onMoveTo: (ICoordinate) => void; + prevActionCoordinate: ICoordinate; + onExeAction: (ICoordinate) => void; } const MapCell = (props: IProps) => { - const { coordinate: { x, y}, mapData, cellClassCache, players, 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)) { 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) => { @@ -71,6 +110,44 @@ const MapCell = (props: IProps) => { { players && players.map((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/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 6f6397f6..2b2b94ad 100644 --- a/packages/client/src/pages/game/index.tsx +++ b/packages/client/src/pages/game/index.tsx @@ -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'; const Game = () => { const [renderMapData, setRenderMapData] = useState([]);