From 8d989d543a658d7a72e373253c1b63ce0eba6f55 Mon Sep 17 00:00:00 2001 From: genxium Date: Sun, 11 Dec 2022 17:26:55 +0800 Subject: [PATCH] Improved offline map for code abstraction and testing. --- frontend/assets/resources/map/dungeon/map.tmx | 137 +++++++++++------- .../prefabs/ControlledCharacter.prefab | 22 +-- frontend/assets/scenes/offline_map_1.fire | 2 +- frontend/assets/scripts/Map.js | 1 - frontend/assets/scripts/OfflineMap.js | 30 ++-- .../scripts/TileCollisionManagerSingleton.js | 30 ++-- 6 files changed, 136 insertions(+), 86 deletions(-) diff --git a/frontend/assets/resources/map/dungeon/map.tmx b/frontend/assets/resources/map/dungeon/map.tmx index e970d9c..b257153 100644 --- a/frontend/assets/resources/map/dungeon/map.tmx +++ b/frontend/assets/resources/map/dungeon/map.tmx @@ -1,11 +1,11 @@ - + - eJzt2zFv2kAYgGFElCVD1AytlL1b/0mGKlPHTvkn3Tt27NT+zxoJJHqysXGMv/N9z/BMRsjc6zsOMHe73e4OAAAAAAAAAAAAAAAAAABmeDiKPg/W83bm1P8toegOkf33R6f+3zsvA/YN0v///kP0b895/5eR/g8VtNL/dv376N+2w2v/eNQ3NuWaEN1K/3X7Z6C//tEdIvvfzxDdTH/99ddf/5j+NdBff/31119//bfV/+fExz0d6d9W/z+d3wPHDr8//+181T+8/9wxPX2n+OOd9Ndff/0P5/Jc0L/9/s9Ff/Nff/3j+38YsWT/c/rH9h/r3tf/V+fblU797f/q6T+1/evO/n8rpvaf2n6v/6aM9e9r/KXzONC+7F96vZL+cf372j+eKbvfov+nzmf9q+l/ad0/7780/evtP2ePeC391+8/5Roox3LJvmOW7L+voEWN/Zca40vmtNe/nf7R9M99Deivv/76R7eI6h89/tGyf/6LHv9o+uemf27656Z/bvrnpn9u+uemf27656Z/bvrnpn9u+uemf27656b/fE+F6Jb6b7t/+XylW9yjpn89/c3/uvuPzc/olvqvO/9boP+6als73P89ruX/BOifm/7jc3/o2Nh+cAt7Qu//l9u3tt7rf938b132/hn/86n/evO/9j2B/uv3n0P/9fpveT+vf13zv3b656Z/btn7E98BAAAAAAAAAAAAAAAAWN8/Hh2Hvw== + eJzt3D9v00AYwGErFUuHigqB1J0Bic+BhDqgTnRj6gdBYmdkZILviSNiFKwkTlz73rPfZ3gUKcmQ3O/sXP5crpqmuQIAAAAAAAAAAAAAAAAAgBGud6IfB+U87en6PyUU3SGy/2an6/+ldX/EZoX0/7//Mfqvz37/+4H+1xW00n++/ofov27b5/5659DY9M8J0a30L9s/A/31j+4Q2f/FCNHN9Ndff/31j+lfA/31119//fXXf1n9v595v9sd/dfV/1fr55Hbtt8//2590j+8/9gx7T5T/PZM+uuvv/7bx3LXo//6+9/1+jv+9dc/vv/LAVP236d/bP+h7of6/2h9vlDX3/qvnv7ntn9orP+X4tz+57bf6L8oQ/0PNX7fujnSvt+/7+FC+sf1P9T+Zk+/+xz937Te6l9N/1Pn/f3+U9O/3v5j1oiX0r98/3PmQH8sp+w7ZMr+mwpa1Nh/qjE+ZUx7/dfTP5r+ueeA/vrrr390i6j+0eMfLfv7v+jxj6Z/bvrnpn9u+uemf27656Z/bvrnpn9u+uemf27656Z/bvrnpn9u+o/3qie6pf7L7n87YI7fqOlfT3/Hf939+731XzbrP/1Lj/ex1/bI/psKWtTc/3HnY9N8/fD38t91j4Ht9C/Tv+ve182D6Ib6z9f/1N6gofdrkef1S/pHd6i1f9f53TPUvodM/3nVvo8we/+593zWvpc0e/9Sx3+nts+J9C/bv5sDl9K/XP8p1/Nj/ttH/3Uf/yX/30n/ZfYvNQ/0zy17f+I7AAAAAAAAAAAAAAAAAOX9ARz6kGc= @@ -164,77 +164,110 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + - - + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/assets/resources/prefabs/ControlledCharacter.prefab b/frontend/assets/resources/prefabs/ControlledCharacter.prefab index 0bee135..915d81b 100644 --- a/frontend/assets/resources/prefabs/ControlledCharacter.prefab +++ b/frontend/assets/resources/prefabs/ControlledCharacter.prefab @@ -65,7 +65,7 @@ "ctor": "Float64Array", "array": [ 0, - 3, + 0, 0, 0, 0, @@ -97,7 +97,7 @@ "__id__": 1 }, "_children": [], - "_active": true, + "_active": false, "_components": [ { "__id__": 3 @@ -116,8 +116,8 @@ }, "_contentSize": { "__type__": "cc.Size", - "width": 46.68, - "height": 27.72 + "width": 28.01, + "height": 15.12 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -129,7 +129,7 @@ "ctor": "Float64Array", "array": [ 0, - 0, + 20, 0, 0, 0, @@ -169,8 +169,8 @@ "_useOriginalSize": false, "_string": "(0, 0)", "_N$string": "(0, 0)", - "_fontSize": 20, - "_lineHeight": 22, + "_fontSize": 12, + "_lineHeight": 12, "_enableWrapText": true, "_N$file": null, "_isSystemFontUsed": true, @@ -395,8 +395,8 @@ }, "_contentSize": { "__type__": "cc.Size", - "width": 76, - "height": 84 + "width": 24, + "height": 24 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -408,7 +408,7 @@ "ctor": "Float64Array", "array": [ 3, - 182, + 20, 0, 0, 0, @@ -451,7 +451,7 @@ "__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821" }, "_type": 0, - "_sizeMode": 1, + "_sizeMode": 0, "_fillType": 0, "_fillCenter": { "__type__": "cc.Vec2", diff --git a/frontend/assets/scenes/offline_map_1.fire b/frontend/assets/scenes/offline_map_1.fire index 4acd2a3..1e5c272 100644 --- a/frontend/assets/scenes/offline_map_1.fire +++ b/frontend/assets/scenes/offline_map_1.fire @@ -454,7 +454,7 @@ "array": [ 0, 0, - 216.50635094610968, + 217.365603642227, 0, 0, 0, diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index b748d62..dcdb91f 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -273,7 +273,6 @@ cc.Class({ const self = this; const mapNode = self.node; const canvasNode = mapNode.parent; - [self.gravityX, self.gravityY] = self.worldToVirtualGridPos(0 / self.serverFps, -9.8 / self.serverFps); // Clearing previous info of all players. [BEGINS] self.collisionPlayerIndexPrefix = (1 << 17); // For tracking the movements of players diff --git a/frontend/assets/scripts/OfflineMap.js b/frontend/assets/scripts/OfflineMap.js index e85745b..b754585 100644 --- a/frontend/assets/scripts/OfflineMap.js +++ b/frontend/assets/scripts/OfflineMap.js @@ -2,12 +2,6 @@ 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'); -/* -[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, this "snapIntoPlatformOverlap" should be small enough such that the jumping initial "velY" can escape from it by 1 renderFrame (when jumping is triggered, the character is waived from snappig for 1 renderFrame). -*/ -const snapIntoPlatformOverlap = 0.1; cc.Class({ extends: OnlineMap, @@ -19,7 +13,7 @@ cc.Class({ onLoad() { const self = this; window.mapIns = self; - self.showCriticalCoordinateLabels = true; + self.showCriticalCoordinateLabels = false; cc.director.getCollisionManager().enabled = false; @@ -75,6 +69,16 @@ cc.Class({ } }; + /* + [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 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 = 5 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame) + [self.gravityX, self.gravityY] = [0, -Math.ceil(4*self.jumpingInitVelY/self.serverFps)]; // unit: (virtual grid length/renderFrame^2) + const tiledMapIns = self.node.getComponent(cc.TiledMap); const fullPathOfTmxFile = cc.js.formatStr("map/%s/map", "dungeon"); @@ -115,7 +119,7 @@ cc.Class({ return [p.x, p.y]; })); - if (self.showCriticalCoordinateLabels) { + if (false && self.showCriticalCoordinateLabels) { for (let i = 0; i < boundaryObj.length; ++i) { const barrierVertLabelNode = new cc.Node(); switch (i % 4) { @@ -407,7 +411,7 @@ cc.Class({ && characStateIsInterruptWaivable ) { - thatPlayerInNextFrame.velY = currPlayerDownsync.speed * 4.5; + thatPlayerInNextFrame.velY = self.jumpingInitVelY; jumpTriggered[joinIndex - 1] = true; console.log(`playerId=${playerId}, joinIndex=${joinIndex} triggered a rising-edge of btnB at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}, nextVelY=${thatPlayerInNextFrame.velY}, characStateAlreadyInAir=${characStateAlreadyInAir}, characStateIsInterruptWaivable=${characStateIsInterruptWaivable}`); } @@ -471,11 +475,13 @@ cc.Class({ let [pushbackX, pushbackY] = [result2.overlap * result2.overlap_x, result2.overlap * result2.overlap_y]; if (null == potential.data) { // "null == potential.data" implies a barrier - const remainsNotInAir = (!currPlayerDownsync.inAir); - const localFallStopping = (currPlayerDownsync.inAir && 0 > pushbackY); // prevents false fall-stopping on the lateral sides + const normAlignmentWithGravity = (result2.overlap_x * 0 + result2.overlap_y * (-1.0)); + const flatEnough = (self.snapIntoPlatformThreshold < normAlignmentWithGravity); // prevents false snapping on the lateral sides + const remainsNotInAir = (!currPlayerDownsync.inAir && flatEnough); + const localFallStopping = (currPlayerDownsync.inAir && flatEnough); if (remainsNotInAir || localFallStopping) { fallStopping |= localFallStopping; - [pushbackX, pushbackY] = [(result2.overlap - snapIntoPlatformOverlap) * result2.overlap_x, (result2.overlap - snapIntoPlatformOverlap) * result2.overlap_y] + [pushbackX, pushbackY] = [(result2.overlap - self.snapIntoPlatformOverlap) * result2.overlap_x, (result2.overlap - self.snapIntoPlatformOverlap) * result2.overlap_y] // [overlay_x, overlap_y] is the unit vector that points into the platform; FIXME: Should only assign to [snappedIntoPlatformEx, snappedIntoPlatformEy] at most once! snappedIntoPlatformEx = -result2.overlap_y; snappedIntoPlatformEy = result2.overlap_x; diff --git a/frontend/assets/scripts/TileCollisionManagerSingleton.js b/frontend/assets/scripts/TileCollisionManagerSingleton.js index 80a2f17..2487371 100644 --- a/frontend/assets/scripts/TileCollisionManagerSingleton.js +++ b/frontend/assets/scripts/TileCollisionManagerSingleton.js @@ -123,21 +123,33 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod if (0 < gid) { continue; } - const polylinePoints = object.polylinePoints; - if (null == polylinePoints) { - continue - } const boundaryType = object.boundary_type; - let toPushBarriers = []; - toPushBarriers.boundaryType = boundaryType; + let toPushBarrier = []; + toPushBarrier.boundaryType = boundaryType; switch (boundaryType) { case "barrier": + let polylinePoints = object.polylinePoints; + if (null == polylinePoints) { + polylinePoints = [{ + x: 0, + y: 0 + }, { + x: object.width, + y: 0 + }, { + x: object.width, + y: -object.height + }, { + x: 0, + y: -object.height + }]; + } for (let k = 0; k < polylinePoints.length; ++k) { /* Since CocosCreatorv2.1.3, the Y-coord of object polylines is inverted compared to that of the tmx file. */ - toPushBarriers.push(this.continuousObjLayerVecToContinuousMapNodeVec(withTiledMapNode, cc.v2(polylinePoints[k].x, -polylinePoints[k].y))); + toPushBarrier.push(this.continuousObjLayerVecToContinuousMapNodeVec(withTiledMapNode, cc.v2(polylinePoints[k].x, -polylinePoints[k].y))); } - toPushBarriers.anchor = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset); // DON'T use "(object.x, object.y)" which are wrong/meaningless! - toRet.barriers.push(toPushBarriers); + toPushBarrier.anchor = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset); // DON'T use "(object.x, object.y)" which are wrong/meaningless! + toRet.barriers.push(toPushBarrier); break; default: break;