mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 11:48:56 +00:00
Fixes for backend integration.
This commit is contained in:
parent
bc8eab8115
commit
0b0de0beb3
@ -1212,8 +1212,8 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
|
|||||||
}
|
}
|
||||||
currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame)
|
currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame)
|
||||||
delayedInputFrameId := pR.ConvertToInputFrameId(collisionSysRenderFrameId, pR.InputDelayFrames)
|
delayedInputFrameId := pR.ConvertToInputFrameId(collisionSysRenderFrameId, pR.InputDelayFrames)
|
||||||
var delayedInputList []uint64 = nil
|
var delayedInputList *[]uint64 = nil
|
||||||
var delayedInputListForPrevRenderFrame []uint64 = nil
|
var delayedInputListForPrevRenderFrame *[]uint64 = nil
|
||||||
if 0 <= delayedInputFrameId {
|
if 0 <= delayedInputFrameId {
|
||||||
if delayedInputFrameId > pR.LastAllConfirmedInputFrameId {
|
if delayedInputFrameId > pR.LastAllConfirmedInputFrameId {
|
||||||
panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
|
panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
|
||||||
@ -1223,19 +1223,19 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
|
|||||||
panic(fmt.Sprintf("delayedInputFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
|
panic(fmt.Sprintf("delayedInputFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
|
||||||
}
|
}
|
||||||
delayedInputFrame := tmp.(*pb.InputFrameDownsync)
|
delayedInputFrame := tmp.(*pb.InputFrameDownsync)
|
||||||
delayedInputList = delayedInputFrame.InputList
|
delayedInputList = &delayedInputFrame.InputList
|
||||||
delayedInputFrameIdForPrevRenderFrame := pR.ConvertToInputFrameId(collisionSysRenderFrameId-1, pR.InputDelayFrames)
|
delayedInputFrameIdForPrevRenderFrame := pR.ConvertToInputFrameId(collisionSysRenderFrameId-1, pR.InputDelayFrames)
|
||||||
if 0 <= delayedInputFrameIdForPrevRenderFrame {
|
if 0 <= delayedInputFrameIdForPrevRenderFrame {
|
||||||
tmp = pR.InputsBuffer.GetByFrameId(delayedInputFrameId)
|
tmp = pR.InputsBuffer.GetByFrameId(delayedInputFrameIdForPrevRenderFrame)
|
||||||
if nil == tmp {
|
if nil == tmp {
|
||||||
panic(fmt.Sprintf("delayedInputFrameIdForPrevRenderFrame=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId-1=%v! InputsBuffer=%v", delayedInputFrameIdForPrevRenderFrame, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId-1, pR.InputsBufferString(false)))
|
panic(fmt.Sprintf("delayedInputFrameIdForPrevRenderFrame=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId-1=%v! InputsBuffer=%v", delayedInputFrameIdForPrevRenderFrame, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId-1, pR.InputsBufferString(false)))
|
||||||
}
|
}
|
||||||
delayedInputFrameForPrevRenderFrame := tmp.(*pb.InputFrameDownsync)
|
delayedInputFrameForPrevRenderFrame := tmp.(*pb.InputFrameDownsync)
|
||||||
delayedInputListForPrevRenderFrame = delayedInputFrameForPrevRenderFrame.InputList
|
delayedInputListForPrevRenderFrame = &delayedInputFrameForPrevRenderFrame.InputList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.GravityX, pR.GravityY, pR.JumpingInitVelY, pR.InputDelayFrames, pR.InputScaleFrames, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformThreshold, pR.WorldToVirtualGridRatio, pR.VirtualGridToWorldRatio)
|
nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(*delayedInputList, *delayedInputListForPrevRenderFrame, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.GravityX, pR.GravityY, pR.JumpingInitVelY, pR.InputDelayFrames, pR.InputScaleFrames, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformThreshold, pR.WorldToVirtualGridRatio, pR.VirtualGridToWorldRatio)
|
||||||
pR.RenderFrameBuffer.Put(nextRenderFrame)
|
pR.RenderFrameBuffer.Put(nextRenderFrame)
|
||||||
pR.CurDynamicsRenderFrameId++
|
pR.CurDynamicsRenderFrameId++
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "1.2.5",
|
|
||||||
"uuid": "368b10b6-88fc-423c-9fcd-545d9fc673bd",
|
|
||||||
"asyncLoadAssets": false,
|
|
||||||
"autoReleaseAssets": false,
|
|
||||||
"subMetas": {}
|
|
||||||
}
|
|
@ -605,8 +605,8 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id);
|
const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id);
|
||||||
let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance);
|
let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance);
|
||||||
let shouldForceResync = pbRdf.ShouldForceResync;
|
let shouldForceResync = pbRdf.shouldForceResync;
|
||||||
const notSelfUnconfirmed = (0 == (rdf.BackendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1))));
|
const notSelfUnconfirmed = (0 == (pbRdf.backendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1))));
|
||||||
if (notSelfUnconfirmed) {
|
if (notSelfUnconfirmed) {
|
||||||
shouldForceDumping2 = false;
|
shouldForceDumping2 = false;
|
||||||
shouldForceResync = false;
|
shouldForceResync = false;
|
||||||
@ -647,7 +647,8 @@ cc.Class({
|
|||||||
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) {
|
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) {
|
||||||
console.log('On battle started! renderFrameId=', rdf.Id);
|
console.log('On battle started! renderFrameId=', rdf.Id);
|
||||||
} else {
|
} else {
|
||||||
console.log('On battle resynced! renderFrameId=', rdf.Id);
|
self.hideFindingPlayersGUI();
|
||||||
|
console.warn('On battle resynced! renderFrameId=', rdf.Id);
|
||||||
}
|
}
|
||||||
self.renderFrameId = rdf.Id;
|
self.renderFrameId = rdf.Id;
|
||||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
self.lastRenderFrameIdTriggeredAt = performance.now();
|
||||||
@ -1071,6 +1072,12 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`);
|
|||||||
currPlayerDownsync.framesToRecover = currPlayerDownsync.FrameToRecover;
|
currPlayerDownsync.framesToRecover = currPlayerDownsync.FrameToRecover;
|
||||||
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false);
|
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update countdown
|
||||||
|
self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos;
|
||||||
|
if (self.countdownNanos <= 0) {
|
||||||
|
self.onBattleStopped(self.playerRichInfoDict);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCachedInputFrameDownsyncWithPrediction(inputFrameId) {
|
getCachedInputFrameDownsyncWithPrediction(inputFrameId) {
|
||||||
|
@ -13,7 +13,7 @@ cc.Class({
|
|||||||
onLoad() {
|
onLoad() {
|
||||||
const self = this;
|
const self = this;
|
||||||
window.mapIns = self;
|
window.mapIns = self;
|
||||||
self.showCriticalCoordinateLabels = true;
|
self.showCriticalCoordinateLabels = false;
|
||||||
|
|
||||||
const mapNode = self.node;
|
const mapNode = self.node;
|
||||||
const canvasNode = mapNode.parent;
|
const canvasNode = mapNode.parent;
|
||||||
@ -31,6 +31,7 @@ cc.Class({
|
|||||||
self.inputDelayFrames = 8;
|
self.inputDelayFrames = 8;
|
||||||
self.inputScaleFrames = 2;
|
self.inputScaleFrames = 2;
|
||||||
self.inputFrameUpsyncDelayTolerance = 2;
|
self.inputFrameUpsyncDelayTolerance = 2;
|
||||||
|
self.collisionMinStep = 8;
|
||||||
|
|
||||||
self.renderCacheSize = 1024;
|
self.renderCacheSize = 1024;
|
||||||
self.serverFps = 60;
|
self.serverFps = 60;
|
||||||
@ -49,22 +50,17 @@ cc.Class({
|
|||||||
recoveryFrames: 34, // usually but not always "startupFrames+activeFrames", I hereby set it to be 1 frame more than the actual animation to avoid critical transition, i.e. when the animation is 1 frame from ending but "rdfPlayer.framesToRecover" is already counted 0 and the player triggers an other same attack, making an effective bullet trigger but no animation is played due to same animName is still playing
|
recoveryFrames: 34, // usually but not always "startupFrames+activeFrames", I hereby set it to be 1 frame more than the actual animation to avoid critical transition, i.e. when the animation is 1 frame from ending but "rdfPlayer.framesToRecover" is already counted 0 and the player triggers an other same attack, making an effective bullet trigger but no animation is played due to same animName is still playing
|
||||||
recoveryFramesOnBlock: 34,
|
recoveryFramesOnBlock: 34,
|
||||||
recoveryFramesOnHit: 34,
|
recoveryFramesOnHit: 34,
|
||||||
moveforward: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
},
|
|
||||||
hitboxOffset: 12.0, // should be about the radius of the PlayerCollider
|
hitboxOffset: 12.0, // should be about the radius of the PlayerCollider
|
||||||
hitboxSize: {
|
|
||||||
x: 23.0,
|
|
||||||
y: 32.0,
|
|
||||||
},
|
|
||||||
|
|
||||||
// for defender
|
// for defender
|
||||||
hitStunFrames: 18,
|
hitStunFrames: 18,
|
||||||
blockStunFrames: 9,
|
blockStunFrames: 9,
|
||||||
pushback: 8.0,
|
pushback: 8.0,
|
||||||
releaseTriggerType: 1, // 1: rising-edge, 2: falling-edge
|
releaseTriggerType: 1, // 1: rising-edge, 2: falling-edge
|
||||||
damage: 5
|
damage: 5,
|
||||||
|
hitboxSizeX: 24.0,
|
||||||
|
hitboxSizeY: 32.0,
|
||||||
|
selfMoveforwardX: 0,
|
||||||
|
selfMoveforwardY: 0,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,7 +72,7 @@ cc.Class({
|
|||||||
self.snapIntoPlatformOverlap = 0.1;
|
self.snapIntoPlatformOverlap = 0.1;
|
||||||
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
||||||
self.jumpingInitVelY = 7 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
self.jumpingInitVelY = 7 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
||||||
[self.gravityX, self.gravityY] = [0, -0.5*self.worldToVirtualGridRatio]; // unit: (virtual grid length/renderFrame^2)
|
[self.gravityX, self.gravityY] = [0, -0.5 * self.worldToVirtualGridRatio]; // unit: (virtual grid length/renderFrame^2)
|
||||||
|
|
||||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||||
|
|
||||||
@ -89,7 +85,6 @@ cc.Class({
|
|||||||
|
|
||||||
tiledMapIns.tmxAsset = null;
|
tiledMapIns.tmxAsset = null;
|
||||||
mapNode.removeAllChildren();
|
mapNode.removeAllChildren();
|
||||||
self._resetCurrentMatch();
|
|
||||||
|
|
||||||
if (self.showCriticalCoordinateLabels) {
|
if (self.showCriticalCoordinateLabels) {
|
||||||
const drawer = new cc.Node();
|
const drawer = new cc.Node();
|
||||||
@ -101,25 +96,30 @@ cc.Class({
|
|||||||
self.g = g;
|
self.g = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tiledMapIns.tmxAsset = tmxAsset;
|
tiledMapIns.tmxAsset = tmxAsset;
|
||||||
const newMapSize = tiledMapIns.getMapSize();
|
const newMapSize = tiledMapIns.getMapSize();
|
||||||
const newTileSize = tiledMapIns.getTileSize();
|
const newTileSize = tiledMapIns.getTileSize();
|
||||||
self.node.setContentSize(newMapSize.width * newTileSize.width, newMapSize.height * newTileSize.height);
|
self.node.setContentSize(newMapSize.width * newTileSize.width, newMapSize.height * newTileSize.height);
|
||||||
self.node.setPosition(cc.v2(0, 0));
|
self.node.setPosition(cc.v2(0, 0));
|
||||||
|
|
||||||
|
self.stageDiscreteW = newMapSize.width;
|
||||||
|
self.stageDiscreteH = newMapSize.height;
|
||||||
|
self.stageTileW = newTileSize.width;
|
||||||
|
self.stageTileH = newTileSize.height;
|
||||||
|
|
||||||
|
self._resetCurrentMatch();
|
||||||
let barrierIdCounter = 0;
|
let barrierIdCounter = 0;
|
||||||
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
||||||
for (let boundaryObj of boundaryObjs.barriers) {
|
for (let boundaryObj of boundaryObjs.barriers) {
|
||||||
const x0 = boundaryObj.anchor.x,
|
const gopkgsBoundaryAnchor = gopkgs.NewVec2DJs(boundaryObj.anchor.x, boundaryObj.anchor.y);
|
||||||
y0 = boundaryObj.anchor.y;
|
const gopkgsBoundaryPts = Array.from(boundaryObj, p => {
|
||||||
|
return gopkgs.NewVec2DJs(p.x, p.y);
|
||||||
|
});
|
||||||
|
const gopkgsBoundary = gopkgs.NewPolygon2DJs(gopkgsBoundaryAnchor, gopkgsBoundaryPts);
|
||||||
|
const gopkgsBarrier = gopkgs.NewBarrierJs(gopkgsBoundary);
|
||||||
|
|
||||||
const newBarrier = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj, p => {
|
const newBarrierCollider = gopkgs.GenerateConvexPolygonColliderJs(gopkgsBoundary, self.spaceOffsetX, self.spaceOffsetY, gopkgsBarrier, "Barrier");
|
||||||
return [p.x, p.y];
|
self.gopkgsCollisionSys.Add(newBarrierCollider);
|
||||||
}));
|
|
||||||
newBarrier.data = {
|
|
||||||
hardPushback: true
|
|
||||||
};
|
|
||||||
|
|
||||||
if (false && self.showCriticalCoordinateLabels) {
|
if (false && self.showCriticalCoordinateLabels) {
|
||||||
for (let i = 0; i < boundaryObj.length; ++i) {
|
for (let i = 0; i < boundaryObj.length; ++i) {
|
||||||
@ -152,20 +152,20 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// console.log("Created barrier: ", newBarrier);
|
// console.log("Created barrier: ", newBarrierCollider);
|
||||||
++barrierIdCounter;
|
++barrierIdCounter;
|
||||||
const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter);
|
const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter);
|
||||||
self.collisionSysMap.set(collisionBarrierIndex, newBarrier);
|
self.gopkgsCollisionSysMap[collisionBarrierIndex] = newBarrierCollider;
|
||||||
}
|
}
|
||||||
|
|
||||||
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
|
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
|
||||||
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
||||||
players: {
|
playersArr: [
|
||||||
10: window.pb.protos.PlayerDownsync.create({
|
window.pb.protos.PlayerDownsync.create({
|
||||||
id: 10,
|
id: 10,
|
||||||
joinIndex: 1,
|
joinIndex: 1,
|
||||||
virtualGridX: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[0],
|
virtualGridX: boundaryObjs.playerStartingPositions[0].x * self.worldToVirtualGridRatio,
|
||||||
virtualGridY: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[1],
|
virtualGridY: boundaryObjs.playerStartingPositions[0].y * self.worldToVirtualGridRatio,
|
||||||
speed: 1 * self.worldToVirtualGridRatio,
|
speed: 1 * self.worldToVirtualGridRatio,
|
||||||
colliderRadius: 12,
|
colliderRadius: 12,
|
||||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
||||||
@ -176,11 +176,11 @@ cc.Class({
|
|||||||
velY: 0,
|
velY: 0,
|
||||||
inAir: true,
|
inAir: true,
|
||||||
}),
|
}),
|
||||||
11: window.pb.protos.PlayerDownsync.create({
|
window.pb.protos.PlayerDownsync.create({
|
||||||
id: 11,
|
id: 11,
|
||||||
joinIndex: 2,
|
joinIndex: 2,
|
||||||
virtualGridX: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[0],
|
virtualGridX: boundaryObjs.playerStartingPositions[1].x * self.worldToVirtualGridRatio,
|
||||||
virtualGridY: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[1],
|
virtualGridY: boundaryObjs.playerStartingPositions[1].y * self.worldToVirtualGridRatio,
|
||||||
speed: 1 * self.worldToVirtualGridRatio,
|
speed: 1 * self.worldToVirtualGridRatio,
|
||||||
colliderRadius: 12,
|
colliderRadius: 12,
|
||||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
||||||
@ -191,10 +191,15 @@ cc.Class({
|
|||||||
velY: 0,
|
velY: 0,
|
||||||
inAir: true,
|
inAir: true,
|
||||||
}),
|
}),
|
||||||
}
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
self.selfPlayerInfo = {
|
self.selfPlayerInfo = {
|
||||||
id: 11
|
Id: 11,
|
||||||
|
JoinIndex: 2,
|
||||||
|
// For compatibility
|
||||||
|
id: 11,
|
||||||
|
joinIndex: 2,
|
||||||
};
|
};
|
||||||
self.onRoomDownsyncFrame(startRdf);
|
self.onRoomDownsyncFrame(startRdf);
|
||||||
|
|
||||||
@ -223,7 +228,7 @@ cc.Class({
|
|||||||
currSelfInput = prevAndCurrInputs[1];
|
currSelfInput = prevAndCurrInputs[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const [prevRdf, rdf] = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.collisionSys, self.collisionSysMap, false);
|
const [prevRdf, rdf] = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.gopkgsCollisionSys, self.gopkgsCollisionSysMap, false);
|
||||||
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
|
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
|
||||||
self.showDebugBoundaries(rdf);
|
self.showDebugBoundaries(rdf);
|
||||||
++self.renderFrameId;
|
++self.renderFrameId;
|
||||||
@ -234,4 +239,5 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ver": "1.0.5",
|
"ver": "1.0.5",
|
||||||
"uuid": "47d7dcb8-4b89-41da-9c6a-2499463a86a2",
|
"uuid": "b3810903-496b-43d7-8461-898cee958548",
|
||||||
"isPlugin": false,
|
"isPlugin": false,
|
||||||
"loadPluginInWeb": true,
|
"loadPluginInWeb": true,
|
||||||
"loadPluginInNative": true,
|
"loadPluginInNative": true,
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
const i18n = require('LanguageData');
|
|
||||||
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
|
|
||||||
|
|
||||||
const OnlineMap = require('./Map');
|
|
||||||
|
|
||||||
cc.Class({
|
|
||||||
extends: OnlineMap,
|
|
||||||
|
|
||||||
onDestroy() {
|
|
||||||
console.warn("+++++++ Map onDestroy()");
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoad() {
|
|
||||||
const self = this;
|
|
||||||
window.mapIns = self;
|
|
||||||
self.showCriticalCoordinateLabels = false;
|
|
||||||
|
|
||||||
const mapNode = self.node;
|
|
||||||
const canvasNode = mapNode.parent;
|
|
||||||
|
|
||||||
self.mainCameraNode = self.canvasNode.getChildByName("Main Camera");
|
|
||||||
self.mainCamera = self.mainCameraNode.getComponent(cc.Camera);
|
|
||||||
for (let child of self.mainCameraNode.children) {
|
|
||||||
child.setScale(1 / self.mainCamera.zoomRatio);
|
|
||||||
}
|
|
||||||
self.widgetsAboveAllNode = self.mainCameraNode.getChildByName("WidgetsAboveAll");
|
|
||||||
self.mainCameraNode.setPosition(cc.v2());
|
|
||||||
|
|
||||||
/** Init required prefab ended. */
|
|
||||||
|
|
||||||
self.inputDelayFrames = 8;
|
|
||||||
self.inputScaleFrames = 2;
|
|
||||||
self.inputFrameUpsyncDelayTolerance = 2;
|
|
||||||
self.collisionMinStep = 8;
|
|
||||||
|
|
||||||
self.renderCacheSize = 1024;
|
|
||||||
self.serverFps = 60;
|
|
||||||
self.rollbackEstimatedDt = 0.016667;
|
|
||||||
self.rollbackEstimatedDtMillis = 16.667;
|
|
||||||
self.rollbackEstimatedDtNanos = 16666666;
|
|
||||||
self.tooFastDtIntervalMillis = 0.5 * self.rollbackEstimatedDtMillis;
|
|
||||||
|
|
||||||
self.worldToVirtualGridRatio = 1000;
|
|
||||||
self.virtualGridToWorldRatio = 1.0 / self.worldToVirtualGridRatio;
|
|
||||||
self.meleeSkillConfig = {
|
|
||||||
1: {
|
|
||||||
// for offender
|
|
||||||
startupFrames: 10,
|
|
||||||
activeFrames: 20,
|
|
||||||
recoveryFrames: 34, // usually but not always "startupFrames+activeFrames", I hereby set it to be 1 frame more than the actual animation to avoid critical transition, i.e. when the animation is 1 frame from ending but "rdfPlayer.framesToRecover" is already counted 0 and the player triggers an other same attack, making an effective bullet trigger but no animation is played due to same animName is still playing
|
|
||||||
recoveryFramesOnBlock: 34,
|
|
||||||
recoveryFramesOnHit: 34,
|
|
||||||
hitboxOffset: 12.0, // should be about the radius of the PlayerCollider
|
|
||||||
// for defender
|
|
||||||
hitStunFrames: 18,
|
|
||||||
blockStunFrames: 9,
|
|
||||||
pushback: 8.0,
|
|
||||||
releaseTriggerType: 1, // 1: rising-edge, 2: falling-edge
|
|
||||||
damage: 5,
|
|
||||||
hitboxSizeX: 24.0,
|
|
||||||
hitboxSizeY: 32.0,
|
|
||||||
selfMoveforwardX: 0,
|
|
||||||
selfMoveforwardY: 0,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
[WARNING] As when a character is standing on a barrier, if not carefully curated there MIGHT BE a bouncing sequence of "[(inAir -> dropIntoBarrier ->), (notInAir -> pushedOutOfBarrier ->)], [(inAir -> ..."
|
|
||||||
|
|
||||||
Moreover, "snapIntoPlatformOverlap" should be small enough such that the walking "velX" or jumping initial "velY" can escape from it by 1 renderFrame (when jumping is triggered, the character is waived from snappig for 1 renderFrame).
|
|
||||||
*/
|
|
||||||
self.snapIntoPlatformOverlap = 0.1;
|
|
||||||
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
|
||||||
self.jumpingInitVelY = 7 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
|
||||||
[self.gravityX, self.gravityY] = [0, -0.5 * self.worldToVirtualGridRatio]; // unit: (virtual grid length/renderFrame^2)
|
|
||||||
|
|
||||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
|
||||||
|
|
||||||
const fullPathOfTmxFile = cc.js.formatStr("map/%s/map", "dungeon");
|
|
||||||
cc.loader.loadRes(fullPathOfTmxFile, cc.TiledMapAsset, (err, tmxAsset) => {
|
|
||||||
if (null != err) {
|
|
||||||
console.error(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tiledMapIns.tmxAsset = null;
|
|
||||||
mapNode.removeAllChildren();
|
|
||||||
|
|
||||||
if (self.showCriticalCoordinateLabels) {
|
|
||||||
const drawer = new cc.Node();
|
|
||||||
drawer.setPosition(cc.v2(0, 0))
|
|
||||||
safelyAddChild(self.node, drawer);
|
|
||||||
setLocalZOrder(drawer, 999);
|
|
||||||
const g = drawer.addComponent(cc.Graphics);
|
|
||||||
g.lineWidth = 2;
|
|
||||||
self.g = g;
|
|
||||||
}
|
|
||||||
|
|
||||||
tiledMapIns.tmxAsset = tmxAsset;
|
|
||||||
const newMapSize = tiledMapIns.getMapSize();
|
|
||||||
const newTileSize = tiledMapIns.getTileSize();
|
|
||||||
self.node.setContentSize(newMapSize.width * newTileSize.width, newMapSize.height * newTileSize.height);
|
|
||||||
self.node.setPosition(cc.v2(0, 0));
|
|
||||||
|
|
||||||
self.stageDiscreteW = newMapSize.width;
|
|
||||||
self.stageDiscreteH = newMapSize.height;
|
|
||||||
self.stageTileW = newTileSize.width;
|
|
||||||
self.stageTileH = newTileSize.height;
|
|
||||||
|
|
||||||
self._resetCurrentMatch();
|
|
||||||
let barrierIdCounter = 0;
|
|
||||||
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
|
||||||
for (let boundaryObj of boundaryObjs.barriers) {
|
|
||||||
const gopkgsBoundaryAnchor = gopkgs.NewVec2DJs(boundaryObj.anchor.x, boundaryObj.anchor.y);
|
|
||||||
const gopkgsBoundaryPts = Array.from(boundaryObj, p => {
|
|
||||||
return gopkgs.NewVec2DJs(p.x, p.y);
|
|
||||||
});
|
|
||||||
const gopkgsBoundary = gopkgs.NewPolygon2DJs(gopkgsBoundaryAnchor, gopkgsBoundaryPts);
|
|
||||||
const gopkgsBarrier = gopkgs.NewBarrierJs(gopkgsBoundary);
|
|
||||||
|
|
||||||
const newBarrierCollider = gopkgs.GenerateConvexPolygonColliderJs(gopkgsBoundary, self.spaceOffsetX, self.spaceOffsetY, gopkgsBarrier, "Barrier");
|
|
||||||
self.gopkgsCollisionSys.Add(newBarrierCollider);
|
|
||||||
|
|
||||||
if (false && self.showCriticalCoordinateLabels) {
|
|
||||||
for (let i = 0; i < boundaryObj.length; ++i) {
|
|
||||||
const barrierVertLabelNode = new cc.Node();
|
|
||||||
switch (i % 4) {
|
|
||||||
case 0:
|
|
||||||
barrierVertLabelNode.color = cc.Color.RED;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
barrierVertLabelNode.color = cc.Color.GRAY;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
barrierVertLabelNode.color = cc.Color.BLACK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
barrierVertLabelNode.color = cc.Color.MAGENTA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const wx = boundaryObj.anchor.x + boundaryObj[i].x,
|
|
||||||
wy = boundaryObj.anchor.y + boundaryObj[i].y;
|
|
||||||
barrierVertLabelNode.setPosition(cc.v2(wx, wy));
|
|
||||||
const barrierVertLabel = barrierVertLabelNode.addComponent(cc.Label);
|
|
||||||
barrierVertLabel.fontSize = 12;
|
|
||||||
barrierVertLabel.lineHeight = barrierVertLabel.fontSize + 1;
|
|
||||||
barrierVertLabel.string = `(${wx.toFixed(1)}, ${wy.toFixed(1)})`;
|
|
||||||
safelyAddChild(self.node, barrierVertLabelNode);
|
|
||||||
setLocalZOrder(barrierVertLabelNode, 5);
|
|
||||||
|
|
||||||
barrierVertLabelNode.active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// console.log("Created barrier: ", newBarrierCollider);
|
|
||||||
++barrierIdCounter;
|
|
||||||
const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter);
|
|
||||||
self.gopkgsCollisionSysMap[collisionBarrierIndex] = newBarrierCollider;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
|
|
||||||
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
|
||||||
playersArr: [
|
|
||||||
window.pb.protos.PlayerDownsync.create({
|
|
||||||
id: 10,
|
|
||||||
joinIndex: 1,
|
|
||||||
virtualGridX: boundaryObjs.playerStartingPositions[0].x * self.worldToVirtualGridRatio,
|
|
||||||
virtualGridY: boundaryObjs.playerStartingPositions[0].y * self.worldToVirtualGridRatio,
|
|
||||||
speed: 1 * self.worldToVirtualGridRatio,
|
|
||||||
colliderRadius: 12,
|
|
||||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
|
||||||
framesToRecover: 0,
|
|
||||||
dirX: 0,
|
|
||||||
dirY: 0,
|
|
||||||
velX: 0,
|
|
||||||
velY: 0,
|
|
||||||
inAir: true,
|
|
||||||
}),
|
|
||||||
window.pb.protos.PlayerDownsync.create({
|
|
||||||
id: 11,
|
|
||||||
joinIndex: 2,
|
|
||||||
virtualGridX: boundaryObjs.playerStartingPositions[1].x * self.worldToVirtualGridRatio,
|
|
||||||
virtualGridY: boundaryObjs.playerStartingPositions[1].y * self.worldToVirtualGridRatio,
|
|
||||||
speed: 1 * self.worldToVirtualGridRatio,
|
|
||||||
colliderRadius: 12,
|
|
||||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
|
||||||
framesToRecover: 0,
|
|
||||||
dirX: 0,
|
|
||||||
dirY: 0,
|
|
||||||
velX: 0,
|
|
||||||
velY: 0,
|
|
||||||
inAir: true,
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
self.selfPlayerInfo = {
|
|
||||||
Id: 11,
|
|
||||||
JoinIndex: 2,
|
|
||||||
// For compatibility
|
|
||||||
id: 11,
|
|
||||||
joinIndex: 2,
|
|
||||||
};
|
|
||||||
self.onRoomDownsyncFrame(startRdf);
|
|
||||||
|
|
||||||
self.battleState = ALL_BATTLE_STATES.IN_BATTLE;
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
update(dt) {
|
|
||||||
const self = this;
|
|
||||||
if (ALL_BATTLE_STATES.IN_BATTLE == self.battleState) {
|
|
||||||
const elapsedMillisSinceLastFrameIdTriggered = performance.now() - self.lastRenderFrameIdTriggeredAt;
|
|
||||||
if (elapsedMillisSinceLastFrameIdTriggered < self.tooFastDtIntervalMillis) {
|
|
||||||
// [WARNING] We should avoid a frontend ticking too fast to prevent cheating, as well as ticking too slow to cause a "resync avalanche" that impacts user experience!
|
|
||||||
// console.debug("Avoiding too fast frame@renderFrameId=", self.renderFrameId, ": elapsedMillisSinceLastFrameIdTriggered=", elapsedMillisSinceLastFrameIdTriggered);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
let st = performance.now();
|
|
||||||
let prevSelfInput = null,
|
|
||||||
currSelfInput = null;
|
|
||||||
const noDelayInputFrameId = self._convertToInputFrameId(self.renderFrameId, 0); // It's important that "inputDelayFrames == 0" here
|
|
||||||
if (self.shouldGenerateInputFrameUpsync(self.renderFrameId)) {
|
|
||||||
const prevAndCurrInputs = self.getOrPrefabInputFrameUpsync(noDelayInputFrameId);
|
|
||||||
prevSelfInput = prevAndCurrInputs[0];
|
|
||||||
currSelfInput = prevAndCurrInputs[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const [prevRdf, rdf] = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.gopkgsCollisionSys, self.gopkgsCollisionSysMap, false);
|
|
||||||
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
|
|
||||||
self.showDebugBoundaries(rdf);
|
|
||||||
++self.renderFrameId;
|
|
||||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
|
||||||
let t3 = performance.now();
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error during Map.update", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "1.0.5",
|
|
||||||
"uuid": "b3810903-496b-43d7-8461-898cee958548",
|
|
||||||
"isPlugin": false,
|
|
||||||
"loadPluginInWeb": true,
|
|
||||||
"loadPluginInNative": true,
|
|
||||||
"loadPluginInEditor": false,
|
|
||||||
"subMetas": {}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user