@@ -95,28 +95,6 @@ var World = new Class({
9595 */
9696 this . pendingDestroy = new Set ( ) ;
9797
98- /**
99- * Dynamic Bodies that need a second `update` call to resynchronize their Game Objects.
100- * This set is filled only when the `_late` flag is on, and is processed and cleared during `postUpdate`.
101- *
102- * @name Phaser.Physics.Arcade.World#late
103- * @type {Phaser.Structs.Set.<Phaser.Physics.Arcade.Body> }
104- * @private
105- * @since 3.16.0
106- */
107- this . late = new Set ( ) ;
108-
109- /**
110- * A flag allowing the `late` set to be filled, as appropriate.
111- * This is on (true) only between `update` and `postUpdate` and false at other times.
112- *
113- * @name Phaser.Physics.Arcade.World#_late
114- * @type {boolean }
115- * @private
116- * @since 3.16.0
117- */
118- this . _late = false ;
119-
12098 /**
12199 * This simulation's collision processors.
122100 *
@@ -651,7 +629,6 @@ var World = new Class({
651629 {
652630 this . tree . remove ( body ) ;
653631 this . bodies . delete ( body ) ;
654- this . late . delete ( body ) ;
655632 }
656633 else if ( body . physicsType === CONST . STATIC_BODY )
657634 {
@@ -935,12 +912,25 @@ var World = new Class({
935912 return ;
936913 }
937914
915+ // Update all active bodies
916+ var body ;
917+ var bodies = this . bodies . entries ;
918+
919+ for ( var i = 0 ; i < bodies . length ; i ++ )
920+ {
921+ body = bodies [ i ] ;
922+
923+ if ( body . enable )
924+ {
925+ body . preUpdate ( ) ;
926+ }
927+ }
928+
938929 var stepsThisFrame = 0 ;
939930 var fixedDelta = this . _frameTime ;
940931 var msPerFrame = this . _frameTimeMS * this . timeScale ;
941932
942933 this . _elapsed += delta ;
943- this . _late = false ;
944934
945935 while ( this . _elapsed >= msPerFrame )
946936 {
@@ -952,7 +942,6 @@ var World = new Class({
952942 }
953943
954944 this . stepsLastFrame = stepsThisFrame ;
955- this . _late = true ;
956945 } ,
957946
958947 /**
@@ -1000,18 +989,6 @@ var World = new Class({
1000989 collider . update ( ) ;
1001990 }
1002991 }
1003-
1004- len = bodies . length ;
1005-
1006- for ( i = 0 ; i < len ; i ++ )
1007- {
1008- body = bodies [ i ] ;
1009-
1010- if ( body . enable )
1011- {
1012- body . postUpdate ( ) ;
1013- }
1014- }
1015992 } ,
1016993
1017994 /**
@@ -1023,38 +1000,23 @@ var World = new Class({
10231000 postUpdate : function ( )
10241001 {
10251002 var i ;
1026- var bodies ;
10271003 var body ;
1028- var len ;
1004+ var bodies = this . bodies . entries ;
1005+ var len = bodies . length ;
10291006
10301007 var dynamic = this . bodies ;
10311008 var staticBodies = this . staticBodies ;
1032- var pending = this . pendingDestroy ;
1033- var late = this . late ;
10341009
1035- if ( late . size > 0 )
1010+ for ( i = 0 ; i < len ; i ++ )
10361011 {
1037- bodies = late . entries ;
1038- len = bodies . length ;
1012+ body = bodies [ i ] ;
10391013
1040- for ( i = 0 ; i < len ; i ++ )
1014+ if ( body . enable )
10411015 {
1042- body = bodies [ i ] ;
1043-
1044- if ( body . enable )
1045- {
1046- body . postUpdate ( ) ;
1047- }
1016+ body . postUpdate ( ) ;
10481017 }
1049-
1050- late . clear ( ) ;
10511018 }
10521019
1053- this . _late = false ;
1054-
1055- bodies = dynamic . entries ;
1056- len = bodies . length ;
1057-
10581020 if ( this . drawDebug )
10591021 {
10601022 var graphics = this . debugGraphic ;
@@ -1085,6 +1047,8 @@ var World = new Class({
10851047 }
10861048 }
10871049
1050+ var pending = this . pendingDestroy ;
1051+
10881052 if ( pending . size > 0 )
10891053 {
10901054 var dynamicTree = this . tree ;
@@ -1101,7 +1065,6 @@ var World = new Class({
11011065 {
11021066 dynamicTree . remove ( body ) ;
11031067 dynamic . delete ( body ) ;
1104- late . delete ( body ) ;
11051068 }
11061069 else if ( body . physicsType === CONST . STATIC_BODY )
11071070 {
@@ -1400,18 +1363,9 @@ var World = new Class({
14001363 this . emit ( Events . OVERLAP , body1 . gameObject , body2 . gameObject , body1 , body2 ) ;
14011364 }
14021365 }
1403- else
1366+ else if ( body1 . onCollide || body2 . onCollide )
14041367 {
1405- if ( this . _late )
1406- {
1407- this . late . set ( body1 ) ;
1408- this . late . set ( body2 ) ;
1409- }
1410-
1411- if ( body1 . onCollide || body2 . onCollide )
1412- {
1413- this . emit ( Events . COLLIDE , body1 . gameObject , body2 . gameObject , body1 , body2 ) ;
1414- }
1368+ this . emit ( Events . COLLIDE , body1 . gameObject , body2 . gameObject , body1 , body2 ) ;
14151369 }
14161370 }
14171371
@@ -1612,8 +1566,8 @@ var World = new Class({
16121566 }
16131567
16141568 // sync changes back to the bodies
1615- body1 . postUpdate ( ) ;
1616- body2 . postUpdate ( ) ;
1569+ // body1.postUpdate();
1570+ // body2.postUpdate();
16171571
16181572 return true ;
16191573 } ,
@@ -2073,6 +2027,81 @@ var World = new Class({
20732027 return didCollide ;
20742028 } ,
20752029
2030+ /**
2031+ * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects.
2032+ *
2033+ * You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
2034+ * tile filtering and culling for you, as well as handle the interesting face collision automatically.
2035+ *
2036+ * This method is offered for those who would like to check for collision with specific Tiles in a layer, without
2037+ * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions
2038+ * on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
2039+ * you should filter them before passing them to this method.
2040+ *
2041+ * Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have
2042+ * say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the
2043+ * tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on
2044+ * dynamic maps, this method can prove very useful.
2045+ *
2046+ * @method Phaser.Physics.Arcade.World#collideTiles
2047+ * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
2048+ * @since 3.16.3
2049+ *
2050+ * @param {Phaser.GameObjects.GameObject } sprite - The first object to check for collision.
2051+ * @param {Phaser.Tilemaps.Tile[] } tiles - An array of Tiles to check for collision against.
2052+ * @param {ArcadePhysicsCallback } [collideCallback] - An optional callback function that is called if the objects collide.
2053+ * @param {ArcadePhysicsCallback } [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
2054+ * @param {any } [callbackContext] - The context in which to run the callbacks.
2055+ *
2056+ * @return {boolean } True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
2057+ */
2058+ collideTiles : function ( sprite , tiles , collideCallback , processCallback , callbackContext )
2059+ {
2060+ if ( ! sprite . body . enable || tiles . length === 0 )
2061+ {
2062+ return false ;
2063+ }
2064+ else
2065+ {
2066+ return this . collideSpriteVsTilesHandler ( sprite , tiles , collideCallback , processCallback , callbackContext , false , false ) ;
2067+ }
2068+ } ,
2069+
2070+ /**
2071+ * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects.
2072+ *
2073+ * You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
2074+ * tile filtering and culling for you, as well as handle the interesting face collision automatically.
2075+ *
2076+ * This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without
2077+ * having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap
2078+ * tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
2079+ * you should filter them before passing them to this method.
2080+ *
2081+ * @method Phaser.Physics.Arcade.World#overlapTiles
2082+ * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
2083+ * @since 3.16.3
2084+ *
2085+ * @param {Phaser.GameObjects.GameObject } sprite - The first object to check for collision.
2086+ * @param {Phaser.Tilemaps.Tile[] } tiles - An array of Tiles to check for collision against.
2087+ * @param {ArcadePhysicsCallback } [collideCallback] - An optional callback function that is called if the objects overlap.
2088+ * @param {ArcadePhysicsCallback } [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
2089+ * @param {any } [callbackContext] - The context in which to run the callbacks.
2090+ *
2091+ * @return {boolean } True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
2092+ */
2093+ overlapTiles : function ( sprite , tiles , collideCallback , processCallback , callbackContext )
2094+ {
2095+ if ( ! sprite . body . enable || tiles . length === 0 )
2096+ {
2097+ return false ;
2098+ }
2099+ else
2100+ {
2101+ return this . collideSpriteVsTilesHandler ( sprite , tiles , collideCallback , processCallback , callbackContext , true , false ) ;
2102+ }
2103+ } ,
2104+
20762105 /**
20772106 * Internal handler for Sprite vs. Tilemap collisions.
20782107 * Please use Phaser.Physics.Arcade.World#collide instead.
@@ -2131,13 +2160,47 @@ var World = new Class({
21312160 {
21322161 return false ;
21332162 }
2163+ else
2164+ {
2165+ return this . collideSpriteVsTilesHandler ( sprite , mapData , collideCallback , processCallback , callbackContext , overlapOnly , true ) ;
2166+ }
2167+ } ,
2168+
2169+ /**
2170+ * Internal handler for Sprite vs. Tilemap collisions.
2171+ * Please use Phaser.Physics.Arcade.World#collide instead.
2172+ *
2173+ * @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler
2174+ * @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
2175+ * @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
2176+ * @private
2177+ * @since 3.16.3
2178+ *
2179+ * @param {Phaser.GameObjects.GameObject } sprite - The first object to check for collision.
2180+ * @param {(Phaser.Tilemaps.DynamicTilemapLayer|Phaser.Tilemaps.StaticTilemapLayer) } tilemapLayer - The second object to check for collision.
2181+ * @param {ArcadePhysicsCallback } [collideCallback] - An optional callback function that is called if the objects collide.
2182+ * @param {ArcadePhysicsCallback } [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
2183+ * @param {any } [callbackContext] - The context in which to run the callbacks.
2184+ * @param {boolean } [overlapOnly] - Whether this is a collision or overlap check.
2185+ * @param {boolean } [isLayer] - Is this check coming from a TilemapLayer or an array of tiles?
2186+ *
2187+ * @return {boolean } True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
2188+ */
2189+ collideSpriteVsTilesHandler : function ( sprite , tiles , collideCallback , processCallback , callbackContext , overlapOnly , isLayer )
2190+ {
2191+ var body = sprite . body ;
21342192
21352193 var tile ;
21362194 var tileWorldRect = { left : 0 , right : 0 , top : 0 , bottom : 0 } ;
2195+ var tilemapLayer ;
2196+ var collision = false ;
21372197
2138- for ( var i = 0 ; i < mapData . length ; i ++ )
2198+ for ( var i = 0 ; i < tiles . length ; i ++ )
21392199 {
2140- tile = mapData [ i ] ;
2200+ tile = tiles [ i ] ;
2201+
2202+ tilemapLayer = tile . tilemapLayer ;
2203+
21412204 tileWorldRect . left = tilemapLayer . tileToWorldX ( tile . x ) ;
21422205 tileWorldRect . top = tilemapLayer . tileToWorldY ( tile . y ) ;
21432206
@@ -2154,28 +2217,32 @@ var World = new Class({
21542217 if ( TileIntersectsBody ( tileWorldRect , body )
21552218 && ( ! processCallback || processCallback . call ( callbackContext , sprite , tile ) )
21562219 && ProcessTileCallbacks ( tile , sprite )
2157- && ( overlapOnly || SeparateTile ( i , body , tile , tileWorldRect , tilemapLayer , this . TILE_BIAS ) ) )
2220+ && ( overlapOnly || SeparateTile ( i , body , tile , tileWorldRect , tilemapLayer , this . TILE_BIAS , isLayer ) ) )
21582221 {
21592222 this . _total ++ ;
21602223
2224+ collision = true ;
2225+
21612226 if ( collideCallback )
21622227 {
21632228 collideCallback . call ( callbackContext , sprite , tile ) ;
21642229 }
21652230
21662231 if ( overlapOnly && body . onOverlap )
21672232 {
2168- this . emit ( Events . TILE_OVERLAP , body . gameObject , tile , body ) ;
2233+ this . emit ( Events . TILE_OVERLAP , sprite , tile , body ) ;
21692234 }
21702235 else if ( body . onCollide )
21712236 {
2172- this . emit ( Events . TILE_COLLIDE , body . gameObject , tile , body ) ;
2237+ this . emit ( Events . TILE_COLLIDE , sprite , tile , body ) ;
21732238 }
21742239
21752240 // sync changes back to the body
2176- body . postUpdate ( ) ;
2241+ // body.postUpdate();
21772242 }
21782243 }
2244+
2245+ return collision ;
21792246 } ,
21802247
21812248 /**
@@ -2288,7 +2355,6 @@ var World = new Class({
22882355 this . staticTree . clear ( ) ;
22892356 this . bodies . clear ( ) ;
22902357 this . staticBodies . clear ( ) ;
2291- this . late . clear ( ) ;
22922358 this . colliders . destroy ( ) ;
22932359
22942360 this . removeAllListeners ( ) ;
0 commit comments