@@ -9,6 +9,7 @@ var CircleContains = require('../../geom/circle/Contains');
99var Class = require ( '../../utils/Class' ) ;
1010var CONST = require ( './const' ) ;
1111var Events = require ( './events' ) ;
12+ var FuzzyEqual = require ( '../../math/fuzzy/Equal' ) ;
1213var FuzzyGreaterThan = require ( '../../math/fuzzy/GreaterThan' ) ;
1314var FuzzyLessThan = require ( '../../math/fuzzy/LessThan' ) ;
1415var CheckOverlapY = require ( './CheckOverlapY' ) ;
@@ -833,6 +834,9 @@ var Body = new Class({
833834 * @since 3.17.0
834835 */
835836 this . _gy = 0 ;
837+
838+ this . _sleepX = 0 ;
839+ this . _sleepY = 0 ;
836840 } ,
837841
838842 /**
@@ -1295,35 +1299,7 @@ var Body = new Class({
12951299 gameObject . angle += this . deltaZ ( ) ;
12961300 }
12971301
1298- // Check for sleeping state
1299-
1300- var worldBlocked = this . worldBlocked ;
1301-
1302- // else if (this._sleep > 0 && !this.worldBlocked.up && !this.worldBlocked.down)
1303-
1304- if ( Math . abs ( dy ) < 1 && this . isBlocked ( ) )
1305- {
1306- if ( this . _sleep < this . sleepIterations )
1307- {
1308- this . _sleep ++ ;
1309-
1310- if ( this . _sleep >= this . sleepIterations )
1311- {
1312- this . sleep ( ) ;
1313- }
1314- }
1315- }
1316- else if ( this . _sleep > 0 && ! this . isBlockedY ( ) )
1317- {
1318- // Waking up? Do it progressively, not instantly, to ensure it isn't just a step fluctuation
1319- this . _sleep *= 0.8 ;
1320-
1321- if ( this . _sleep <= 0 )
1322- {
1323- console . log ( 'body woken from postUpdate' , dy ) ;
1324- this . wake ( ) ;
1325- }
1326- }
1302+ this . checkSleep ( dx , dy ) ;
13271303
13281304 // Store collision flags
13291305 var wasTouching = this . wasTouching ;
@@ -1342,6 +1318,61 @@ var Body = new Class({
13421318 this . prevVelocity . y = this . velocity . y ;
13431319 } ,
13441320
1321+ // return true if gravity is pulling up and body blocked up,
1322+ // or gravity is pulling down and body blocked down
1323+ isGravityBlockedY : function ( )
1324+ {
1325+ var gy = this . _gy ;
1326+
1327+ return ( ( gy < 0 && this . isBlockedUp ( ) ) || ( gy > 0 && this . isBlockedDown ( ) ) ) ;
1328+ } ,
1329+
1330+ // Check for sleeping state
1331+ checkSleep : function ( dx , dy )
1332+ {
1333+ // Can't sleep if not blocked in the opposite direction somehow
1334+
1335+ dx = Math . abs ( dx ) ;
1336+ dy = Math . abs ( dy ) ;
1337+
1338+ if ( ! this . sleeping && this . isGravityBlockedY ( ) )
1339+ {
1340+ // Falling asleep?
1341+
1342+ if ( dy < 1 && FuzzyEqual ( dy , this . _sleepY , 0.1 ) )
1343+ {
1344+ if ( this . _sleep < this . sleepIterations )
1345+ {
1346+ this . _sleep ++ ;
1347+
1348+ if ( this . _sleep >= this . sleepIterations )
1349+ {
1350+ this . sleep ( ) ;
1351+ }
1352+ }
1353+ }
1354+ }
1355+ else if ( this . sleeping && ! this . isGravityBlockedY ( ) )
1356+ {
1357+ // Waking up?
1358+
1359+ if ( this . _sleep > 0 )
1360+ {
1361+ // Do it progressively, not instantly, to ensure it isn't just a step fluctuation
1362+ this . _sleep -= ( this . sleepIterations * 0.1 ) ;
1363+
1364+ if ( this . _sleep <= 0 )
1365+ {
1366+ console . log ( 'body woken from postUpdate' , dy ) ;
1367+ this . wake ( ) ;
1368+ }
1369+ }
1370+ }
1371+
1372+ this . _sleepX = dx ;
1373+ this . _sleepY = dy ;
1374+ } ,
1375+
13451376 /**
13461377 * Checks for collisions between this Body and the world boundary and separates them.
13471378 *
@@ -2071,7 +2102,7 @@ var Body = new Class({
20712102 this . y = by . bottom ;
20722103 this . forcePosition = true ;
20732104
2074- if ( this . bounce . y === 0 )
2105+ if ( this . bounce . y === 0 && this . isGravityBlockedY ( ) )
20752106 {
20762107 this . velocity . y = 0 ;
20772108 }
@@ -2094,7 +2125,7 @@ var Body = new Class({
20942125 this . bottom = by . y ;
20952126 this . forcePosition = true ;
20962127
2097- if ( this . bounce . y === 0 )
2128+ if ( this . bounce . y === 0 && this . isGravityBlockedY ( ) )
20982129 {
20992130 this . velocity . y = 0 ;
21002131 }
@@ -2233,14 +2264,15 @@ var Body = new Class({
22332264 return ( this . blocked . down || this . worldBlocked . down ) ;
22342265 } ,
22352266
2267+ // Is this body world blocked AND blocked on the opposite face?
22362268 isBlockedY : function ( )
22372269 {
22382270 var blocked = this . blocked ;
22392271 var worldBlocked = this . worldBlocked ;
22402272
22412273 return (
2242- ( blocked . up || worldBlocked . up ) &&
2243- ( blocked . down || worldBlocked . down )
2274+ ( worldBlocked . down && blocked . up ) ||
2275+ ( worldBlocked . up && blocked . down )
22442276 ) ;
22452277 } ,
22462278
0 commit comments