Fixed collision detection and camera tracking.

This commit is contained in:
genxium 2022-09-26 11:16:18 +08:00
parent 2dfd6083c5
commit 80dc05a92b
5 changed files with 234 additions and 67 deletions

View File

@ -440,7 +440,7 @@
"array": [ "array": [
0, 0,
0, 0,
209.73151519075364, 216.05530045313827,
0, 0,
0, 0,
0, 0,

View File

@ -22,7 +22,7 @@ cc.Class({
if (!self.mapScriptIns) return; if (!self.mapScriptIns) return;
if (!self.mapScriptIns.selfPlayerInfo) return; if (!self.mapScriptIns.selfPlayerInfo) return;
if (!self.mapScriptIns.playerRichInfoDict) return; if (!self.mapScriptIns.playerRichInfoDict) return;
const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict[self.mapScriptIns.selfPlayerInfo.id]; const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict.get(self.mapScriptIns.selfPlayerInfo.id);
if (!selfPlayerRichInfo) return; if (!selfPlayerRichInfo) return;
const selfPlayerNode = selfPlayerRichInfo.node; const selfPlayerNode = selfPlayerRichInfo.node;
if (!selfPlayerNode) return; if (!selfPlayerNode) return;

View File

@ -126,7 +126,7 @@ cc.Class({
}, },
maxChasingRenderFramesPerUpdate: { maxChasingRenderFramesPerUpdate: {
type: cc.Integer, type: cc.Integer,
default: 5 default: 10
}, },
}, },
@ -565,6 +565,8 @@ cc.Class({
self.onBattleStarted(rdf); self.onBattleStarted(rdf);
return; return;
case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_READDED_AND_ACKED: case window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.PLAYER_READDED_AND_ACKED:
// [WARNING] The "frameId" from server could be quite fast-forwarding, don't assign it in other cases.
self.renderFrameId = frameId;
self.lastAllConfirmedRenderFrameId = frameId; self.lastAllConfirmedRenderFrameId = frameId;
self.onBattleReadyToStart(rdf.playerMetas, true); self.onBattleReadyToStart(rdf.playerMetas, true);
self.onBattleStarted(rdf); self.onBattleStarted(rdf);
@ -763,8 +765,8 @@ cc.Class({
newPlayerNode.getComponent("SelfPlayer").mapNode = self.node; newPlayerNode.getComponent("SelfPlayer").mapNode = self.node;
const currentSelfColliderCircle = newPlayerNode.getComponent(cc.CircleCollider); const currentSelfColliderCircle = newPlayerNode.getComponent(cc.CircleCollider);
const newPlayerColliderLatest = self.latestCollisionSys.createCircle(x, y, currentSelfColliderCircle); const newPlayerColliderLatest = self.latestCollisionSys.createCircle(x, y, currentSelfColliderCircle.radius);
const newPlayerColliderChaser = self.chaserCollisionSys.createCircle(x, y, currentSelfColliderCircle); const newPlayerColliderChaser = self.chaserCollisionSys.createCircle(x, y, currentSelfColliderCircle.radius);
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
self.latestCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderLatest); self.latestCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderLatest);
self.chaserCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderChaser); self.chaserCollisionSysMap.set(collisionPlayerIndex, newPlayerColliderChaser);
@ -819,11 +821,6 @@ cc.Class({
} catch (err) { } catch (err) {
console.error("Error during Map.update", err); console.error("Error during Map.update", err);
} finally { } finally {
// Update camera to track selfPlayer.
if (null != self.ctrl) {
self.ctrl.justifyMapNodePosAndScale(self.ctrl.linearSpeedBase, self.ctrl.zoomingSpeedBase);
}
// Update countdown // Update countdown
if (null != self.countdownNanos) { if (null != self.countdownNanos) {
self.countdownNanos -= self.rollbackEstimatedDt*1000000000; self.countdownNanos -= self.rollbackEstimatedDt*1000000000;
@ -1050,7 +1047,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*self.rollbackEstimatedDt; const baseChange = player.speed*self.rollbackEstimatedDt*decodedInput.speedFactor;
playerCollider.x += baseChange*decodedInput.dx; playerCollider.x += baseChange*decodedInput.dx;
playerCollider.y += baseChange*decodedInput.dy; playerCollider.y += baseChange*decodedInput.dy;
/* /*
@ -1063,8 +1060,9 @@ cc.Class({
collisionSys.update(); collisionSys.update();
const result = collisionSys.createResult(); // Can I reuse a "self.latestCollisionSysResult" object throughout the whole battle? const result = collisionSys.createResult(); // Can I reuse a "self.latestCollisionSysResult" object throughout the whole battle?
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => { // [WARNING] Traverse in the order of joinIndices to guarantee determinism.
const joinIndex = playerRichInfo.joinIndex; for (let i in self.playerRichInfoArr) {
const joinIndex = parseInt(i) + 1;
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
const playerCollider = collisionSysMap.get(collisionPlayerIndex); const playerCollider = collisionSysMap.get(collisionPlayerIndex);
const potentials = playerCollider.potentials(); const potentials = playerCollider.potentials();
@ -1075,7 +1073,7 @@ cc.Class({
playerCollider.x -= result.overlap * result.overlap_x; playerCollider.x -= result.overlap * result.overlap_x;
playerCollider.y -= result.overlap * result.overlap_y; playerCollider.y -= result.overlap * result.overlap_y;
} }
}); }
} }
return self._createRoomDownsyncFrameLocally(renderFrameIdEd, collisionSys, collisionSysMap); return self._createRoomDownsyncFrameLocally(renderFrameIdEd, collisionSys, collisionSysMap);
@ -1101,6 +1099,10 @@ cc.Class({
nodeAndScriptIns[1].showArrowTipNode(); nodeAndScriptIns[1].showArrowTipNode();
} }
} }
self.playerRichInfoArr = new Array(self.playerRichInfoDict.size);
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
self.playerRichInfoArr[playerRichInfo.joinIndex-1] = playerRichInfo;
});
}, },
_stringifyRecentInputCache(usefullOutput) { _stringifyRecentInputCache(usefullOutput) {

View File

@ -1,19 +1,24 @@
window.DIRECTION_DECODER = [ window.DIRECTION_DECODER = [
[0, 0], [0, 0, null],
[0, +1], [0, +1, null],
[0, -1], [0, -1, null],
[+2, 0], [+2, 0, null],
[-2, 0], [-2, 0, null],
[+2, +1], [+2, +1, null],
[-2, -1], [-2, -1, null],
[+2, -1], [+2, -1, null],
[-2, +1], [-2, +1, null],
[+2, 0], [+2, 0, null],
[-2, 0], [-2, 0, null],
[0, +1], [0, +1, null],
[0, -1], [0, -1, null],
]; ];
for (let k in window.DIRECTION_DECODER) {
const length = Math.sqrt(window.DIRECTION_DECODER[k][0]*window.DIRECTION_DECODER[k][0] + window.DIRECTION_DECODER[k][1]*window.DIRECTION_DECODER[k][1]);
window.DIRECTION_DECODER[k][2] = (0 == length ? 0 : (1.0/length));
}
cc.Class({ cc.Class({
extends: cc.Component, extends: cc.Component,
properties: { properties: {
@ -114,43 +119,6 @@ cc.Class({
this.initialized = true; this.initialized = true;
}, },
justifyMapNodePosAndScale(linearSpeedBase, zoomingSpeedBase) {
const self = this;
if (false == self.mapScriptIns._inputControlEnabled) return;
if (null != self._cachedMapNodePosTarget) {
while (self.maxMovingBufferLength < self._cachedMapNodePosTarget.length) {
self._cachedMapNodePosTarget.shift();
}
if (0 < self._cachedMapNodePosTarget.length && 0 == self.mapNode.getNumberOfRunningActions()) {
const nextMapNodePosTarget = self._cachedMapNodePosTarget.shift();
const linearSpeed = linearSpeedBase;
const finalDiffVec = nextMapNodePosTarget.pos.sub(self.mapNode.position);
const finalDiffVecMag = finalDiffVec.mag();
if (self.linearMovingEps > finalDiffVecMag) {
// Jittering.
// cc.log("Map node moving by finalDiffVecMag == %s is just jittering.", finalDiffVecMag);
return;
}
const durationSeconds = finalDiffVecMag / linearSpeed;
cc.log("Map node moving to %o in %s/%s == %s seconds.", nextMapNodePosTarget.pos, finalDiffVecMag, linearSpeed, durationSeconds);
const bufferedTargetPos = cc.v2(nextMapNodePosTarget.pos.x, nextMapNodePosTarget.pos.y);
self.mapNode.runAction(cc.sequence(
cc.moveTo(durationSeconds, bufferedTargetPos),
cc.callFunc(() => {
if (self._isMapOverMoved(self.mapNode.position)) {
self.mapNode.setPosition(bufferedTargetPos);
}
}, self)
));
}
}
if (null != self._cachedZoomRawTarget && false == self._cachedZoomRawTarget.processed) {
cc.log(`Processing self._cachedZoomRawTarget == ${self._cachedZoomRawTarget}`);
self._cachedZoomRawTarget.processed = true;
self.mapNode.setScale(self._cachedZoomRawTarget.scale);
}
},
_initTouchEvent() { _initTouchEvent() {
const self = this; const self = this;
const translationListenerNode = (self.translationListenerNode ? self.translationListenerNode : self.mapNode); const translationListenerNode = (self.translationListenerNode ? self.translationListenerNode : self.mapNode);
@ -377,7 +345,8 @@ cc.Class({
} }
return { return {
dx: mapped[0], dx: mapped[0],
dy: mapped[1] dy: mapped[1],
speedFactor: mapped[2],
} }
}, },

File diff suppressed because one or more lines are too long