Fixes to frontend coordinate conversion.

This commit is contained in:
genxium 2022-11-09 23:46:11 +08:00
parent aa795fcee5
commit 885443c2b1
5 changed files with 45 additions and 58 deletions

View File

@ -1251,9 +1251,11 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
} }
} }
pbPlayers := toPbPlayers(pR.Players)
newRenderFrame := RoomDownsyncFrame{ newRenderFrame := RoomDownsyncFrame{
Id: collisionSysRenderFrameId + 1, Id: collisionSysRenderFrameId + 1,
Players: toPbPlayers(pR.Players), Players: pbPlayers,
CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*pR.RollbackEstimatedDtNanos), CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*pR.RollbackEstimatedDtNanos),
} }
pR.RenderFrameBuffer.Put(&newRenderFrame) pR.RenderFrameBuffer.Put(&newRenderFrame)
@ -1292,10 +1294,10 @@ func (pR *Room) printBarrier(barrierCollider *resolv.Object) {
Logger.Info(fmt.Sprintf("Barrier in roomId=%v: w=%v, h=%v, shape=%v", pR.Id, barrierCollider.W, barrierCollider.H, barrierCollider.Shape)) Logger.Info(fmt.Sprintf("Barrier in roomId=%v: w=%v, h=%v, shape=%v", pR.Id, barrierCollider.W, barrierCollider.H, barrierCollider.Shape))
} }
func (pR *Room) worldToVirtualGridPos(x, y float64) (int32, int32) { func (pR *Room) worldToVirtualGridPos(wx, wy float64) (int32, int32) {
// In JavaScript floating numbers suffer from seemingly non-deterministic arithmetics, and even if certain libs solved this issue by approaches such as fixed-point-number, they might not be used in other libs -- e.g. the "collision libs" we're interested in -- thus couldn't kill all pains. // In JavaScript floating numbers suffer from seemingly non-deterministic arithmetics, and even if certain libs solved this issue by approaches such as fixed-point-number, they might not be used in other libs -- e.g. the "collision libs" we're interested in -- thus couldn't kill all pains.
var virtualGridX int32 = int32(x * pR.WorldToVirtualGridRatio) var virtualGridX int32 = int32(wx * pR.WorldToVirtualGridRatio)
var virtualGridY int32 = int32(y * pR.WorldToVirtualGridRatio) var virtualGridY int32 = int32(wy * pR.WorldToVirtualGridRatio)
return virtualGridX, virtualGridY return virtualGridX, virtualGridY
} }

View File

@ -440,7 +440,7 @@
"array": [ "array": [
0, 0,
0, 0,
377.5870760500153, 216.67592045656244,
0, 0,
0, 0,
0, 0,

View File

@ -1,6 +1,8 @@
const i18n = require('LanguageData'); const i18n = require('LanguageData');
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
window.pb = require("./modules/room_downsync_frame_proto_bundle.forcemsg");
cc.Class({ cc.Class({
extends: cc.Component, extends: cc.Component,
@ -96,30 +98,6 @@ cc.Class({
if (null != qDict && qDict["expectedRoomId"]) { if (null != qDict && qDict["expectedRoomId"]) {
window.clearBoundRoomIdInBothVolatileAndPersistentStorage(); window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
} }
cc.loader.loadRes("pbfiles/room_downsync_frame", function(err, textAsset /* cc.TextAsset */ ) {
if (err) {
cc.error(err.message || err);
return;
}
// Otherwise, `window.RoomDownsyncFrame` is already assigned.
let protoRoot = new protobuf.Root;
window.protobuf.parse(textAsset.text, protoRoot);
window.RoomDownsyncFrame = protoRoot.lookupType("treasurehunterx.RoomDownsyncFrame");
window.BattleColliderInfo = protoRoot.lookupType("treasurehunterx.BattleColliderInfo");
window.WsReq = protoRoot.lookupType("treasurehunterx.WsReq");
window.WsResp = protoRoot.lookupType("treasurehunterx.WsResp");
self.checkIntAuthTokenExpire().then(
(intAuthToken) => {
console.log("Successfully found `intAuthToken` in local cache");
self.useTokenLogin(intAuthToken);
},
() => {
console.warn("Failed to find `intAuthToken` in local cache");
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
}
);
});
}, },
getRetCodeList() { getRetCodeList() {

View File

@ -223,7 +223,7 @@ cc.Class({
inputFrameUpsyncBatch.push(inputFrameUpsync); inputFrameUpsyncBatch.push(inputFrameUpsync);
} }
} }
const reqData = window.WsReq.encode({ const reqData = window.pb.protos.WsReq.encode({
msgId: Date.now(), msgId: Date.now(),
playerId: self.selfPlayerInfo.id, playerId: self.selfPlayerInfo.id,
act: window.UPSYNC_MSG_ACT_PLAYER_CMD, act: window.UPSYNC_MSG_ACT_PLAYER_CMD,
@ -502,7 +502,7 @@ cc.Class({
self.backgroundMapTiledIns.node.setContentSize(newBackgroundMapSize.width * newBackgroundMapTileSize.width, newBackgroundMapSize.height * newBackgroundMapTileSize.height); self.backgroundMapTiledIns.node.setContentSize(newBackgroundMapSize.width * newBackgroundMapTileSize.width, newBackgroundMapSize.height * newBackgroundMapTileSize.height);
self.backgroundMapTiledIns.node.setPosition(cc.v2(0, 0)); self.backgroundMapTiledIns.node.setPosition(cc.v2(0, 0));
const reqData = window.WsReq.encode({ const reqData = window.pb.protos.WsReq.encode({
msgId: Date.now(), msgId: Date.now(),
act: window.UPSYNC_MSG_ACT_PLAYER_COLLIDER_ACK, act: window.UPSYNC_MSG_ACT_PLAYER_COLLIDER_ACK,
}).finish(); }).finish();
@ -598,12 +598,6 @@ cc.Class({
console.log('On battle resynced! renderFrameId=', rdf.id); console.log('On battle resynced! renderFrameId=', rdf.id);
} }
self.renderFrameId = rdf.id;
self.lastRenderFrameIdTriggeredAt = performance.now();
// In this case it must be true that "rdf.id > chaserRenderFrameId >= lastAllConfirmedRenderFrameId".
self.lastAllConfirmedRenderFrameId = rdf.id;
self.chaserRenderFrameId = rdf.id;
const players = rdf.players; const players = rdf.players;
const playerMetas = rdf.playerMetas; const playerMetas = rdf.playerMetas;
self._initPlayerRichInfoDict(players, playerMetas); self._initPlayerRichInfoDict(players, playerMetas);
@ -615,6 +609,12 @@ cc.Class({
playersInfoScriptIns.updateData(playerMeta); playersInfoScriptIns.updateData(playerMeta);
} }
self.renderFrameId = rdf.id;
self.lastRenderFrameIdTriggeredAt = performance.now();
// In this case it must be true that "rdf.id > chaserRenderFrameId >= lastAllConfirmedRenderFrameId".
self.lastAllConfirmedRenderFrameId = rdf.id;
self.chaserRenderFrameId = rdf.id;
if (null != rdf.countdownNanos) { if (null != rdf.countdownNanos) {
self.countdownNanos = rdf.countdownNanos; self.countdownNanos = rdf.countdownNanos;
} }
@ -741,17 +741,16 @@ cc.Class({
self.playersInfoNode.getComponent("PlayersInfo").clearInfo(); self.playersInfoNode.getComponent("PlayersInfo").clearInfo();
}, },
spawnPlayerNode(joinIndex, x, y) { spawnPlayerNode(joinIndex, vx, vy, playerRichInfo) {
const self = this; const self = this;
const newPlayerNode = 1 == joinIndex ? cc.instantiate(self.player1Prefab) : cc.instantiate(self.player2Prefab); // hardcoded for now, car color determined solely by joinIndex const newPlayerNode = 1 == joinIndex ? cc.instantiate(self.player1Prefab) : cc.instantiate(self.player2Prefab); // hardcoded for now, car color determined solely by joinIndex
newPlayerNode.setPosition(cc.v2(x, y)); const wpos = self.virtualGridToWorldPos(vx, vy);
newPlayerNode.setPosition(cc.v2(wpos[0], wpos[1]));
newPlayerNode.getComponent("SelfPlayer").mapNode = self.node; newPlayerNode.getComponent("SelfPlayer").mapNode = self.node;
const currentSelfColliderCircle = newPlayerNode.getComponent(cc.CircleCollider); const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerRichInfo);
const r = currentSelfColliderCircle.radius, const d = playerRichInfo.colliderRadius*2, x0 = cpos[0],
d = 2 * r; y0 = cpos[1];
// The collision box of an individual player is a polygon instead of a circle, because the backend collision engine doesn't handle circle alignment well.
const x0 = x - r,
y0 = y - r;
let pts = [[0, 0], [d, 0], [d, d], [0, d]]; let pts = [[0, 0], [d, 0], [d, d], [0, d]];
const newPlayerColliderLatest = self.latestCollisionSys.createPolygon(x0, y0, pts); const newPlayerColliderLatest = self.latestCollisionSys.createPolygon(x0, y0, pts);
@ -919,9 +918,19 @@ cc.Class({
self.findingPlayerNode.parent.removeChild(self.findingPlayerNode); self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
}, },
onBattleReadyToStart(playerMetas) { onBattleReadyToStart(rdf) {
console.log("Calling `onBattleReadyToStart` with:", playerMetas);
const self = this; const self = this;
const players = rdf.players;
const playerMetas = rdf.playerMetas;
self._initPlayerRichInfoDict(players, playerMetas);
// Show the top status indicators for IN_BATTLE
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
for (let i in playerMetas) {
const playerMeta = playerMetas[i];
playersInfoScriptIns.updateData(playerMeta);
}
console.log("Calling `onBattleReadyToStart` with:", playerMetas);
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer"); const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
findingPlayerScriptIns.hideExitButton(); findingPlayerScriptIns.hideExitButton();
findingPlayerScriptIns.updatePlayersInfo(playerMetas); findingPlayerScriptIns.updatePlayersInfo(playerMetas);
@ -965,9 +974,7 @@ cc.Class({
const joinIndex = playerRichInfo.joinIndex; const joinIndex = playerRichInfo.joinIndex;
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
const playerCollider = collisionSysMap.get(collisionPlayerIndex); const playerCollider = collisionSysMap.get(collisionPlayerIndex);
const currentSelfColliderCircle = playerRichInfo.node.getComponent(cc.CircleCollider);
const vpos = self.playerColliderAnchorToVirtualGridPos(playerCollider.x, playerCollider.y, playerRichInfo); const vpos = self.playerColliderAnchorToVirtualGridPos(playerCollider.x, playerCollider.y, playerRichInfo);
const r = currentSelfColliderCircle.radius;
rdf.players[playerRichInfo.id] = { rdf.players[playerRichInfo.id] = {
id: playerRichInfo.id, id: playerRichInfo.id,
virtualGridX: vpos[0], virtualGridX: vpos[0],
@ -1044,7 +1051,7 @@ cc.Class({
const playerCollider = collisionSysMap.get(collisionPlayerIndex); const playerCollider = collisionSysMap.get(collisionPlayerIndex);
const player = latestRdf.players[playerId]; const player = latestRdf.players[playerId];
const cpos = self.worldToVirtualGridPos(player.virtualGridX, player.virtualGridY); const cpos = self.virtualGridToPlayerColliderPos(player.virtualGridX, player.virtualGridY, playerRichInfo);
playerCollider.x = cpos[0]; playerCollider.x = cpos[0];
playerCollider.y = cpos[1]; playerCollider.y = cpos[1];
}); });
@ -1069,7 +1076,7 @@ cc.Class({
const player = renderFrame.players[playerId]; const player = renderFrame.players[playerId];
const encodedInput = inputList[joinIndex - 1]; const encodedInput = inputList[joinIndex - 1];
const decodedInput = self.ctrl.decodeDirection(encodedInput); const decodedInput = self.ctrl.decodeDirection(encodedInput);
const baseChange = player.speed * decodedInput.speedFactor; const baseChange = player.speed * self.virtualGridToWorldRatio * decodedInput.speedFactor;
playerCollider.x += baseChange * decodedInput.dx; playerCollider.x += baseChange * decodedInput.dx;
playerCollider.y += baseChange * decodedInput.dy; playerCollider.y += baseChange * decodedInput.dy;
} }
@ -1104,16 +1111,16 @@ cc.Class({
if (self.playerRichInfoDict.has(playerId)) continue; // Skip already put keys if (self.playerRichInfoDict.has(playerId)) continue; // Skip already put keys
const immediatePlayerInfo = players[playerId]; const immediatePlayerInfo = players[playerId];
const immediatePlayerMeta = playerMetas[playerId]; const immediatePlayerMeta = playerMetas[playerId];
const nodeAndScriptIns = self.spawnPlayerNode(immediatePlayerInfo.joinIndex, immediatePlayerInfo.x, immediatePlayerInfo.y);
self.playerRichInfoDict.set(playerId, immediatePlayerInfo); self.playerRichInfoDict.set(playerId, immediatePlayerInfo);
Object.assign(self.playerRichInfoDict.get(playerId), immediatePlayerMeta);
const nodeAndScriptIns = self.spawnPlayerNode(immediatePlayerInfo.joinIndex, immediatePlayerInfo.virtualGridX, immediatePlayerInfo.virtualGridY, self.playerRichInfoDict.get(playerId));
Object.assign(self.playerRichInfoDict.get(playerId), { Object.assign(self.playerRichInfoDict.get(playerId), {
node: nodeAndScriptIns[0], node: nodeAndScriptIns[0],
scriptIns: nodeAndScriptIns[1] scriptIns: nodeAndScriptIns[1]
}); });
Object.assign(self.playerRichInfoDict.get(playerId), immediatePlayerMeta);
if (self.selfPlayerInfo.id == playerId) { if (self.selfPlayerInfo.id == playerId) {
self.selfPlayerInfo = Object.assign(self.selfPlayerInfo, immediatePlayerInfo); self.selfPlayerInfo = Object.assign(self.selfPlayerInfo, immediatePlayerInfo);
nodeAndScriptIns[1].showArrowTipNode(); nodeAndScriptIns[1].showArrowTipNode();
@ -1177,12 +1184,12 @@ cc.Class({
playerColliderAnchorToVirtualGridPos(cx, cy, playerRichInfo) { playerColliderAnchorToVirtualGridPos(cx, cy, playerRichInfo) {
const self = this; const self = this;
const wpos = self.playerColliderAnchorToWorldPos(cx, cy, playerRichInfo); const wpos = self.playerColliderAnchorToWorldPos(cx, cy, playerRichInfo);
return pR.worldToVirtualGridPos(wpos[0], wpos[1]) return self.worldToVirtualGridPos(wpos[0], wpos[1])
}, },
virtualGridToPlayerColliderPos(vx, vy, playerRichInfo) { virtualGridToPlayerColliderPos(vx, vy, playerRichInfo) {
const self = this; const self = this;
const wpos = self.virtualGridToWorldPos(vx, vy); const wpos = self.virtualGridToWorldPos(vx, vy);
return playerWorldToCollisionPos(wpos[0], wpos[1], playerRichInfo) return self.playerWorldToCollisionPos(wpos[0], wpos[1], playerRichInfo)
}, },
}); });

View File

@ -146,7 +146,7 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
return; return;
} }
try { try {
const resp = window.WsResp.decode(new Uint8Array(evt.data)); const resp = window.pb.protos.WsResp.decode(new Uint8Array(evt.data));
switch (resp.act) { switch (resp.act) {
case window.DOWNSYNC_MSG_ACT_HB_REQ: case window.DOWNSYNC_MSG_ACT_HB_REQ:
window.handleHbRequirements(resp); // 获取boundRoomId并存储到localStorage window.handleHbRequirements(resp); // 获取boundRoomId并存储到localStorage
@ -159,7 +159,7 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
mapIns.hideFindingPlayersGUI(); mapIns.hideFindingPlayersGUI();
break; break;
case window.DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START: case window.DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START:
mapIns.onBattleReadyToStart(resp.rdf.playerMetas); mapIns.onBattleReadyToStart(resp.rdf);
break; break;
case window.DOWNSYNC_MSG_ACT_BATTLE_START: case window.DOWNSYNC_MSG_ACT_BATTLE_START:
mapIns.onRoomDownsyncFrame(resp.rdf); mapIns.onRoomDownsyncFrame(resp.rdf);