@@ -1285,17 +1285,23 @@ class PlayState extends MusicBeatState
12851285 if (updateIconPositions != null )
12861286 updateIconPositions ();
12871287
1288- if (startingSong )
1289- {
1290- if (startedCountdown )
1291- {
1288+ if (startingSong ) {
1289+ if (startedCountdown ) {
12921290 Conductor .songPosition + = Conductor .songOffset + elapsed * 1000 ;
12931291 if (Conductor .songPosition >= 0 )
12941292 startSong ();
12951293 }
12961294 } else if (FlxG .sound .music != null ) {
12971295 var instTime = FlxG .sound .music .time ;
1298- var isOffsync = vocals .time != instTime || [for (strumLine in strumLines .members ) strumLine .vocals .time != instTime ].contains (true );
1296+ var isOffsync : Bool = vocals .time != instTime ;
1297+ if (! isOffsync ) {
1298+ for (strumLine in strumLines .members ) {
1299+ if (strumLine .vocals .time != instTime ) {
1300+ isOffsync = true ;
1301+ break ;
1302+ }
1303+ }
1304+ }
12991305 __vocalOffsetViolation = Math .max (0 , __vocalOffsetViolation + (isOffsync ? elapsed : - elapsed / 2 ));
13001306 if (__vocalOffsetViolation > 25 ) {
13011307 resyncVocals ();
@@ -1309,31 +1315,17 @@ class PlayState extends MusicBeatState
13091315 if (controls. PAUSE && startedCountdown && canPause )
13101316 pauseGame ();
13111317
1312- if (generatedMusic && strumLines .members [curCameraTarget ] != null )
1313- {
1314- var pos = FlxPoint .get ();
1315- var r = 0 ;
1316- for (c in strumLines .members [curCameraTarget ].characters ) {
1317- if (c == null || ! c .visible ) continue ;
1318- var cpos = c .getCameraPosition ();
1319- pos .x + = cpos .x ;
1320- pos .y + = cpos .y ;
1321- r ++ ;
1322- // cpos.put();
1323- }
1324- if (r > 0 ) {
1325- pos .x / = r ;
1326- pos .y / = r ;
1327-
1328- var event = scripts .event (" onCameraMove" , EventManager .get (CamMoveEvent ).recycle (pos , strumLines .members [curCameraTarget ], r ));
1318+ if (generatedMusic && strumLines .members [curCameraTarget ] != null ) {
1319+ var data : CamPosData = getStrumlineCamPos (curCameraTarget );
1320+ if (data .amount > 0 ) {
1321+ var event = scripts .event (" onCameraMove" , EventManager .get (CamMoveEvent ).recycle (data .pos , strumLines .members [curCameraTarget ], data .amount ));
13291322 if (! event .cancelled )
1330- camFollow .setPosition (pos . x , pos .y );
1323+ camFollow .setPosition (event . position . x , event . position .y );
13311324 }
1332- pos .put ();
1325+ data .put ();
13331326 }
13341327
1335- if (camZooming )
1336- {
1328+ if (camZooming ) {
13371329 FlxG .camera .zoom = lerp (FlxG .camera .zoom , defaultCamZoom , camGameZoomLerp );
13381330 camHUD .zoom = lerp (camHUD .zoom , defaultHudZoom , camHUDZoomLerp );
13391331 }
@@ -1367,6 +1359,41 @@ class PlayState extends MusicBeatState
13671359 scripts .event (" postDraw" , e );
13681360 }
13691361
1362+ /**
1363+ * Returns the camera position of the specified strumline.
1364+ * @param strumLine The strumline to get the camera position of.
1365+ * @param pos The position to put the camera position in. If `null`, a new FlxPoint will be created.
1366+ * @param ignoreInvisible Whenever invisible characters should be ignored.
1367+ **/
1368+ public inline function getStrumlineCamPos (strumLine : Int , ? pos : FlxPoint = null , ? ignoreInvisible : Bool = true ): CamPosData {
1369+ return getCharactersCamPos (strumLines .members [strumLine ].characters , pos , ignoreInvisible );
1370+ }
1371+
1372+ /**
1373+ * Returns the camera position of the specified characters.
1374+ * @param chars The characters to get the camera position of.
1375+ * @param pos The position to put the camera position in. If `null`, a new FlxPoint will be created.
1376+ * @param ignoreInvisible Whenever invisible characters should be ignored.
1377+ **/
1378+ public function getCharactersCamPos (chars : Array <Character >, ? pos : FlxPoint = null , ? ignoreInvisible : Bool = true ): CamPosData {
1379+ if (pos == null ) pos = FlxPoint .get ();
1380+ var amount = 0 ;
1381+ for (c in chars ) {
1382+ if (c == null || (ignoreInvisible && ! c .visible )) continue ;
1383+ var cpos = c .getCameraPosition ();
1384+ pos .x + = cpos .x ;
1385+ pos .y + = cpos .y ;
1386+ amount ++ ;
1387+ // cpos.put(); // not actually in the pool, so no need
1388+ }
1389+ if (amount > 0 ) {
1390+ pos .x / = amount ;
1391+ pos .y / = amount ;
1392+ }
1393+ return new CamPosData (pos , amount );
1394+ }
1395+
1396+
13701397 public var scrollSpeedTween : FlxTween = null ;
13711398
13721399 public function executeEvent (event : ChartEvent ) @:privateAccess {
@@ -1995,3 +2022,28 @@ typedef PlayStateTransitionData = {
19952022 var camFollowY : Float ;
19962023 var camZoom : Float ;
19972024}
2025+
2026+ class CamPosData {
2027+ /**
2028+ * The camera position.
2029+ **/
2030+ public var pos : FlxPoint ;
2031+ /**
2032+ * The amount of characters that was involved in the calculation.
2033+ **/
2034+ public var amount : Int ;
2035+
2036+ public function new (pos : FlxPoint , amount : Int ) {
2037+ this .pos = pos ;
2038+ this .amount = amount ;
2039+ }
2040+
2041+ /**
2042+ * Puts the position back into the pool, making it reusable.
2043+ **/
2044+ public function put () {
2045+ if (pos == null ) return ;
2046+ pos .put ();
2047+ pos = null ;
2048+ }
2049+ }
0 commit comments