From 46591eae5eb6a4aa6be64505c944f7ccda0aa307 Mon Sep 17 00:00:00 2001 From: vivomo <929992114@qq.com> Date: Wed, 18 Oct 2023 19:45:54 +0800 Subject: [PATCH 1/7] feat: map follow user's move --- packages/client/src/config/index.ts | 5 ++ packages/client/src/pages/game/index.tsx | 87 +++++++++++++++------- packages/client/src/pages/game/styles.scss | 1 + packages/client/src/pages/home/index.tsx | 2 +- 4 files changed, 69 insertions(+), 26 deletions(-) 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/pages/game/index.tsx b/packages/client/src/pages/game/index.tsx index 39c5fd39..eedfd0d8 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'; @@ -38,34 +38,35 @@ const Game = () => { const location = useLocation(); const { username = '', avatar = 'snake', 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; const curPlayerIndex = players.findIndex(item => item.id === curPlayer!.id); const interval = setInterval(() => { + triggerVertexUpdate(paths[pathIndex], players[curPlayerIndex]); Object.assign(players[curPlayerIndex], paths[pathIndex]); pathIndex++; setPlayers([...players]); @@ -76,6 +77,41 @@ 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); @@ -87,6 +123,7 @@ const Game = () => { // getPosition('0x35be872A3C94Bf581A9DA4c653CE734380b75B7D'); }, []); + return (
@@ -105,7 +142,7 @@ const Game = () => { data={RankMockData} curId={CurIdMockData} /> - + {/**/} { const [hasInit, setHasInit] = useState(false); const [walletAddress, setWalletAddress] = useState(''); - const [step, setStep] = useState('mint'); + const [step, setStep] = useState('play'); const { Modal, open, close, setContent } = useModal({ title: '', }); From 7a0db44b2868dd1a3d8a9130eec16a498b1d920c Mon Sep 17 00:00:00 2001 From: vivomo <929992114@qq.com> Date: Wed, 18 Oct 2023 19:46:26 +0800 Subject: [PATCH 2/7] feat: map follow user's move --- packages/client/src/pages/game/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/game/index.tsx b/packages/client/src/pages/game/index.tsx index eedfd0d8..6f6397f6 100644 --- a/packages/client/src/pages/game/index.tsx +++ b/packages/client/src/pages/game/index.tsx @@ -125,7 +125,7 @@ const Game = () => { return ( -
+
Date: Wed, 18 Oct 2023 20:00:52 +0800 Subject: [PATCH 3/7] feat: fog follow user's move --- packages/client/src/components/Fog/styles.scss | 10 +++++----- packages/client/src/components/Map/index.tsx | 8 ++++++-- packages/client/src/components/MapCell/index.tsx | 9 +++++---- packages/client/src/components/Player/index.tsx | 5 +++++ packages/client/src/pages/game/styles.scss | 1 + 5 files changed, 22 insertions(+), 11 deletions(-) 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..2818b5b2 100644 --- a/packages/client/src/components/Map/index.tsx +++ b/packages/client/src/components/Map/index.tsx @@ -35,7 +35,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]); @@ -73,7 +77,7 @@ const Map = (props: IProps) => { }} mapData={data} cellClassCache={cellClassCache.current} - player={playerData[`${x}-${y}`]} + players={playerData[`${x}-${y}`]} onMoveTo={onMoveTo} /> ) diff --git a/packages/client/src/components/MapCell/index.tsx b/packages/client/src/components/MapCell/index.tsx index 16409276..dc02937c 100644 --- a/packages/client/src/components/MapCell/index.tsx +++ b/packages/client/src/components/MapCell/index.tsx @@ -27,12 +27,12 @@ interface IProps { coordinate: ICoordinate, mapData: number[][]; cellClassCache: ICellClassCache; - player?: IPlayer; + players?: IPlayer[]; onMoveTo: (ICoordinate) => void; } const MapCell = (props: IProps) => { - const { coordinate: { x, y}, mapData, cellClassCache, player, onMoveTo } = props; + const { coordinate: { x, y}, mapData, cellClassCache, players, onMoveTo } = props; if (!cellClassCache[`${y}-${x}`]) { cellClassCache[`${y}-${x}`] = getCellClass(mapData, { x, y}); } @@ -42,7 +42,7 @@ const MapCell = (props: IProps) => { const onContextMenu = (e) => { e.preventDefault(); const curMapDataType = mapData[y][x]; - if (isMovable(curMapDataType) && !player) { + if (isMovable(curMapDataType)) { onMoveTo({ x, y}); } @@ -67,8 +67,9 @@ const MapCell = (props: IProps) => { }) }
+ { - player && + players && players.map((player) => ) }
); 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/pages/game/styles.scss b/packages/client/src/pages/game/styles.scss index 6b31ff16..4b11f2d0 100644 --- a/packages/client/src/pages/game/styles.scss +++ b/packages/client/src/pages/game/styles.scss @@ -4,6 +4,7 @@ height: 100vh; align-items: center; justify-content: center; + overflow: hidden; //background: url("../../assets/wall/wall_5.png"); .mi-game-user-avatar { From cd7d636d93f7846dc154031dabe57e65d68570aa Mon Sep 17 00:00:00 2001 From: vivomo <929992114@qq.com> Date: Wed, 18 Oct 2023 20:05:19 +0800 Subject: [PATCH 4/7] feat: update map style --- packages/client/src/components/Map/styles.scss | 1 - packages/client/src/pages/game/styles.scss | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) 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/pages/game/styles.scss b/packages/client/src/pages/game/styles.scss index 4b11f2d0..aaea1079 100644 --- a/packages/client/src/pages/game/styles.scss +++ b/packages/client/src/pages/game/styles.scss @@ -5,7 +5,7 @@ align-items: center; justify-content: center; overflow: hidden; - //background: url("../../assets/wall/wall_5.png"); + background: url("../../assets/wall/wall_5.png"); .mi-game-user-avatar { position: absolute; From 44c4e328e5aae7ff5075cb5aa624572c0f215522 Mon Sep 17 00:00:00 2001 From: vivomo <929992114@qq.com> Date: Wed, 18 Oct 2023 21:06:09 +0800 Subject: [PATCH 5/7] feat: use menu --- packages/client/src/components/Map/index.tsx | 6 +- .../client/src/components/MapCell/index.tsx | 83 ++++++++++++++++++- .../client/src/components/MapCell/styles.scss | 39 +++++++++ packages/client/src/mock/data.ts | 14 +++- packages/client/src/pages/game/index.tsx | 1 - 5 files changed, 137 insertions(+), 6 deletions(-) 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([]); From 3c5662fb332bced83316e74f898e231970c6dc48 Mon Sep 17 00:00:00 2001 From: lewis <71866430+xingxinglian@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:14:13 +0800 Subject: [PATCH 6/7] chore: temp remove speed --- packages/contracts/src/systems/MoveSystem.sol | 2 +- packages/contracts/worlds.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts/src/systems/MoveSystem.sol b/packages/contracts/src/systems/MoveSystem.sol index 66d21942..8248637e 100644 --- a/packages/contracts/src/systems/MoveSystem.sol +++ b/packages/contracts/src/systems/MoveSystem.sol @@ -31,7 +31,7 @@ contract MoveSystem is System { moveList.length > 0 && moveList.length <= BattleConfig.getMaxMoveDistance(BATTLE_CONFIG_KEY), "invalid move distance" ); - require(moveList.length <= Player.getSpeed(_msgSender()), "exceed player speed"); + // require(moveList.length <= Player.getSpeed(_msgSender()), "exceed player speed"); // check player lock require(PlayerLocationLock.get(_msgSender()) == 0, "You are locked"); // check continuity diff --git a/packages/contracts/worlds.json b/packages/contracts/worlds.json index 98e6e3d2..e9146703 100644 --- a/packages/contracts/worlds.json +++ b/packages/contracts/worlds.json @@ -1,7 +1,7 @@ { "4242": { - "address": "0x480f891A7b1AA7018Bb0cCb5Af558d82FA4A5501", - "blockNumber": 27830588 + "address": "0x2b50622F55780b14C08a288E41A08b2e2368bA4f", + "blockNumber": 27941048 }, "31337": { "address": "0x74Df809b1dfC099E8cdBc98f6a8D1F5c2C3f66f8" From 022356570ed485d87a76cf10db494fa0b1a5286b Mon Sep 17 00:00:00 2001 From: lewis <71866430+xingxinglian@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:18:03 +0800 Subject: [PATCH 7/7] chore: remove space limit --- packages/contracts/src/systems/BattlePrepareSystem.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/systems/BattlePrepareSystem.sol b/packages/contracts/src/systems/BattlePrepareSystem.sol index 538dfc33..63ec628f 100644 --- a/packages/contracts/src/systems/BattlePrepareSystem.sol +++ b/packages/contracts/src/systems/BattlePrepareSystem.sol @@ -41,7 +41,7 @@ contract BattlePrepareSystem is System { moveList.length > 0 && moveList.length <= BattleConfig.getMaxAttackzDistance(BATTLE_CONFIG_KEY), "invalid attack distance" ); - require(moveList.length <= Player.getSpace(_msgSender()), "exceed player space"); + // require(moveList.length <= Player.getSpace(_msgSender()), "exceed player space"); //Todo: temp remove require( Player.getState(_msgSender()) == PlayerState.Exploring &&