diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go
index a947116..40a3ed4 100644
--- a/battle_srv/models/room.go
+++ b/battle_srv/models/room.go
@@ -201,7 +201,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
pPlayerFromDbInit.Speed = pR.PlayerDefaultSpeed // Hardcoded
- pPlayerFromDbInit.ColliderRadius = float64(12) // Hardcoded
+ pPlayerFromDbInit.ColliderRadius = float64(24) // Hardcoded
pR.Players[playerId] = pPlayerFromDbInit
pR.PlayerDownsyncSessionDict[playerId] = session
@@ -234,7 +234,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
pEffectiveInRoomPlayerInstance.Speed = pR.PlayerDefaultSpeed // Hardcoded
- pEffectiveInRoomPlayerInstance.ColliderRadius = float64(12) // Hardcoded
+ pEffectiveInRoomPlayerInstance.ColliderRadius = float64(16) // Hardcoded
Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("joinIndex", pEffectiveInRoomPlayerInstance.JoinIndex), zap.Any("playerBattleState", pEffectiveInRoomPlayerInstance.BattleState), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId), zap.Any("LastSentInputFrameId", pEffectiveInRoomPlayerInstance.LastSentInputFrameId))
return true
@@ -252,7 +252,7 @@ func (pR *Room) ChooseStage() error {
}
rand.Seed(time.Now().Unix())
- stageNameList := []string{ /*"simple" ,*/ "richsoil"}
+ stageNameList := []string{"simple" /* "richsoil" */}
chosenStageIndex := rand.Int() % len(stageNameList) // Hardcoded temporarily. -- YFLu
pR.StageName = stageNameList[chosenStageIndex]
@@ -792,7 +792,7 @@ 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.
pR.WorldToVirtualGridRatio = float64(10)
pR.VirtualGridToWorldRatio = float64(1.0) / pR.WorldToVirtualGridRatio // this is a one-off computation, should avoid division in iterations
- pR.PlayerDefaultSpeed = 10 // Hardcoded in virtual grids per frame
+ pR.PlayerDefaultSpeed = 20 // Hardcoded in virtual grids per frame
pR.Players = make(map[int32]*Player)
pR.PlayersArr = make([]*Player, pR.Capacity)
pR.CollisionSysMap = make(map[int32]*resolv.Object)
@@ -940,7 +940,7 @@ func (pR *Room) onPlayerAdded(playerId int32) {
if nil == playerPos {
panic(fmt.Sprintf("onPlayerAdded error, nil == playerPos, roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
}
- pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = pR.worldToVirtualGridPos(playerPos.X, playerPos.Y)
+ pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = WorldToVirtualGridPos(playerPos.X, playerPos.Y, pR.WorldToVirtualGridRatio)
break
}
@@ -1240,15 +1240,19 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
currPlayerDownsync := currRenderFrame.Players[playerId]
encodedInput := inputList[joinIndex-1]
decodedInput := DIRECTION_DECODER[encodedInput]
- newVx := (currPlayerDownsync.VirtualGridX + (decodedInput[0] + decodedInput[0]*currPlayerDownsync.Speed))
- newVy := (currPlayerDownsync.VirtualGridY + (decodedInput[1] + decodedInput[1]*currPlayerDownsync.Speed))
+ proposedVirtualGridDx, proposedVirtualGridDy := (decodedInput[0] + decodedInput[0]*currPlayerDownsync.Speed), (decodedInput[1] + decodedInput[1]*currPlayerDownsync.Speed)
+ newVx, newVy := (currPlayerDownsync.VirtualGridX + proposedVirtualGridDx), (currPlayerDownsync.VirtualGridY + proposedVirtualGridDy)
// Reset playerCollider position from the "virtual grid position"
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
playerCollider := collisionSysMap[collisionPlayerIndex]
- playerCollider.X, playerCollider.Y = pR.virtualGridToPlayerColliderPos(newVx, newVy, player)
+ playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio)
// Update in the collision system
playerCollider.Update()
+
+ if 0 < encodedInput {
+ Logger.Debug(fmt.Sprintf("Moved playerId=%v: virtual (%d, %d) -> (%d, %d), now playerCollider at (%.2f, %.2f)", playerId, currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY, newVx, newVy, playerCollider.X, playerCollider.Y))
+ }
}
// handle pushbacks upon collision after all movements treated as simultaneous
@@ -1256,17 +1260,17 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
joinIndex := player.JoinIndex
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
playerCollider := collisionSysMap[collisionPlayerIndex]
- oldDx, oldDy := float64(0), float64(0)
- if collision := playerCollider.Check(oldDx, oldDy); collision != nil {
+ if collision := playerCollider.Check(0, 0); collision != nil {
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
+ Logger.Warn(fmt.Sprintf("Collided: a=%v", ConvexPolygonStr(playerShape)))
for _, obj := range collision.Objects {
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
- 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))
+ if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape); overlapped {
+ Logger.Warn(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
effPushbacks[joinIndex-1].X += pushbackX
effPushbacks[joinIndex-1].Y += pushbackY
} 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.Warn(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), overlapResult))
}
}
}
@@ -1278,7 +1282,7 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
playerCollider := collisionSysMap[collisionPlayerIndex]
// Update "virtual grid position"
- newVx, newVy := pR.playerColliderAnchorToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, player)
+ newVx, newVy := PolygonColliderAnchorToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.WorldToVirtualGridRatio)
nextRenderFramePlayers[playerId].VirtualGridX = newVx
nextRenderFramePlayers[playerId].VirtualGridY = newVy
}
@@ -1296,10 +1300,10 @@ func (pR *Room) inputFrameIdDebuggable(inputFrameId int32) bool {
func (pR *Room) refreshColliders(spaceW, spaceH int32) {
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
- minStep := int(pR.PlayerDefaultSpeed) // the approx minimum distance a player can move per frame in world coordinate
- space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled
+ minStep := (int(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 2) // the approx minimum distance a player can move per frame in world coordinate
+ 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 {
- wx, wy := pR.virtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY)
+ wx, wy := VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio)
playerCollider := GenerateRectCollider(wx, wy, player.ColliderRadius*2, player.ColliderRadius*2, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Player")
space.Add(playerCollider)
// Keep track of the collider in "pR.CollisionSysMap"
@@ -1319,37 +1323,3 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) {
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))
}
-
-func (pR *Room) worldToVirtualGridPos(wx, wy float64) (int32, int32) {
- // [WARNING] Introduces loss of precision!
- // 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(math.Round(wx * pR.WorldToVirtualGridRatio))
- var virtualGridY int32 = int32(math.Round(wy * pR.WorldToVirtualGridRatio))
- return virtualGridX, virtualGridY
-}
-
-func (pR *Room) virtualGridToWorldPos(vx, vy int32) (float64, float64) {
- // No loss of precision
- var wx float64 = float64(vx) * pR.VirtualGridToWorldRatio
- var wy float64 = float64(vy) * pR.VirtualGridToWorldRatio
- return wx, wy
-}
-
-func (pR *Room) playerWorldToCollisionPos(wx, wy float64, player *Player) (float64, float64) {
- // TODO: remove this duplicate code w.r.t. "dnmshared/resolv_helper.go"
- return wx - player.ColliderRadius + pR.collisionSpaceOffsetX, wy - player.ColliderRadius + pR.collisionSpaceOffsetY
-}
-
-func (pR *Room) playerColliderAnchorToWorldPos(cx, cy float64, player *Player) (float64, float64) {
- return cx + player.ColliderRadius - pR.collisionSpaceOffsetX, cy + player.ColliderRadius - pR.collisionSpaceOffsetY
-}
-
-func (pR *Room) playerColliderAnchorToVirtualGridPos(cx, cy float64, player *Player) (int32, int32) {
- wx, wy := pR.playerColliderAnchorToWorldPos(cx, cy, player)
- return pR.worldToVirtualGridPos(wx, wy)
-}
-
-func (pR *Room) virtualGridToPlayerColliderPos(vx, vy int32, player *Player) (float64, float64) {
- wx, wy := pR.virtualGridToWorldPos(vx, vy)
- return pR.playerWorldToCollisionPos(wx, wy, player)
-}
diff --git a/collider_visualizer/worldColliderDisplay.go b/collider_visualizer/worldColliderDisplay.go
index 9064e91..a89a150 100644
--- a/collider_visualizer/worldColliderDisplay.go
+++ b/collider_visualizer/worldColliderDisplay.go
@@ -33,14 +33,15 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
spaceOffsetX := float64(spaceW) * 0.5
spaceOffsetY := float64(spaceH) * 0.5
- playerDefaultSpeed := int32(10)
- minStep := int(playerDefaultSpeed)
- playerColliderRadius := float64(12)
+ virtualGridToWorldRatio := 0.1
+ playerDefaultSpeed := 20
+ minStep := (int(float64(playerDefaultSpeed)*virtualGridToWorldRatio) << 2)
+ playerColliderRadius := float64(24)
playerColliders := make([]*resolv.Object, len(playerPosList.Eles))
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep)
for i, playerPos := range playerPosList.Eles {
playerCollider := GenerateRectCollider(playerPos.X, playerPos.Y, playerColliderRadius*2, playerColliderRadius*2, spaceOffsetX, spaceOffsetY, "Player") // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset"
- Logger.Info(fmt.Sprintf("Player Collider#%d: playerPos.X=%v, playerPos.Y=%v, radius=%v, spaceOffsetX=%v, spaceOffsetY=%v, shape=%v", i, playerPos.X, playerPos.Y, playerColliderRadius, spaceOffsetX, spaceOffsetY, playerCollider.Shape))
+ Logger.Info(fmt.Sprintf("Player Collider#%d: player world pos =(%.2f, %.2f), shape=%v", i, playerPos.X, playerPos.Y, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon))))
playerColliders[i] = playerCollider
space.Add(playerCollider)
}
@@ -48,7 +49,7 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
barrierLocalId := 0
for _, barrierUnaligned := range barrierList.Eles {
barrierCollider := GenerateConvexPolygonCollider(barrierUnaligned, spaceOffsetX, spaceOffsetY, "Barrier")
- Logger.Info(fmt.Sprintf("Added barrier: shape=%v", barrierCollider.Shape))
+ Logger.Info(fmt.Sprintf("Added barrier: shape=%v", ConvexPolygonStr(barrierCollider.Shape.(*resolv.ConvexPolygon))))
space.Add(barrierCollider)
barrierLocalId++
}
@@ -57,22 +58,22 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
moveToCollide := true
if moveToCollide {
+ proposedDx, proposedDy := -50.0, -60.0
effPushback := Vec2D{X: float64(0), Y: float64(0)}
toTestPlayerCollider := playerColliders[0]
- toTestPlayerCollider.X += -50.0
- toTestPlayerCollider.Y += -60.0
+ toTestPlayerCollider.X += proposedDx
+ toTestPlayerCollider.Y += proposedDy
toTestPlayerCollider.Update()
- oldDx, oldDy := float64(0), float64(0)
- if collision := toTestPlayerCollider.Check(oldDx, oldDy); collision != nil {
+ if collision := toTestPlayerCollider.Check(0, 0); collision != nil {
playerShape := toTestPlayerCollider.Shape.(*resolv.ConvexPolygon)
for _, obj := range collision.Objects {
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
- if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(oldDx, oldDy, playerShape, barrierShape); overlapped {
- Logger.Info(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
+ if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape); overlapped {
+ Logger.Warn(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
effPushback.X += pushbackX
effPushback.Y += pushbackY
} else {
- Logger.Info(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), overlapResult))
+ Logger.Warn(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), overlapResult))
}
}
toTestPlayerCollider.X -= effPushback.X
diff --git a/dnmshared/resolv_helper.go b/dnmshared/resolv_helper.go
index afe38c5..306d654 100644
--- a/dnmshared/resolv_helper.go
+++ b/dnmshared/resolv_helper.go
@@ -12,14 +12,15 @@ import (
func ConvexPolygonStr(body *resolv.ConvexPolygon) string {
var s []string = make([]string, len(body.Points))
for i, p := range body.Points {
- s[i] = fmt.Sprintf("[%v, %v]", p[0]+body.X, p[1]+body.Y)
+ s[i] = fmt.Sprintf("[%.2f, %.2f]", p[0]+body.X, p[1]+body.Y)
}
- return fmt.Sprintf("[%s]", strings.Join(s, ", "))
+ return fmt.Sprintf("{\n%s\n}", strings.Join(s, ",\n"))
}
func GenerateRectCollider(origX, origY, w, h, spaceOffsetX, spaceOffsetY float64, tag string) *resolv.Object {
- collider := resolv.NewObject(origX-w*0.5+spaceOffsetX, origY-h*0.5+spaceOffsetY, w, h, tag)
+ cx, cy := WorldToPolygonColliderAnchorPos(origX, origY, w*0.5, h*0.5, spaceOffsetX, spaceOffsetY)
+ collider := resolv.NewObject(cx, cy, w, h, tag)
shape := resolv.NewRectangle(0, 0, w, h)
collider.SetShape(shape)
return collider
@@ -219,3 +220,36 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, re
// the specified unit vector "e" doesn't separate "a" and "b", overlap result is generated
return false
}
+
+func WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio float64) (int32, int32) {
+ // [WARNING] Introduces loss of precision!
+ // 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(math.Round(wx * worldToVirtualGridRatio))
+ var virtualGridY int32 = int32(math.Round(wy * worldToVirtualGridRatio))
+ return virtualGridX, virtualGridY
+}
+
+func VirtualGridToWorldPos(vx, vy int32, virtualGridToWorldRatio float64) (float64, float64) {
+ // No loss of precision
+ var wx float64 = float64(vx) * virtualGridToWorldRatio
+ var wy float64 = float64(vy) * virtualGridToWorldRatio
+ return wx, wy
+}
+
+func WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
+ return wx - halfBoundingW + collisionSpaceOffsetX, wy - halfBoundingH + collisionSpaceOffsetY
+}
+
+func PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
+ return cx + halfBoundingW - collisionSpaceOffsetX, cy + halfBoundingH - collisionSpaceOffsetY
+}
+
+func PolygonColliderAnchorToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
+ wx, wy := PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
+ return WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio)
+}
+
+func VirtualGridToPolygonColliderAnchorPos(vx, vy int32, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
+ wx, wy := VirtualGridToWorldPos(vx, vy, virtualGridToWorldRatio)
+ return WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
+}
diff --git a/frontend/assets/resources/map/simple/map.tmx b/frontend/assets/resources/map/simple/map.tmx
index 16b49c2..7f28144 100644
--- a/frontend/assets/resources/map/simple/map.tmx
+++ b/frontend/assets/resources/map/simple/map.tmx
@@ -17,7 +17,7 @@
- eJztwQENAAAAwqD3T20ON6AAAAAAAAAAAADg3wAnEAAB
+ eJzt1jEKgDAQRNE0GtD739fGaQIhqJHdCf81aSz2oyspBQAAAADWcUYPMIEaaugU37TvwbGl9y05tYz2wWFfaMiBhhyNKzRs99n7lzo0SG1OcWqQtsWxQdSwD57L3CCjO4dDg7zd+Yye7nxmajlCp5jD6Y4OAAAA4H8XE6wBrA==
diff --git a/frontend/assets/resources/prefabs/Pacman1.prefab b/frontend/assets/resources/prefabs/Pacman1.prefab
index 7d5723c..bf52f5a 100644
--- a/frontend/assets/resources/prefabs/Pacman1.prefab
+++ b/frontend/assets/resources/prefabs/Pacman1.prefab
@@ -100,7 +100,7 @@
"__id__": 1
},
"_children": [],
- "_active": false,
+ "_active": true,
"_components": [
{
"__id__": 3
@@ -119,8 +119,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
- "width": 93.36,
- "height": 40
+ "width": 46.68,
+ "height": 27.72
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -132,7 +132,7 @@
"ctor": "Float64Array",
"array": [
-5,
- 101,
+ 50,
0,
0,
0,
@@ -164,12 +164,16 @@
"__id__": 2
},
"_enabled": true,
- "_materials": [],
+ "_materials": [
+ {
+ "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+ }
+ ],
"_useOriginalSize": false,
"_string": "(0, 0)",
"_N$string": "(0, 0)",
- "_fontSize": 40,
- "_lineHeight": 40,
+ "_fontSize": 20,
+ "_lineHeight": 22,
"_enableWrapText": true,
"_N$file": null,
"_isSystemFontUsed": true,
@@ -557,15 +561,13 @@
},
"_enabled": true,
"animComp": null,
- "baseSpeed": 50,
- "speed": 50,
"lastMovedAt": 0,
- "eps": 0.1,
- "magicLeanLowerBound": 0.414,
- "magicLeanUpperBound": 2.414,
"arrowTipNode": {
"__id__": 8
},
+ "coordLabel": {
+ "__id__": 3
+ },
"_id": ""
},
{
diff --git a/frontend/assets/resources/prefabs/Pacman2.prefab b/frontend/assets/resources/prefabs/Pacman2.prefab
index cc5b6c8..b6d4472 100644
--- a/frontend/assets/resources/prefabs/Pacman2.prefab
+++ b/frontend/assets/resources/prefabs/Pacman2.prefab
@@ -100,7 +100,7 @@
"__id__": 1
},
"_children": [],
- "_active": false,
+ "_active": true,
"_components": [
{
"__id__": 3
@@ -119,8 +119,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
- "width": 93.36,
- "height": 40
+ "width": 46.68,
+ "height": 27.72
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -132,7 +132,7 @@
"ctor": "Float64Array",
"array": [
-5,
- 101,
+ 50,
0,
0,
0,
@@ -164,12 +164,16 @@
"__id__": 2
},
"_enabled": true,
- "_materials": [],
+ "_materials": [
+ {
+ "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+ }
+ ],
"_useOriginalSize": false,
"_string": "(0, 0)",
"_N$string": "(0, 0)",
- "_fontSize": 40,
- "_lineHeight": 40,
+ "_fontSize": 20,
+ "_lineHeight": 22,
"_enableWrapText": true,
"_N$file": null,
"_isSystemFontUsed": true,
@@ -557,15 +561,13 @@
},
"_enabled": true,
"animComp": null,
- "baseSpeed": 50,
- "speed": 50,
"lastMovedAt": 0,
- "eps": 0.1,
- "magicLeanLowerBound": 0.414,
- "magicLeanUpperBound": 2.414,
"arrowTipNode": {
"__id__": 8
},
+ "coordLabel": {
+ "__id__": 3
+ },
"_id": ""
},
{
diff --git a/frontend/assets/scripts/BasePlayer.js b/frontend/assets/scripts/BasePlayer.js
index 8f1b5ea..bded266 100644
--- a/frontend/assets/scripts/BasePlayer.js
+++ b/frontend/assets/scripts/BasePlayer.js
@@ -6,30 +6,10 @@ module.export = cc.Class({
type: cc.Animation,
default: null,
},
- baseSpeed: {
- type: cc.Float,
- default: 50,
- },
- speed: {
- type: cc.Float,
- default: 50
- },
lastMovedAt: {
type: cc.Float,
default: 0 // In "GMT milliseconds"
- },
- eps: {
- default: 0.10,
- type: cc.Float
- },
- magicLeanLowerBound: {
- default: 0.414, // Tangent of (PI/8).
- type: cc.Float
- },
- magicLeanUpperBound: {
- default: 2.414, // Tangent of (3*PI/8).
- type: cc.Float
- },
+ }
},
// LIFE-CYCLE CALLBACKS:
@@ -70,7 +50,7 @@ module.export = cc.Class({
this.activeDirection = newScheduledDirection;
this.activeDirection = newScheduledDirection;
const clipKey = newScheduledDirection.dx.toString() + newScheduledDirection.dy.toString();
- const clips = (this.attacked ? this.attackedClips : this.clips);
+ const clips = (this.attacked ? this.attackedClips : this.clips);
let clip = clips[clipKey];
if (!clip) {
// Keep playing the current anim.
@@ -86,11 +66,9 @@ module.export = cc.Class({
}
},
- update(dt) {
- },
+ update(dt) {},
- lateUpdate(dt) {
- },
+ lateUpdate(dt) {},
_generateRandomDirection() {
return ALL_DISCRETE_DIRECTIONS_CLOCKWISE[Math.floor(Math.random() * ALL_DISCRETE_DIRECTIONS_CLOCKWISE.length)];
@@ -117,16 +95,16 @@ module.export = cc.Class({
updateSpeed(proposedSpeed) {
if (0 == proposedSpeed && 0 < this.speed) {
- this.startFrozenDisplay();
- }
+ this.startFrozenDisplay();
+ }
if (0 < proposedSpeed && 0 == this.speed) {
- this.stopFrozenDisplay();
- }
- this.speed = proposedSpeed;
+ this.stopFrozenDisplay();
+ }
+ this.speed = proposedSpeed;
},
startFrozenDisplay() {
- const self = this;
+ const self = this;
self.attacked = true;
},
diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js
index 65e15de..f195b07 100644
--- a/frontend/assets/scripts/Map.js
+++ b/frontend/assets/scripts/Map.js
@@ -352,6 +352,8 @@ cc.Class({
window.mapIns = self;
window.forceBigEndianFloatingNumDecoding = self.forceBigEndianFloatingNumDecoding;
+ self.showCriticalCoordinateLabels = true;
+
console.warn("+++++++ Map onLoad()");
window.handleClientSessionError = function() {
console.warn('+++++++ Common handleClientSessionError()');
@@ -473,9 +475,36 @@ cc.Class({
const x0 = boundaryObj[0].x,
y0 = boundaryObj[0].y;
let pts = [];
- // TODO: Simplify this redundant coordinate conversion within "extractBoundaryObjects", but since this routine is only called once per battle, not urgent.
for (let i = 0; i < boundaryObj.length; ++i) {
- pts.push([boundaryObj[i].x - x0, boundaryObj[i].y - y0]);
+ const dx = boundaryObj[i].x - x0;
+ const dy = boundaryObj[i].y - y0;
+ pts.push([dx, dy]);
+ if (self.showCriticalCoordinateLabels) {
+ 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;
+ }
+ barrierVertLabelNode.setPosition(cc.v2(x0+0.95*dx, y0+0.5*dy));
+ const barrierVertLabel = barrierVertLabelNode.addComponent(cc.Label);
+ barrierVertLabel.fontSize = 20;
+ barrierVertLabel.lineHeight = 22;
+ barrierVertLabel.string = `(${boundaryObj[i].x.toFixed(1)}, ${boundaryObj[i].y.toFixed(1)})`;
+ safelyAddChild(self.node, barrierVertLabelNode);
+ setLocalZOrder(barrierVertLabelNode, 5);
+
+ barrierVertLabelNode.active = true;
+ }
}
const newBarrier = self.collisionSys.createPolygon(x0, y0, pts);
// console.log("Created barrier: ", newBarrier);
diff --git a/frontend/assets/scripts/SelfPlayer.js b/frontend/assets/scripts/SelfPlayer.js
index 9025a24..33ab8cf 100644
--- a/frontend/assets/scripts/SelfPlayer.js
+++ b/frontend/assets/scripts/SelfPlayer.js
@@ -1,4 +1,4 @@
-const BasePlayer = require("./BasePlayer");
+const BasePlayer = require("./BasePlayer");
cc.Class({
extends: BasePlayer,
@@ -7,6 +7,10 @@ cc.Class({
arrowTipNode: {
type: cc.Node,
default: null
+ },
+ coordLabel: {
+ type: cc.Label,
+ default: null
}
},
start() {
@@ -34,7 +38,7 @@ cc.Class({
return;
}
self.arrowTipNode.active = true;
- window.setTimeout(function(){
+ window.setTimeout(function() {
if (null == self.arrowTipNode) {
return;
}
@@ -44,6 +48,9 @@ cc.Class({
update(dt) {
BasePlayer.prototype.update.call(this, dt);
+ if (this.mapIns.showCriticalCoordinateLabels) {
+ this.coordLabel.string = `(${this.node.x.toFixed(2)}, ${this.node.y.toFixed(2)})`;
+ }
},
});
diff --git a/frontend/assets/scripts/TileCollisionManagerSingleton.js b/frontend/assets/scripts/TileCollisionManagerSingleton.js
index 560f38a..e8181a0 100644
--- a/frontend/assets/scripts/TileCollisionManagerSingleton.js
+++ b/frontend/assets/scripts/TileCollisionManagerSingleton.js
@@ -371,8 +371,8 @@ TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNo
const tilesElListUnderTilesets = {};
for (let tsxFilenameIdx = 0; tsxFilenameIdx < tsxFileNames.length; ++tsxFilenameIdx) {
const tsxOrientation = tileSets[tsxFilenameIdx].orientation;
- if (cc.TiledMap.Orientation.ORTHO != tsxOrientation) {
- cc.error("Error at tileset %s: We proceed with ONLY tilesets in ORTHO orientation for all map orientations by now.", tsxFileNames[tsxFilenameIdx]);
+ if (cc.TiledMap.Orientation.ORTHO == tsxOrientation) {
+ cc.error("Error at tileset %s: We don't proceed with tilesets in ORTHO orientation by now.", tsxFileNames[tsxFilenameIdx]);
continue;
};