Optimize Note & Strum Rendering (#941)
* optimize * Delete the unnecessary * Delete __posPoint * 更新 Note.hx * @:dox(hide) * 更新 Strum.hx * Fix the bug
This commit is contained in:
+80
-37
@@ -126,8 +126,7 @@ class Note extends FlxSprite
|
||||
|
||||
static var DEFAULT_FIELDS:Array<String> = ["time", "id", "type", "sLen"];
|
||||
|
||||
public function new(strumLine:StrumLine, noteData:ChartNote, sustain:Bool = false, sustainLength:Float = 0, sustainOffset:Float = 0, ?prev:Note)
|
||||
{
|
||||
public function new(strumLine:StrumLine, noteData:ChartNote, sustain:Bool = false, sustainLength:Float = 0, sustainOffset:Float = 0, ?prev:Note) {
|
||||
super();
|
||||
|
||||
moves = false;
|
||||
@@ -241,23 +240,13 @@ class Note extends FlxSprite
|
||||
*/
|
||||
public var strumRelativePos:Bool = true;
|
||||
|
||||
override function drawComplex(camera:FlxCamera) {
|
||||
var downscrollCam = (camera is HudCamera ? ({var _:HudCamera=cast camera;_;}).downscroll : false);
|
||||
if (updateFlipY) flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
|
||||
if (downscrollCam && __strum != null) {
|
||||
final xx = x;
|
||||
x += origin.x - offset.x;
|
||||
x -= __strum.x; x *= -1; x += __strum.x;
|
||||
x -= origin.x - offset.x;
|
||||
x += __strum.width; // ??? maybe this isnt good
|
||||
super.drawComplex(camera);
|
||||
x = xx;
|
||||
} else
|
||||
super.drawComplex(camera);
|
||||
}
|
||||
|
||||
static var __notePosFrameOffset:FlxPoint = new FlxPoint();
|
||||
static var __posPoint:FlxPoint = new FlxPoint();
|
||||
@:dox(hide) static var __lastAngle:Float = Math.NaN;
|
||||
@:dox(hide) static var __lastAngleSin:Float = 0;
|
||||
@:dox(hide) static var __lastAngleCos:Float = 0;
|
||||
@:dox(hide) static var __lastStrumW:Float = Math.NaN;
|
||||
@:dox(hide) static var __lastStrumH:Float = Math.NaN;
|
||||
@:dox(hide) static var __lastStrumHalfW:Float = 0;
|
||||
@:dox(hide) static var __lastStrumHalfH:Float = 0;
|
||||
|
||||
override function draw() {
|
||||
@:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
|
||||
@@ -266,16 +255,28 @@ class Note extends FlxSprite
|
||||
var negativeScroll = isSustainNote && strumRelativePos && lastScrollSpeed < 0;
|
||||
if (negativeScroll) y -= height;
|
||||
if (__strum != null && strumRelativePos) {
|
||||
final pos = __posPoint.set(x, y);
|
||||
// distance = pos.y , we can use it safely like this
|
||||
final xx = -origin.x + offset.x + (pos.y * Math.cos((__noteAngle + 90) * FlxAngle.TO_RAD));
|
||||
final yy = -origin.y + offset.y + (pos.y * Math.sin((__noteAngle + 90) * FlxAngle.TO_RAD));
|
||||
setPosition(
|
||||
xx + __strum.x + (__strum.width * 0.5),
|
||||
yy + __strum.y + (__strum.height * 0.5)
|
||||
);
|
||||
final originalX = x;
|
||||
final originalY = y;
|
||||
|
||||
if (__noteAngle != __lastAngle) {
|
||||
__lastAngle = __noteAngle;
|
||||
final result = FlxMath.fastSinCos((__noteAngle + 90) * FlxAngle.TO_RAD);
|
||||
__lastAngleSin = result.sin;
|
||||
__lastAngleCos = result.cos;
|
||||
}
|
||||
|
||||
if (__strum.width != __lastStrumW || __strum.height != __lastStrumH) {
|
||||
__lastStrumW = __strum.width;
|
||||
__lastStrumH = __strum.height;
|
||||
__lastStrumHalfW = __strum.width * 0.5;
|
||||
__lastStrumHalfH = __strum.height * 0.5;
|
||||
}
|
||||
|
||||
x = -origin.x + offset.x + (originalY * __lastAngleCos) + __strum.x + __lastStrumHalfW;
|
||||
y = -origin.y + offset.y + (originalY * __lastAngleSin) + __strum.y + __lastStrumHalfH;
|
||||
super.draw();
|
||||
setPosition(pos.x, pos.y);
|
||||
x = originalX;
|
||||
y = originalY;
|
||||
} else {
|
||||
super.draw();
|
||||
}
|
||||
@@ -284,6 +285,38 @@ class Note extends FlxSprite
|
||||
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
|
||||
}
|
||||
|
||||
var __lastDownscrollCam:Bool = false;
|
||||
var __lastX:Float = 0;
|
||||
|
||||
@:noCompletion @:dox(hide) override function isOnScreen(?camera:FlxCamera):Bool {
|
||||
var downscrollCam = (Std.isOfType(camera, HudCamera) ? cast(camera, HudCamera).downscroll : false);
|
||||
|
||||
if (downscrollCam == __lastDownscrollCam)
|
||||
return super.isOnScreen(camera);
|
||||
else
|
||||
__lastX = x;
|
||||
|
||||
if (updateFlipY) flipY = (isSustainNote && flipSustain) && (downscrollCam != (__strum != null && __strum.getScrollSpeed(this) < 0));
|
||||
if (downscrollCam && __strum != null) {
|
||||
x = -x + 2 * (__strum.x - origin.x + offset.x) + __strum.width;
|
||||
}
|
||||
final isOnScreen = super.isOnScreen(camera);
|
||||
return isOnScreen;
|
||||
}
|
||||
|
||||
override function drawComplex(camera:FlxCamera):Void {
|
||||
super.drawComplex(camera);
|
||||
|
||||
if (__lastDownscrollCam) {
|
||||
__lastDownscrollCam = false;
|
||||
x = __lastX;
|
||||
}
|
||||
}
|
||||
|
||||
public function isOnScreenOriginal(?camera:FlxCamera):Bool {
|
||||
return super.isOnScreen(camera);
|
||||
}
|
||||
|
||||
// The * 0.5 is so that it's easier to hit them too late, instead of too early
|
||||
public var earlyPressWindow:Float = 0.5;
|
||||
public var latePressWindow:Float = 1;
|
||||
@@ -294,7 +327,7 @@ class Note extends FlxSprite
|
||||
if (lastScrollSpeed != scrollSpeed) {
|
||||
lastScrollSpeed = scrollSpeed;
|
||||
if (nextSustain != null) {
|
||||
scale.y = (sustainLength * 0.45 * Math.abs(scrollSpeed)) / frameHeight;
|
||||
scale.y = (sustainLength * 0.45 * scrollSpeed) / frameHeight;
|
||||
updateHitbox();
|
||||
scale.y += gapFix / frameHeight;
|
||||
}
|
||||
@@ -304,18 +337,28 @@ class Note extends FlxSprite
|
||||
}
|
||||
|
||||
public function updateSustainClip() if (wasGoodHit && !noSustainClip) {
|
||||
var t = CoolUtil.bound((Conductor.songPosition - strumTime) / height * 0.45 * Math.abs(lastScrollSpeed), 0, 1);
|
||||
var rect = clipRect == null ? FlxRect.get() : clipRect;
|
||||
clipRect = rect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
|
||||
var t = CoolUtil.bound((Conductor.songPosition - strumTime) / height * 0.45 * lastScrollSpeed, 0, 1);
|
||||
@:bypassAccessor {
|
||||
if (clipRect == null) clipRect = FlxRect.get();
|
||||
clipRect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
|
||||
}
|
||||
@:privateAccess {
|
||||
if (frame != null && _frame != null)
|
||||
_frame = frame.clipTo(clipRect, _frame);
|
||||
}
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
override function set_clipRect(rect:FlxRect):FlxRect
|
||||
{
|
||||
clipRect = rect;
|
||||
override function set_clipRect(rect:FlxRect):FlxRect {
|
||||
@:bypassAccessor clipRect = rect;
|
||||
|
||||
if (frames != null)
|
||||
frame = frames.frames[animation.frameIndex];
|
||||
@:privateAccess if (frame != null) {
|
||||
if (rect != null && _frame != null)
|
||||
_frame = frame.clipTo(rect, _frame);
|
||||
else if (_frame != null)
|
||||
_frame = frame.copyTo(_frame);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
+66
-19
@@ -2,6 +2,7 @@ package funkin.game;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import funkin.backend.system.Conductor;
|
||||
|
||||
class Strum extends FlxSprite {
|
||||
@@ -52,8 +53,27 @@ class Strum extends FlxSprite {
|
||||
public var updateNotesPosY:Bool = true;
|
||||
public var extraCopyFields(default, set):Array<String> = [];
|
||||
|
||||
private inline function set_extraCopyFields(val:Array<String>)
|
||||
return extraCopyFields = val == null ? [] : val;
|
||||
@:noCompletion public var __cachedCopyFields:Array<Array<OneOfTwo<String, Int>>> = null;
|
||||
|
||||
private function set_extraCopyFields(val:Array<String>) {
|
||||
extraCopyFields = val == null ? [] : val;
|
||||
__cachedCopyFields = null;
|
||||
return extraCopyFields;
|
||||
}
|
||||
|
||||
private inline function __initCachedCopyFields() {
|
||||
if (__cachedCopyFields != null) return;
|
||||
__cachedCopyFields = [for (field in extraCopyFields) CoolUtil.parsePropertyString(field)];
|
||||
}
|
||||
|
||||
private inline function __applyCopyFields(daNote:Note) {
|
||||
for (i in 0...extraCopyFields.length) {
|
||||
final parsed = __cachedCopyFields[i];
|
||||
final fromProp = CoolUtil.parseProperty(this, parsed);
|
||||
final toProp = CoolUtil.parseProperty(daNote, parsed);
|
||||
toProp.setValue(fromProp.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever the strum is pressed.
|
||||
@@ -129,13 +149,28 @@ class Strum extends FlxSprite {
|
||||
}
|
||||
|
||||
public override function draw() {
|
||||
lastDrawCameras = cameras.copy();
|
||||
if (cameras.length == 1) {
|
||||
if (lastDrawCameras.length != 1 || lastDrawCameras[0] != cameras[0]) {
|
||||
lastDrawCameras = [cameras[0]];
|
||||
}
|
||||
} else {
|
||||
lastDrawCameras = cameras.copy();
|
||||
}
|
||||
super.draw();
|
||||
}
|
||||
|
||||
@:noCompletion public static inline final PIX180:Float = 565.4866776461628; // 180 * Math.PI
|
||||
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2; // DEPRECATED
|
||||
|
||||
static var __lastStrumW:Float = Math.NaN;
|
||||
static var __lastStrumH:Float = Math.NaN;
|
||||
static var __lastStrumHalfW:Float = 0;
|
||||
static var __lastStrumHalfH:Float = 0;
|
||||
static var __noteOffset:FlxPoint = FlxPoint.get();
|
||||
static var __lastNoteAngle:Float = Math.NaN;
|
||||
static var __lastAngleCos:Float = 0;
|
||||
static var __lastAngleSin:Float = 0;
|
||||
|
||||
/**
|
||||
* Updates the position of a note.
|
||||
* @param daNote The note
|
||||
@@ -153,8 +188,10 @@ class Strum extends FlxSprite {
|
||||
}
|
||||
|
||||
updateNotePos(daNote);
|
||||
for (field in extraCopyFields)
|
||||
CoolUtil.cloneProperty(daNote, field, this); // TODO: make this cached to reduce the reflection calls - Neo
|
||||
if (extraCopyFields.length > 0) {
|
||||
__initCachedCopyFields();
|
||||
__applyCopyFields(daNote);
|
||||
}
|
||||
}
|
||||
|
||||
private inline function updateNotePos(daNote:Note) {
|
||||
@@ -169,24 +206,34 @@ class Strum extends FlxSprite {
|
||||
if (daNote.isSustainNote) daNote.y += daNote.height * 0.5;
|
||||
}
|
||||
} else {
|
||||
if (width != __lastStrumW || height != __lastStrumH) {
|
||||
__lastStrumW = width;
|
||||
__lastStrumH = height;
|
||||
__lastStrumHalfW = width * 0.5;
|
||||
__lastStrumHalfH = height * 0.5;
|
||||
}
|
||||
|
||||
if (daNote.__noteAngle != __lastNoteAngle) {
|
||||
__lastNoteAngle = daNote.__noteAngle;
|
||||
final result = FlxMath.fastSinCos((__lastNoteAngle + 90) * FlxAngle.TO_RAD);
|
||||
__lastAngleCos = result.cos;
|
||||
__lastAngleSin = result.sin;
|
||||
}
|
||||
|
||||
final speed = getScrollSpeed(daNote);
|
||||
final distance = (daNote.strumTime - Conductor.songPosition) * 0.45 * speed;
|
||||
final __noteAngle = FlxMath.fastSinCos((daNote.__noteAngle + 90) * FlxAngle.TO_RAD);
|
||||
final angleX = __noteAngle.cos;
|
||||
final angleY = __noteAngle.sin;
|
||||
final _noteOffset = FlxPoint.get(angleX * distance, angleY * distance);
|
||||
_noteOffset.x += -daNote.origin.x + daNote.offset.x;
|
||||
_noteOffset.y += -daNote.origin.y + daNote.offset.y;
|
||||
__noteOffset.set(__lastAngleCos * distance, __lastAngleSin * distance);
|
||||
__noteOffset.x += -daNote.origin.x + daNote.offset.x;
|
||||
__noteOffset.y += -daNote.origin.y + daNote.offset.y;
|
||||
if (daNote.isSustainNote) {
|
||||
final m = (daNote.height * 0.5 * (speed < 0 ? -1 : 1)); // daNote.height works better than this.height in this case ???
|
||||
_noteOffset.x += angleX * m;
|
||||
_noteOffset.y += angleY * m;
|
||||
final m = (daNote.height * 0.5 * (speed < 0 ? -1 : 1));
|
||||
__noteOffset.x += __lastAngleCos * m;
|
||||
__noteOffset.y += __lastAngleSin * m;
|
||||
}
|
||||
_noteOffset.x += x + (width * 0.5);
|
||||
_noteOffset.y += y + (height * 0.5);
|
||||
if (shouldX) daNote.x = _noteOffset.x;
|
||||
if (shouldY) daNote.y = _noteOffset.y;
|
||||
_noteOffset.put();
|
||||
__noteOffset.x += x + __lastStrumHalfW;
|
||||
__noteOffset.y += y + __lastStrumHalfH;
|
||||
if (shouldX) daNote.x = __noteOffset.x;
|
||||
if (shouldY) daNote.y = __noteOffset.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user