mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 11:48:56 +00:00
Minor update to floating number precision.
This commit is contained in:
parent
1a3b3a0a7a
commit
f37f4337de
@ -128,11 +128,12 @@ func calRoomScore(inRoomPlayerCount int32, roomPlayerCnt int, currentRoomBattleS
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
Id int32
|
Id int32
|
||||||
Capacity int
|
Capacity int
|
||||||
Players map[int32]*Player
|
playerColliderRadius float64
|
||||||
PlayersArr []*Player // ordered by joinIndex
|
Players map[int32]*Player
|
||||||
CollisionSysMap map[int32]*resolv.Object
|
PlayersArr []*Player // ordered by joinIndex
|
||||||
|
CollisionSysMap map[int32]*resolv.Object
|
||||||
/**
|
/**
|
||||||
* The following `PlayerDownsyncSessionDict` is NOT individually put
|
* The following `PlayerDownsyncSessionDict` is NOT individually put
|
||||||
* under `type Player struct` for a reason.
|
* under `type Player struct` for a reason.
|
||||||
@ -415,7 +416,12 @@ func (pR *Room) StartBattle() {
|
|||||||
pR.RenderFrameBuffer.Put(kickoffFrame)
|
pR.RenderFrameBuffer.Put(kickoffFrame)
|
||||||
|
|
||||||
// Refresh "Colliders"
|
// Refresh "Colliders"
|
||||||
pR.refreshColliders()
|
spaceW := pR.StageDiscreteW * pR.StageTileW
|
||||||
|
spaceH := pR.StageDiscreteH * pR.StageTileH
|
||||||
|
|
||||||
|
spaceOffsetX := float64(spaceW) * 0.5
|
||||||
|
spaceOffsetY := float64(spaceH) * 0.5
|
||||||
|
pR.refreshColliders(spaceW, spaceH, spaceOffsetX, spaceOffsetY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
|
* Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
|
||||||
@ -488,7 +494,7 @@ func (pR *Room) StartBattle() {
|
|||||||
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
|
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
|
||||||
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames)
|
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames)
|
||||||
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
|
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
|
||||||
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId)
|
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId, spaceOffsetX, spaceOffsetY)
|
||||||
dynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
|
dynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,6 +798,7 @@ func (pR *Room) Dismiss() {
|
|||||||
func (pR *Room) OnDismissed() {
|
func (pR *Room) OnDismissed() {
|
||||||
|
|
||||||
// Always instantiates new HeapRAM blocks and let the old blocks die out due to not being retained by any root reference.
|
// Always instantiates new HeapRAM blocks and let the old blocks die out due to not being retained by any root reference.
|
||||||
|
pR.playerColliderRadius = float64(12) // hardcoded
|
||||||
pR.Players = make(map[int32]*Player)
|
pR.Players = make(map[int32]*Player)
|
||||||
pR.PlayersArr = make([]*Player, pR.Capacity)
|
pR.PlayersArr = make([]*Player, pR.Capacity)
|
||||||
pR.CollisionSysMap = make(map[int32]*resolv.Object)
|
pR.CollisionSysMap = make(map[int32]*resolv.Object)
|
||||||
@ -1175,7 +1182,7 @@ func (pR *Room) forceConfirmationIfApplicable() uint64 {
|
|||||||
return unconfirmedMask
|
return unconfirmedMask
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32) {
|
func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32, spaceOffsetX, spaceOffsetY float64) {
|
||||||
if fromRenderFrameId >= toRenderFrameId {
|
if fromRenderFrameId >= toRenderFrameId {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1216,26 +1223,27 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
|
|||||||
playerCollider := pR.CollisionSysMap[collisionPlayerIndex]
|
playerCollider := pR.CollisionSysMap[collisionPlayerIndex]
|
||||||
if collision := playerCollider.Check(oldDx, oldDy, "Barrier"); collision != nil {
|
if collision := playerCollider.Check(oldDx, oldDy, "Barrier"); collision != nil {
|
||||||
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
||||||
for _, obj := range collision.Objects {
|
for _, obj := range collision.Objects {
|
||||||
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
|
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||||
if overlapped, pushbackX, pushbackY := CalcPushbacks(oldDx, oldDy, playerShape, barrierShape); overlapped {
|
if overlapped, pushbackX, pushbackY := CalcPushbacks(oldDx, oldDy, playerShape, barrierShape); overlapped {
|
||||||
Logger.Debug(fmt.Sprintf("Collided & overlapped: player.X=%v, player.Y=%v, oldDx=%v, oldDy=%v, playerShape=%v, toCheckBarrier=%v, pushbackX=%v, pushbackY=%v", playerCollider.X, playerCollider.Y, oldDx, oldDy, ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
|
Logger.Debug(fmt.Sprintf("Collided & overlapped: player.X=%v, player.Y=%v, oldDx=%v, oldDy=%v, playerShape=%v, toCheckBarrier=%v, pushbackX=%v, pushbackY=%v", playerCollider.X, playerCollider.Y, oldDx, oldDy, ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
|
||||||
dx -= pushbackX
|
dx -= pushbackX
|
||||||
dy -= pushbackY
|
dy -= pushbackY
|
||||||
} else {
|
} else {
|
||||||
Logger.Debug(fmt.Sprintf("Collided BUT not overlapped: player.X=%v, player.Y=%v, oldDx=%v, oldDy=%v, playerShape=%v, toCheckBarrier=%v", playerCollider.X, playerCollider.Y, oldDx, oldDy, ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape)))
|
Logger.Debug(fmt.Sprintf("Collided BUT not overlapped: player.X=%v, player.Y=%v, oldDx=%v, oldDy=%v, playerShape=%v, toCheckBarrier=%v", playerCollider.X, playerCollider.Y, oldDx, oldDy, ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playerCollider.X += dx
|
playerCollider.X += dx
|
||||||
playerCollider.Y += dy
|
playerCollider.Y += dy
|
||||||
|
|
||||||
// Update in "collision space"
|
// Update in "collision space"
|
||||||
playerCollider.Update()
|
playerCollider.Update()
|
||||||
|
|
||||||
player.Dir.Dx = decodedInput[0]
|
player.Dir.Dx = decodedInput[0]
|
||||||
player.Dir.Dy = decodedInput[1]
|
player.Dir.Dy = decodedInput[1]
|
||||||
player.X += dx
|
player.X = playerCollider.X + pR.playerColliderRadius - spaceOffsetX
|
||||||
player.Y += dy
|
player.Y = playerCollider.Y + pR.playerColliderRadius - spaceOffsetY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,19 +1261,13 @@ func (pR *Room) inputFrameIdDebuggable(inputFrameId int32) bool {
|
|||||||
return 0 == (inputFrameId % 10)
|
return 0 == (inputFrameId % 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) refreshColliders() {
|
func (pR *Room) refreshColliders(spaceW, spaceH int32, spaceOffsetX, spaceOffsetY float64) {
|
||||||
playerColliderRadius := float64(12) // hardcoded
|
|
||||||
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
|
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
|
||||||
spaceW := pR.StageDiscreteW * pR.StageTileW
|
|
||||||
spaceH := pR.StageDiscreteH * pR.StageTileH
|
|
||||||
|
|
||||||
spaceOffsetX := float64(spaceW) * 0.5
|
|
||||||
spaceOffsetY := float64(spaceH) * 0.5
|
|
||||||
|
|
||||||
minStep := int(3) // the approx minimum distance a player can move per frame
|
minStep := int(3) // the approx minimum distance a player can move per frame
|
||||||
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled
|
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled
|
||||||
for _, player := range pR.Players {
|
for _, player := range pR.Players {
|
||||||
playerCollider := GenerateRectCollider(player.X, player.Y, playerColliderRadius*2, playerColliderRadius*2, spaceOffsetX, spaceOffsetY, "Player")
|
playerCollider := GenerateRectCollider(player.X, player.Y, pR.playerColliderRadius*2, pR.playerColliderRadius*2, spaceOffsetX, spaceOffsetY, "Player")
|
||||||
space.Add(playerCollider)
|
space.Add(playerCollider)
|
||||||
// Keep track of the collider in "pR.CollisionSysMap"
|
// Keep track of the collider in "pR.CollisionSysMap"
|
||||||
joinIndex := player.JoinIndex
|
joinIndex := player.JoinIndex
|
||||||
|
@ -121,13 +121,19 @@ cc.Class({
|
|||||||
return (0 == inputFrameId % 10);
|
return (0 == inputFrameId % 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
dumpToRenderCache: function(roomDownsyncFrame) {
|
dumpToRenderCache: function(rdf) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
// round player position to lower precision
|
||||||
|
for (let playerId in rdf.players) {
|
||||||
|
const immediatePlayerInfo = rdf.players[playerId];
|
||||||
|
rdf.players[playerId].x = parseFloat(parseInt(immediatePlayerInfo.x * 100)) / 100.0;
|
||||||
|
rdf.players[playerId].y = parseFloat(parseInt(immediatePlayerInfo.y * 100)) / 100.0;
|
||||||
|
}
|
||||||
const minToKeepRenderFrameId = self.lastAllConfirmedRenderFrameId;
|
const minToKeepRenderFrameId = self.lastAllConfirmedRenderFrameId;
|
||||||
while (0 < self.recentRenderCache.cnt && self.recentRenderCache.stFrameId < minToKeepRenderFrameId) {
|
while (0 < self.recentRenderCache.cnt && self.recentRenderCache.stFrameId < minToKeepRenderFrameId) {
|
||||||
self.recentRenderCache.pop();
|
self.recentRenderCache.pop();
|
||||||
}
|
}
|
||||||
const ret = self.recentRenderCache.setByFrameId(roomDownsyncFrame, roomDownsyncFrame.id);
|
const ret = self.recentRenderCache.setByFrameId(rdf, rdf.id);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -382,8 +388,7 @@ cc.Class({
|
|||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
||||||
window.initPersistentSessionClient(self.initAfterWSConnected, null /* Deliberately NOT passing in any `expectedRoomId`. -- YFLu */ );
|
window.initPersistentSessionClient(self.initAfterWSConnected, null /* Deliberately NOT passing in any `expectedRoomId`. -- YFLu */ );
|
||||||
};
|
};
|
||||||
resultPanelScriptIns.onCloseDelegate = () => {
|
resultPanelScriptIns.onCloseDelegate = () => {};
|
||||||
};
|
|
||||||
|
|
||||||
self.gameRuleNode = cc.instantiate(self.gameRulePrefab);
|
self.gameRuleNode = cc.instantiate(self.gameRulePrefab);
|
||||||
self.gameRuleNode.width = self.canvasNode.width;
|
self.gameRuleNode.width = self.canvasNode.width;
|
||||||
@ -575,6 +580,7 @@ cc.Class({
|
|||||||
if (rdf.id < self.lastAllConfirmedRenderFrameId) {
|
if (rdf.id < self.lastAllConfirmedRenderFrameId) {
|
||||||
return window.RING_BUFF_FAILED_TO_SET;
|
return window.RING_BUFF_FAILED_TO_SET;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dumpRenderCacheRet = self.dumpToRenderCache(rdf);
|
const dumpRenderCacheRet = self.dumpToRenderCache(rdf);
|
||||||
if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) {
|
if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) {
|
||||||
console.error("Something is wrong while setting the RingBuffer by frameId!");
|
console.error("Something is wrong while setting the RingBuffer by frameId!");
|
||||||
@ -589,8 +595,12 @@ cc.Class({
|
|||||||
return dumpRenderCacheRet;
|
return dumpRenderCacheRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The logic below applies to (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id || window.RING_BUFF_NON_CONSECUTIVE_SET == dumpRenderCacheRet)
|
// The logic below applies to ( || window.RING_BUFF_NON_CONSECUTIVE_SET == dumpRenderCacheRet)
|
||||||
console.log('On battle started or resynced! renderFrameId=', rdf.id);
|
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id) {
|
||||||
|
console.log('On battle resynced! renderFrameId=', rdf.id);
|
||||||
|
} else {
|
||||||
|
console.log('On battle resynced! renderFrameId=', rdf.id);
|
||||||
|
}
|
||||||
|
|
||||||
self.renderFrameId = rdf.id;
|
self.renderFrameId = rdf.id;
|
||||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
self.lastRenderFrameIdTriggeredAt = performance.now();
|
||||||
@ -973,12 +983,14 @@ cc.Class({
|
|||||||
if (
|
if (
|
||||||
null != inputFrameAppliedOnPrevRenderFrame && self._allConfirmed(inputFrameAppliedOnPrevRenderFrame.confirmedList)
|
null != inputFrameAppliedOnPrevRenderFrame && self._allConfirmed(inputFrameAppliedOnPrevRenderFrame.confirmedList)
|
||||||
&&
|
&&
|
||||||
self.lastAllConfirmedRenderFrameId >= prevRenderFrameId
|
|
||||||
&&
|
|
||||||
rdf.id > self.lastAllConfirmedRenderFrameId
|
rdf.id > self.lastAllConfirmedRenderFrameId
|
||||||
) {
|
) {
|
||||||
|
// We got a more up-to-date "all-confirmed-render-frame".
|
||||||
self.lastAllConfirmedRenderFrameId = rdf.id;
|
self.lastAllConfirmedRenderFrameId = rdf.id;
|
||||||
self.chaserRenderFrameId = rdf.id; // it must be true that "chaserRenderFrameId >= lastAllConfirmedRenderFrameId"
|
if (rdf.id > self.chaserRenderFrameId) {
|
||||||
|
// it must be true that "chaserRenderFrameId >= lastAllConfirmedRenderFrameId"
|
||||||
|
self.chaserRenderFrameId = rdf.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.dumpToRenderCache(rdf);
|
self.dumpToRenderCache(rdf);
|
||||||
return rdf;
|
return rdf;
|
||||||
@ -991,11 +1003,10 @@ cc.Class({
|
|||||||
const immediatePlayerInfo = rdf.players[playerId];
|
const immediatePlayerInfo = rdf.players[playerId];
|
||||||
const dx = (immediatePlayerInfo.x - playerRichInfo.node.x);
|
const dx = (immediatePlayerInfo.x - playerRichInfo.node.x);
|
||||||
const dy = (immediatePlayerInfo.y - playerRichInfo.node.y);
|
const dy = (immediatePlayerInfo.y - playerRichInfo.node.y);
|
||||||
const selfJiggling = (playerId == self.selfPlayerInfo.playerId && (0 != dx && self.teleportEps1D >= Math.abs(dx) && 0 != dy && self.teleportEps1D >= Math.abs(dy)));
|
const justJiggling = (self.teleportEps1D >= Math.abs(dx) && self.teleportEps1D >= Math.abs(dy));
|
||||||
if (!selfJiggling) {
|
if (!justJiggling) {
|
||||||
|
console.log("@renderFrameId=" + self.renderFrameId + ", teleporting playerId=" + playerId + ": '(" + playerRichInfo.node.x + ", " + playerRichInfo.node.y, ")' to '(" + immediatePlayerInfo.x + ", " + immediatePlayerInfo.y + ")'");
|
||||||
playerRichInfo.node.setPosition(immediatePlayerInfo.x, immediatePlayerInfo.y);
|
playerRichInfo.node.setPosition(immediatePlayerInfo.x, immediatePlayerInfo.y);
|
||||||
} else {
|
|
||||||
console.log("selfJiggling: dx = ", dx, ", dy = ", dy);
|
|
||||||
}
|
}
|
||||||
playerRichInfo.scriptIns.scheduleNewDirection(immediatePlayerInfo.dir, false);
|
playerRichInfo.scriptIns.scheduleNewDirection(immediatePlayerInfo.dir, false);
|
||||||
playerRichInfo.scriptIns.updateSpeed(immediatePlayerInfo.speed);
|
playerRichInfo.scriptIns.updateSpeed(immediatePlayerInfo.speed);
|
||||||
@ -1074,9 +1085,9 @@ cc.Class({
|
|||||||
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();
|
||||||
for (const barrier of potentials) {
|
for (const potential of potentials) {
|
||||||
// Test if the player collides with the wall
|
// Test if the player collides with the wall
|
||||||
if (!playerCollider.collides(barrier, result)) continue;
|
if (!playerCollider.collides(potential, result)) continue;
|
||||||
// Push the player out of the wall
|
// Push the player out of the wall
|
||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user