a buncha characcter editor stuff
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import flxanimate.animate.FlxSymbol;
|
||||
import flxanimate.animate.FlxElement;
|
||||
import flxanimate.animate.SymbolParameters;
|
||||
import flxanimate.animate.FlxKeyFrame;
|
||||
import flxanimate.animate.FlxTimeline;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flxanimate.animate.FlxAnim.SymbolStuff;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import openfl.geom.Rectangle;
|
||||
import funkin.backend.utils.XMLUtil.AnimData;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class CharacterAnimButton extends UIButton {
|
||||
public var anim:String = null;
|
||||
public var data:AnimData = null;
|
||||
@@ -32,6 +42,9 @@ class CharacterAnimButton extends UIButton {
|
||||
|
||||
public var labels:Map<UISprite, UIText> = [];
|
||||
|
||||
public var foldableButtons:Array<FlxSprite> = [];
|
||||
public var closed:Bool = true;
|
||||
|
||||
public function new(x:Float, y:Float, animData:AnimData, parent:CharacterAnimsWindow) {
|
||||
this.anim = animData.name;
|
||||
this.data = animData;
|
||||
@@ -51,40 +64,72 @@ class CharacterAnimButton extends UIButton {
|
||||
frames = Paths.getFrames('editors/ui/inputbox');
|
||||
field.fieldWidth = 0; framesOffset = 9;
|
||||
field.size = 14;
|
||||
// field.visible = false;
|
||||
|
||||
animationDisplayBG = new UISliceSprite(x+12, y+12+18+12, 128, 128, 'editors/ui/inputbox-small');
|
||||
members.push(animationDisplayBG);
|
||||
foldableButtons.push(animationDisplayBG);
|
||||
|
||||
nameTextBox = new UITextBox(animationDisplayBG.x+126+16, animationDisplayBG.y, animData.name, 116, 22, false, true);
|
||||
nameTextBox.onChange = (newName:String) -> {this.changeName(newName);};
|
||||
members.push(nameTextBox);
|
||||
foldableButtons.push(nameTextBox);
|
||||
addLabelOn(nameTextBox, "Name", 12);
|
||||
|
||||
animTextBox = new UITextBox(nameTextBox.x + 100 + 12, nameTextBox.y, animData.anim, 146, 22, false, true);
|
||||
animTextBox.onChange = (newAnim:String) -> {this.changeAnim(newAnim);};
|
||||
members.push(animTextBox);
|
||||
foldableButtons.push(animTextBox);
|
||||
addLabelOn(animTextBox, "Animation", 12);
|
||||
|
||||
positionXStepper = new UINumericStepper(animTextBox.x, animTextBox.y+32+18, animData.x, 0.001, 2, null, null, 64, 22, true);
|
||||
positionXStepper.onChange = (text:String) -> {
|
||||
@:privateAccess positionXStepper.__onChange(text);
|
||||
this.changeOffset(positionXStepper.value, null);
|
||||
};
|
||||
members.push(positionXStepper);
|
||||
foldableButtons.push(positionXStepper);
|
||||
addLabelOn(positionXStepper, "Position (X,Y)", 12);
|
||||
|
||||
members.push(XYComma = new UIText(positionXStepper.x+104-32+0, positionXStepper.y + 9, 0, ",", 18));
|
||||
foldableButtons.push(XYComma);
|
||||
|
||||
positionYStepper = new UINumericStepper(positionXStepper.x+104-32+26, positionXStepper.y, animData.y, 0.001, 2, null, null, 64, 22, true);
|
||||
positionYStepper.onChange = (text:String) -> {
|
||||
@:privateAccess positionYStepper.__onChange(text);
|
||||
this.changeOffset(null, positionYStepper.value);
|
||||
};
|
||||
members.push(positionYStepper);
|
||||
foldableButtons.push(positionYStepper);
|
||||
|
||||
fpsStepper = new UINumericStepper(animTextBox.x + 200 + 26, animTextBox.y, 0, 0.1, 2, animData.fps, 100, 52, 22, true);
|
||||
fpsStepper = new UINumericStepper(animTextBox.x + 200 + 26, animTextBox.y, animData.fps, 0.1, 2, 1, 100, 52, 22, true);
|
||||
fpsStepper.onChange = (text:String) -> {
|
||||
@:privateAccess fpsStepper.__onChange(text);
|
||||
this.changeFPS(fpsStepper.value);
|
||||
};
|
||||
members.push(fpsStepper);
|
||||
foldableButtons.push(fpsStepper);
|
||||
addLabelOn(fpsStepper, "FPS", 12);
|
||||
|
||||
loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, "Looping?", animData.loop, 0, true);
|
||||
loopedCheckbox.onChecked = (newLooping:Bool) -> {this.changeLooping(newLooping);};
|
||||
members.push(loopedCheckbox);
|
||||
foldableButtons.push(loopedCheckbox);
|
||||
addLabelOn(loopedCheckbox, "Looped", 12);
|
||||
|
||||
loopedCheckbox.x += 8; loopedCheckbox.y += 6;
|
||||
|
||||
indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y, animData.indices.getDefault([]).join(","), 278, 22, false, true);
|
||||
indicesTextBox.onChange = (text:String) -> {
|
||||
var indices:Array<Int> = [];
|
||||
for(indice in text.split(",")) {
|
||||
var i = Std.parseInt(indice.trim());
|
||||
if (i != null) indices.push(i);
|
||||
}
|
||||
|
||||
this.changeIndicies(indices);
|
||||
}
|
||||
members.push(indicesTextBox);
|
||||
foldableButtons.push(indicesTextBox);
|
||||
addLabelOn(indicesTextBox, "Indices (frames)", 12);
|
||||
|
||||
playIcon = new FlxSprite(x-(10+16), y+8).loadGraphic(Paths.image("editors/character/play"));
|
||||
@@ -102,7 +147,7 @@ class CharacterAnimButton extends UIButton {
|
||||
deleteIcon.antialiasing = false;
|
||||
members.push(deleteIcon);
|
||||
|
||||
editButton = new UIButton(0, 0, "", null, 28,24);
|
||||
editButton = new UIButton(0, 0, "", () -> {this.closed = !this.closed; this.update(0);}, 28,24);
|
||||
editButton.frames = Paths.getFrames("editors/ui/grayscale-button");
|
||||
editButton.color = 0xFFAFAA12;
|
||||
members.push(editButton);
|
||||
@@ -128,49 +173,208 @@ class CharacterAnimButton extends UIButton {
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
playIcon.follow(this, 22, 19);
|
||||
field.follow(this, 22+15+8, 16);
|
||||
bHeight = closed ? 52 : 208;
|
||||
|
||||
deleteButton.follow(this, (500-16-32)-16-(28*2), 14);
|
||||
playIcon.follow(this, 22, (52/2) - (playIcon.height/2));
|
||||
field.follow(this, 22+16+10, (52/2) - (field.height/2) + 1);
|
||||
|
||||
deleteButton.follow(this, 380, 14);
|
||||
deleteIcon.follow(deleteButton, (deleteButton.bWidth/2)-6.5, (deleteButton.bHeight/2)-6);
|
||||
|
||||
editButton.follow(this, (500-16-32)-16-(28*2)-12-28, 14);
|
||||
editButton.follow(this, 340, 14);
|
||||
editIcon.follow(editButton, (editButton.bWidth/2)-8, (editButton.bHeight/2)-6);
|
||||
|
||||
ghostButton.follow(this, (500-16-32)-16-(28*2)-12-28-12-28, 14);
|
||||
ghostButton.follow(this, 300, 14);
|
||||
ghostIcon.follow(ghostButton, (ghostButton.bWidth/2)-8, (ghostButton.bHeight/2)-6);
|
||||
|
||||
animationDisplayBG.follow(this, 16, 8+32+8+2+11);
|
||||
nameTextBox.follow(this, 14+128+16, 8+32+8+2+8+14);
|
||||
animTextBox.follow(this, 14+128+12+116+20, 8+32+8+2+8+14);
|
||||
animationDisplayBG.follow(this, 16, 61);
|
||||
nameTextBox.follow(this, 158, 72);
|
||||
animTextBox.follow(this, 290, 72);
|
||||
|
||||
positionXStepper.follow(this, 14+128+16, 8+32+8+2+8+10+24+26);
|
||||
positionYStepper.follow(this, 14+128+16+64-32+28, 8+32+8+2+8+10+24+26);
|
||||
positionXStepper.follow(this, 158, 118);
|
||||
positionYStepper.follow(this, 218, 118);
|
||||
XYComma.follow(positionXStepper, 64-24, 6);
|
||||
|
||||
fpsStepper.follow(this, 14+128+16+64-32+28+64-22+20, 8+32+8+2+8+10+24+26);
|
||||
loopedCheckbox.follow(this, 14+128+16+64-32+28+64-22+20+52-22+18+8, 8+32+8+2+8+10+24+32);
|
||||
fpsStepper.follow(this, 280, 118);
|
||||
loopedCheckbox.follow(this, 336, 124);
|
||||
|
||||
indicesTextBox.follow(this, 14+128+16, 8+32+8+2+8+10+24+26+24+22);
|
||||
indicesTextBox.follow(this, 158, 164);
|
||||
|
||||
for (ui => text in labels)
|
||||
for (button in foldableButtons)
|
||||
button.visible = button.active = !closed;
|
||||
|
||||
for (ui => text in labels) {
|
||||
text.follow(ui, -(2+(ui is UICheckbox?12:0)), -(18+(ui is UICheckbox?6:0)));
|
||||
text.visible = text.active = ui.visible;
|
||||
}
|
||||
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
public function changeName(newName:String) @:privateAccess {
|
||||
if (newName == anim) return;
|
||||
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim];
|
||||
|
||||
parent.character.animateAtlas.anim.animsMap.remove(anim);
|
||||
parent.character.animateAtlas.anim.animsMap.set(newName, animSymbol);
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = parent.character.animation._animations[anim];
|
||||
flxAnimation.name = newName;
|
||||
|
||||
parent.character.animation._animations.remove(anim);
|
||||
parent.character.animation._animations.set(newName, flxAnimation);
|
||||
}
|
||||
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
animData.name = newName;
|
||||
|
||||
parent.character.animDatas.remove(anim);
|
||||
parent.character.animDatas.set(newName, animData);
|
||||
|
||||
var animOffset:FlxPoint = parent.character.animOffsets[anim];
|
||||
parent.character.animOffsets.remove(anim);
|
||||
parent.character.animOffsets.set(newName, animOffset);
|
||||
|
||||
var displayFrame:{scale:Float, animBounds:Rectangle, frame:Int} = parent.displayAnimsFramesList[anim];
|
||||
parent.displayAnimsFramesList.remove(anim);
|
||||
parent.displayAnimsFramesList.set(newName, displayFrame);
|
||||
|
||||
this.anim = newName;
|
||||
field.text = '${animData.name} (${animData.x}, ${animData.y})';
|
||||
}
|
||||
|
||||
public function changeAnim(newAnim:String) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
if (newAnim == animData.anim) return;
|
||||
|
||||
animData.anim = newAnim;
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim];
|
||||
refreshSymbolKeyFrames(animSymbol, animData);
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = parent.character.animation._animations[anim];
|
||||
flxAnimation.prefix = newAnim;
|
||||
|
||||
refreshFlxAnimationFrames(flxAnimation, animData);
|
||||
parent.buildAnimDisplay(anim, flxAnimation);
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
}
|
||||
|
||||
public function changeOffset(newOffsetX:Null<Float>, newOffsetY:Null<Float>) {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
|
||||
if (newOffsetX != null && newOffsetY != null && newOffsetX == animData.x && newOffsetY == animData.y)
|
||||
return;
|
||||
else {
|
||||
if (newOffsetX != null && newOffsetX == animData.x) return;
|
||||
if (newOffsetY != null && newOffsetY == animData.y) return;
|
||||
}
|
||||
|
||||
if (newOffsetX != null) animData.x = newOffsetX;
|
||||
if (newOffsetY != null) animData.y = newOffsetY;
|
||||
|
||||
parent.character.animOffsets[anim].set(animData.x, animData.y);
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
|
||||
field.text = '${animData.name} (${animData.x}, ${animData.y})';
|
||||
}
|
||||
|
||||
public function changeFPS(newFPS:Float) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
animData.fps = newFPS;
|
||||
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim];
|
||||
animSymbol.frameRate = newFPS;
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = parent.character.animation._animations[anim];
|
||||
flxAnimation.frameRate = newFPS;
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
}
|
||||
|
||||
public function changeLooping(newLooping:Bool) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
animData.loop = newLooping;
|
||||
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim];
|
||||
animSymbol.instance.symbol.loop = animData.loop ? Loop : PlayOnce;
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = parent.character.animation._animations[anim];
|
||||
flxAnimation.looped = animData.loop;
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
}
|
||||
|
||||
public function changeIndicies(indicies:Array<Int>) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
animData.indices = indicies;
|
||||
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim];
|
||||
refreshSymbolKeyFrames(animSymbol, animData);
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = parent.character.animation._animations[anim];
|
||||
refreshFlxAnimationFrames(flxAnimation, animData);
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
}
|
||||
|
||||
public inline function refreshFlxAnimationFrames(flxAnimation:FlxAnimation, animData:AnimData) @:privateAccess {
|
||||
try {
|
||||
if (animData.indices.length > 0) {
|
||||
var frameIndices:Array<Int> = new Array<Int>();
|
||||
parent.character.animation.byIndicesHelper(frameIndices, flxAnimation.prefix, animData.indices, "");
|
||||
|
||||
flxAnimation.frames = frameIndices;
|
||||
} else {
|
||||
final animFrames:Array<FlxFrame> = new Array<FlxFrame>();
|
||||
parent.character.animation.findByPrefix(animFrames, flxAnimation.prefix);
|
||||
|
||||
final frameIndices:Array<Int> = [];
|
||||
parent.character.animation.byPrefixHelper(frameIndices, animFrames, flxAnimation.prefix);
|
||||
|
||||
flxAnimation.frames = frameIndices;
|
||||
}
|
||||
} catch (e) {
|
||||
trace('TODO: ERROR HANDLING $e');
|
||||
}
|
||||
}
|
||||
|
||||
public inline function refreshSymbolKeyFrames(symbol:SymbolStuff, animData:AnimData) @:privateAccess {
|
||||
if (animData.indices.length > 0) {
|
||||
// keeps on crashing, look at flxanimate FlxAnim.hx for refrence
|
||||
} else {
|
||||
for (name in parent.character.animateAtlas.anim.symbolDictionary.keys())
|
||||
if (parent.character.animateAtlas.anim.startsWith(name, animData.anim))
|
||||
{symbol.instance.symbol.name = name; break;}
|
||||
}
|
||||
}
|
||||
|
||||
public override function draw() {
|
||||
super.draw();
|
||||
|
||||
if (parent.displayAnimsFramesList.exists(anim)) {
|
||||
if (!closed && parent.displayAnimsFramesList.exists(anim)) {
|
||||
var displayData:{frame:Int, scale:Float, animBounds:Rectangle} = parent.displayAnimsFramesList.get(anim);
|
||||
parent.displayWindowSprite.frame = parent.displayWindowSprite.frames.frames[displayData.frame];
|
||||
|
||||
parent.displayWindowSprite.scale.x = parent.displayWindowSprite.scale.y = displayData.scale;
|
||||
parent.displayWindowSprite.updateHitbox();
|
||||
|
||||
// parent.displayWindowSprite.origin.set();
|
||||
|
||||
parent.displayWindowSprite.follow(
|
||||
this, 16+(128/2)-((parent.displayWindowSprite.frame.sourceSize.x*displayData.scale)/2),
|
||||
8+32+8+2+11+(128/2)-((parent.displayWindowSprite.frame.sourceSize.y*displayData.scale)/2)
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
class CharacterAnimButtons extends UIButton {
|
||||
public var anim:String = "";
|
||||
|
||||
public var editButton:UIButton;
|
||||
public var editIcon:FlxSprite;
|
||||
|
||||
public var ghostButton:UIButton;
|
||||
public var ghostIcon:FlxSprite;
|
||||
|
||||
public var deleteButton:UIButton;
|
||||
public var deleteIcon:FlxSprite;
|
||||
|
||||
public function new(x:Float,y:Float,anim:String, offset:FlxPoint) {
|
||||
this.anim = anim;
|
||||
super(x,y, '$anim (${offset.x}, ${offset.y})', function () {
|
||||
CharacterEditor.instance.playAnimation(this.anim);
|
||||
}, 282);
|
||||
autoAlpha = false;
|
||||
|
||||
ghostButton = new UIButton(x+282+17, y, "", function () {
|
||||
CharacterEditor.instance.ghostAnim(this.anim);
|
||||
}, 32);
|
||||
ghostButton.autoAlpha = false;
|
||||
members.push(ghostButton);
|
||||
|
||||
ghostIcon = new FlxSprite(ghostButton.x + 8, ghostButton.y + 8).loadGraphic(Paths.image('editors/character/ghost-button'), true, 16, 16);
|
||||
ghostIcon.animation.add("alive", [0]);
|
||||
ghostIcon.animation.add("dead", [1]);
|
||||
ghostIcon.animation.play("dead"); ghostIcon.alpha = 0.5;
|
||||
ghostIcon.antialiasing = false;
|
||||
ghostIcon.updateHitbox();
|
||||
members.push(ghostIcon);
|
||||
|
||||
editButton = new UIButton(ghostButton.x+32+17, y, "", function () {
|
||||
CharacterEditor.instance.editAnimWithUI(this.anim);
|
||||
}, 32);
|
||||
editButton.frames = Paths.getFrames("editors/ui/grayscale-button");
|
||||
editButton.color = FlxColor.YELLOW;
|
||||
editButton.autoAlpha = false;
|
||||
members.push(editButton);
|
||||
|
||||
editIcon = new FlxSprite(editButton.x + 8, editButton.y + 8).loadGraphic(Paths.image('editors/character/edit-button'), true, 16, 16);
|
||||
editIcon.animation.add("edit", [0]);
|
||||
editIcon.animation.add("advanced", [1]);
|
||||
editIcon.animation.play("edit");
|
||||
editIcon.antialiasing = false;
|
||||
members.push(editIcon);
|
||||
|
||||
deleteButton = new UIButton(editButton.x+32+17, y, "", function () {
|
||||
CharacterEditor.instance.deleteAnim(this.anim);
|
||||
}, 32);
|
||||
deleteButton.color = FlxColor.RED;
|
||||
deleteButton.autoAlpha = false;
|
||||
members.push(deleteButton);
|
||||
|
||||
deleteIcon = new FlxSprite(deleteButton.x + (15/2), deleteButton.y + 8).loadGraphic(Paths.image('editors/delete-button'));
|
||||
deleteIcon.antialiasing = false;
|
||||
members.push(deleteIcon);
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
editButton.selectable = ghostButton.selectable = deleteButton.selectable = selectable;
|
||||
editButton.shouldPress = ghostButton.shouldPress = deleteButton.shouldPress = shouldPress;
|
||||
|
||||
hovered = !deleteButton.hovered;
|
||||
updatePos();
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
public function updateInfo(anim:String, offset:FlxPoint, ghost:Bool) {
|
||||
this.anim = anim;
|
||||
|
||||
field.text = '$anim (${offset.x}, ${offset.y})';
|
||||
ghostIcon.animation.play(ghost ? "alive" : "dead");
|
||||
ghostIcon.alpha = ghost ? 1 : 0.5;
|
||||
}
|
||||
|
||||
public inline function updatePos() {
|
||||
// buttons
|
||||
deleteButton.x = (editButton.x = (ghostButton.x = (x+282+17))+32+17)+32+17;
|
||||
deleteButton.y = editButton.y = ghostButton.y = y;
|
||||
// icons
|
||||
ghostIcon.x = ghostButton.x + 8; ghostIcon.y = ghostButton.y + 8;
|
||||
editIcon.x = editButton.x + 8; editIcon.y = editButton.y + 8;
|
||||
deleteIcon.x = deleteButton.x + (15/2); deleteIcon.y = deleteButton.y + 8;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import flixel.animation.FlxAnimation;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import openfl.geom.Rectangle;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
@@ -31,17 +32,22 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
displayWindowSprite.flipX = character.flipX;
|
||||
|
||||
@:privateAccess
|
||||
for (name => anim in displayWindowSprite.animation._animations) {
|
||||
var frameIndex:Int = anim.frames.getDefault([0])[0];
|
||||
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
|
||||
|
||||
var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
|
||||
var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
|
||||
|
||||
displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/animBounds.height, animBounds: animBounds});
|
||||
}
|
||||
for (name => anim in displayWindowSprite.animation._animations)
|
||||
buildAnimDisplay(name, anim);
|
||||
|
||||
for (anim in character.getAnimOrder())
|
||||
add(new CharacterAnimButton(0,0, character.animDatas.get(anim), this));
|
||||
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
public function buildAnimDisplay(name:String, anim:FlxAnimation) {
|
||||
var frameIndex:Int = anim.frames.getDefault([0])[0];
|
||||
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
|
||||
|
||||
var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
|
||||
var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
|
||||
|
||||
displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/animBounds.height, animBounds: animBounds});
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,6 @@ class CharacterEditor extends UIState {
|
||||
static var __character:String;
|
||||
public var character:Character;
|
||||
|
||||
public var ghosts:CharacterGhostsHandler;
|
||||
|
||||
public static var instance(get, null):CharacterEditor;
|
||||
|
||||
private static inline function get_instance()
|
||||
@@ -38,8 +36,6 @@ class CharacterEditor extends UIState {
|
||||
public var charCamera:FlxCamera;
|
||||
public var uiCamera:FlxCamera;
|
||||
|
||||
public var undos:UndoList<CharacterChange> = new UndoList<CharacterChange>();
|
||||
|
||||
public function new(character:String) {
|
||||
super();
|
||||
if (character != null) __character = character;
|
||||
@@ -84,12 +80,10 @@ class CharacterEditor extends UIState {
|
||||
{
|
||||
label: "Undo",
|
||||
keybind: [CONTROL, Z],
|
||||
onSelect: _edit_undo
|
||||
},
|
||||
{
|
||||
label: "Redo",
|
||||
keybinds: [[CONTROL, Y], [CONTROL, SHIFT, Z]],
|
||||
onSelect: _edit_redo
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -99,21 +93,17 @@ class CharacterEditor extends UIState {
|
||||
{
|
||||
label: "New Animation",
|
||||
keybind: [CONTROL, N],
|
||||
onSelect: _char_add_anim,
|
||||
},
|
||||
{
|
||||
label: "Edit Animation",
|
||||
onSelect: _char_edit_anim,
|
||||
},
|
||||
{
|
||||
label: "Delete Animation",
|
||||
keybind: [DELETE],
|
||||
onSelect: _char_remove_anim,
|
||||
},
|
||||
null,
|
||||
{
|
||||
label: "Edit Info",
|
||||
onSelect: _char_edit_info,
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -137,49 +127,40 @@ class CharacterEditor extends UIState {
|
||||
{
|
||||
label: "Move Left",
|
||||
keybind: [LEFT],
|
||||
onSelect: _offsets_left,
|
||||
},
|
||||
{
|
||||
label: "Move Up",
|
||||
keybind: [UP],
|
||||
onSelect: _offsets_up,
|
||||
},
|
||||
{
|
||||
label: "Move Down",
|
||||
keybind: [DOWN],
|
||||
onSelect: _offsets_down,
|
||||
},
|
||||
{
|
||||
label: "Move Right",
|
||||
keybind: [RIGHT],
|
||||
onSelect: _offsets_right,
|
||||
},
|
||||
null,
|
||||
{
|
||||
label: "Move Extra Left",
|
||||
keybind: [SHIFT, LEFT],
|
||||
onSelect: _offsets_extra_left,
|
||||
},
|
||||
{
|
||||
label: "Move Extra Up",
|
||||
keybind: [SHIFT, UP],
|
||||
onSelect: _offsets_extra_up,
|
||||
},
|
||||
{
|
||||
label: "Move Extra Down",
|
||||
keybind: [SHIFT, DOWN],
|
||||
onSelect: _offsets_extra_down,
|
||||
},
|
||||
{
|
||||
label: "Move Extra Right",
|
||||
keybind: [SHIFT, RIGHT],
|
||||
onSelect: _offsets_extra_right,
|
||||
},
|
||||
null,
|
||||
{
|
||||
label: "Clear Offsets",
|
||||
keybind: [CONTROL, R],
|
||||
onSelect: _offsets_clear,
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -226,10 +207,6 @@ class CharacterEditor extends UIState {
|
||||
character.debugMode = true;
|
||||
character.cameras = [charCamera];
|
||||
|
||||
ghosts = new CharacterGhostsHandler(character);
|
||||
ghosts.cameras = [charCamera];
|
||||
|
||||
add(ghosts);
|
||||
add(character);
|
||||
|
||||
uiGroup.cameras = [uiCamera];
|
||||
@@ -305,16 +282,13 @@ class CharacterEditor extends UIState {
|
||||
characterBG.scale.set(characterBG.scale.x / charCamera.zoom, characterBG.scale.y / charCamera.zoom);
|
||||
|
||||
super.update(elapsed);
|
||||
|
||||
WindowUtils.prefix = undos.unsaved ? "* " : "";
|
||||
SaveWarning.showWarning = undos.unsaved;
|
||||
}
|
||||
|
||||
// TOP MENU OPTIONS
|
||||
#if REGION
|
||||
function _file_exit(_) {
|
||||
if (undos.unsaved) SaveWarning.triggerWarning();
|
||||
else FlxG.switchState(new CharacterSelection());
|
||||
/*if (undos.unsaved) SaveWarning.triggerWarning();
|
||||
else*/ FlxG.switchState(new CharacterSelection());
|
||||
}
|
||||
|
||||
function _file_new(_) {
|
||||
@@ -326,7 +300,6 @@ class CharacterEditor extends UIState {
|
||||
'${Paths.getAssetsRoot()}/data/characters/${character.curCharacter}.xml',
|
||||
buildCharacter()
|
||||
);
|
||||
undos.save();
|
||||
#else
|
||||
_file_saveas(_);
|
||||
#end
|
||||
@@ -336,7 +309,6 @@ class CharacterEditor extends UIState {
|
||||
openSubState(new SaveSubstate(buildCharacter(), {
|
||||
defaultSaveFile: '${character.curCharacter}.xml'
|
||||
}));
|
||||
undos.save();
|
||||
}
|
||||
|
||||
function buildCharacter():String {
|
||||
@@ -352,162 +324,6 @@ class CharacterEditor extends UIState {
|
||||
return "<!DOCTYPE codename-engine-character>\n" + Printer.print(charXML, true);
|
||||
}
|
||||
|
||||
function _edit_undo(_) {
|
||||
var undo = undos.undo();
|
||||
switch(undo) {
|
||||
case null:
|
||||
// do nothing
|
||||
case CEditInfo(oldInfo, newInfo):
|
||||
editInfo(oldInfo, false);
|
||||
case CCreateAnim(animID, animData):
|
||||
deleteAnim(animData.name, false);
|
||||
case CEditAnim(name, oldData, animData):
|
||||
editAnim(name, oldData, false);
|
||||
case CDeleteAnim(animID, animData):
|
||||
createAnim(animData, animID, false);
|
||||
case CChangeOffset(name, change):
|
||||
changeOffset(name, change * -1, false);
|
||||
case CResetOffsets(oldOffsets):
|
||||
for (anim => offsets in oldOffsets) {
|
||||
character.animOffsets.set(anim, offsets.clone());
|
||||
ghosts.setOffsets(anim, offsets.clone());
|
||||
}
|
||||
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(0, 0), false); // apply da new offsets
|
||||
}
|
||||
}
|
||||
|
||||
function _edit_redo(_) {
|
||||
var redo = undos.redo();
|
||||
switch(redo) {
|
||||
case null:
|
||||
// do nothing
|
||||
case CEditInfo(oldInfo, newInfo):
|
||||
editInfo(newInfo, false);
|
||||
case CCreateAnim(animID, animData):
|
||||
createAnim(animData, animID, false);
|
||||
case CEditAnim(name, oldData, animData):
|
||||
editAnim(oldData.name, animData, false);
|
||||
case CDeleteAnim(animID, animData):
|
||||
deleteAnim(animData.name, false);
|
||||
case CChangeOffset(name, change):
|
||||
changeOffset(name, change, false);
|
||||
case CResetOffsets(oldOffsets):
|
||||
clearOffsets(false);
|
||||
}
|
||||
}
|
||||
|
||||
function _char_add_anim(_) {
|
||||
createAnimWithUI();
|
||||
}
|
||||
|
||||
function _char_edit_anim(_) {
|
||||
editAnimWithUI(character.getAnimName());
|
||||
}
|
||||
|
||||
function _char_remove_anim(_) {
|
||||
deleteAnim(character.getAnimName());
|
||||
}
|
||||
|
||||
function _char_edit_info(_) {
|
||||
editInfoWithUI();
|
||||
}
|
||||
|
||||
public function createAnimWithUI() {
|
||||
|
||||
}
|
||||
|
||||
public function editAnimWithUI(name:String) {
|
||||
|
||||
}
|
||||
|
||||
public function createAnim(animData:AnimData, animID:Int = -1, addtoUndo:Bool = true) {
|
||||
/*
|
||||
XMLUtil.addAnimToSprite(character, animData);
|
||||
ghosts.createGhost(animData.name);
|
||||
var newButton = new CharacterAnimButton(0, 0, animData.name, FlxPoint.get(animData.x,animData.y));
|
||||
if (animID == -1) characterAnimsWindow.add(newButton);
|
||||
else characterAnimsWindow.insert(newButton, animID);
|
||||
|
||||
playAnimation(animData.name);
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CCreateAnim(character.getNameList().length, animData));
|
||||
*/
|
||||
}
|
||||
|
||||
public function editAnim(name:String, animData:AnimData, addtoUndo:Bool = true) {
|
||||
var oldAnimData:AnimData = character.animDatas.get(name);
|
||||
var buttoner:CharacterAnimButton = null;
|
||||
for (button in characterAnimsWindow.buttons.members)
|
||||
if (button.anim == name) buttoner = button;
|
||||
|
||||
ghosts.removeGhost(name);
|
||||
XMLUtil.addAnimToSprite(character, animData);
|
||||
ghosts.createGhost(animData.name);
|
||||
|
||||
if (character.getAnimName() == animData.name) // update anim ifs its currently selected
|
||||
playAnimation(animData.name);
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CEditAnim(animData.name, oldAnimData, animData));
|
||||
}
|
||||
|
||||
public function deleteAnim(name:String, addtoUndo:Bool = true) {
|
||||
var animOrder:Array<String> = [
|
||||
for (button in characterAnimsWindow.buttons.members)
|
||||
button.anim
|
||||
];
|
||||
|
||||
if (character.getNameList().length-1 == 0)
|
||||
@:privateAccess character.animation._curAnim = null;
|
||||
else
|
||||
playAnimation(animOrder[Std.int(Math.abs(animOrder.indexOf(name)-1))]);
|
||||
|
||||
for(button in characterAnimsWindow.buttons.members)
|
||||
if(button.anim == name) characterAnimsWindow.remove(button);
|
||||
|
||||
// undo shit blah blah
|
||||
var oldID:Int = animOrder.indexOf(name);
|
||||
var oldAnimData:AnimData = character.animDatas.get(name);
|
||||
|
||||
ghosts.removeGhost(name);
|
||||
character.removeAnimation(name);
|
||||
if (character.animOffsets.exists(name)) character.animOffsets.remove(name);
|
||||
if (character.animDatas.exists(name)) character.animDatas.remove(name);
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CDeleteAnim(oldID, oldAnimData));
|
||||
}
|
||||
|
||||
public function editInfoWithUI() {
|
||||
FlxG.state.openSubState(new CharacterInfoScreen(character, (_) -> {
|
||||
if (_ != null) editInfo(_);
|
||||
}));
|
||||
}
|
||||
|
||||
public function editInfo(newInfo:Xml, addtoUndo:Bool = true) {
|
||||
var lastAnim:String = character.getAnimName();
|
||||
|
||||
var oldInfo = character.buildXML();
|
||||
character.applyXML(new Access(newInfo));
|
||||
ghosts.updateInfos(newInfo);
|
||||
|
||||
playAnimation(lastAnim);
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CEditInfo(oldInfo, newInfo));
|
||||
}
|
||||
|
||||
public function ghostAnim(anim:String) {
|
||||
var ghost:Character = ghosts.animGhosts.get(anim);
|
||||
ghost.visible = !ghost.visible;
|
||||
|
||||
var animButton:CharacterAnimButton = null;
|
||||
for (button in characterAnimsWindow.buttons.members)
|
||||
if (button.anim == anim) animButton = button;
|
||||
}
|
||||
|
||||
function _playback_play_anim(_) {
|
||||
if (character.getNameList().length != 0)
|
||||
playAnimation(character.getAnimName());
|
||||
@@ -525,68 +341,6 @@ class CharacterEditor extends UIState {
|
||||
i.alpha = i.anim == anim ? 1 : 0.25;
|
||||
}
|
||||
|
||||
function _offsets_left(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(!character.isFlippedOffsets() ? 1 : -1, 0));
|
||||
}
|
||||
|
||||
function _offsets_up(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(0, 1));
|
||||
}
|
||||
|
||||
function _offsets_down(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(0, -1));
|
||||
}
|
||||
|
||||
function _offsets_right(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(!character.isFlippedOffsets() ? -1 : 1, 0));
|
||||
}
|
||||
|
||||
function _offsets_extra_left(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(!character.isFlippedOffsets() ? 5 : -5, 0));
|
||||
}
|
||||
|
||||
function _offsets_extra_up(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(0, 5));
|
||||
}
|
||||
|
||||
function _offsets_extra_down(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(0, -5));
|
||||
}
|
||||
|
||||
function _offsets_extra_right(_) {
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(!character.isFlippedOffsets() ? -5 : 5, 0));
|
||||
}
|
||||
|
||||
function _offsets_clear(_) {
|
||||
clearOffsets();
|
||||
}
|
||||
|
||||
function changeOffset(anim:String, change:FlxPoint, addtoUndo:Bool = true) {
|
||||
if (character.getNameList().length == 0) return;
|
||||
|
||||
character.animOffsets.set(anim, character.getAnimOffset(anim) + change);
|
||||
character.frameOffset.set(character.getAnimOffset(anim).x, character.getAnimOffset(anim).y);
|
||||
|
||||
ghosts.updateOffsets(anim, change);
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CChangeOffset(anim, change));
|
||||
}
|
||||
|
||||
function clearOffsets(addtoUndo:Bool = true) {
|
||||
if (character.getNameList().length == 0) return;
|
||||
|
||||
var oldOffsets:Map<String, FlxPoint> = [
|
||||
for (anim => offsets in character.animOffsets)
|
||||
anim => offsets.clone()
|
||||
];
|
||||
changeOffset(character.getAnimName(), FlxPoint.get(), false);
|
||||
ghosts.clearOffsets();
|
||||
|
||||
if (addtoUndo)
|
||||
undos.addToUndo(CResetOffsets(oldOffsets));
|
||||
}
|
||||
|
||||
var zoom(default, set):Float = 0;
|
||||
var __camZoom(default, set):Float = 1;
|
||||
function set_zoom(val:Float) {
|
||||
@@ -619,13 +373,4 @@ class CharacterEditor extends UIState {
|
||||
characterMidpoint.put();
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
enum CharacterChange {
|
||||
CEditInfo(oldInfo:Xml, newInfo:Xml);
|
||||
CCreateAnim(animID:Int, animData:AnimData);
|
||||
CEditAnim(name:String, oldData:AnimData, animData:AnimData);
|
||||
CDeleteAnim(animID:Int, animData:AnimData);
|
||||
CChangeOffset(name:String, change:FlxPoint);
|
||||
CResetOffsets(oldOffsets:Map<String, FlxPoint>);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import funkin.game.Character;
|
||||
import haxe.xml.Access;
|
||||
|
||||
class CharacterGhostsHandler extends FlxTypedGroup<Character> {
|
||||
public var character:Character;
|
||||
public var animGhosts:Map<String, Character> = [];
|
||||
|
||||
public function new(character:Character) {
|
||||
this.character = character;
|
||||
super();
|
||||
|
||||
for (anim in character.getNameList())
|
||||
createGhost(anim);
|
||||
}
|
||||
|
||||
public function createGhost(anim:String) {
|
||||
var ghost:Character = new Character(0,0, character.curCharacter);
|
||||
ghost.applyXML(character.xml); // apply cur character stuff
|
||||
ghost.playAnim(anim);
|
||||
ghost.stopAnimation();
|
||||
ghost.alpha = 0.5;
|
||||
ghost.visible = false;
|
||||
add(ghost);
|
||||
|
||||
animGhosts.set(anim, ghost);
|
||||
}
|
||||
|
||||
public function removeGhost(anim:String) {
|
||||
var ghost:Character = animGhosts.get(anim);
|
||||
@:privateAccess if (ghost != null) {
|
||||
ghost.animation._curAnim = null;
|
||||
animGhosts.remove(anim);
|
||||
ghost.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public function updateInfos(xml:Xml) {
|
||||
for (anim => ghost in animGhosts) {
|
||||
ghost.applyXML(new Access(xml));
|
||||
ghost.playAnim(anim);
|
||||
ghost.stopAnimation();
|
||||
}
|
||||
|
||||
rePositionGhosts();
|
||||
}
|
||||
|
||||
public function updateOffsets(name:String, change:FlxPoint) {
|
||||
for (anim => ghost in animGhosts)
|
||||
ghost.animOffsets.set(name, ghost.getAnimOffset(name) + change);
|
||||
|
||||
rePositionGhosts();
|
||||
}
|
||||
|
||||
public function setOffsets(name:String, offset:FlxPoint) {
|
||||
for (anim => ghost in animGhosts)
|
||||
ghost.animOffsets.set(name, offset);
|
||||
|
||||
rePositionGhosts();
|
||||
}
|
||||
|
||||
public function clearOffsets() {
|
||||
for (anim => ghost in animGhosts)
|
||||
ghost.animOffsets[anim].zero();
|
||||
|
||||
rePositionGhosts();
|
||||
}
|
||||
|
||||
inline function rePositionGhosts() {
|
||||
for (ghost in animGhosts)
|
||||
ghost.frameOffset.set(ghost.getAnimOffset(ghost.getAnimName()).x, ghost.getAnimOffset(ghost.getAnimName()).y);
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
import funkin.game.Character;
|
||||
import haxe.xml.Access;
|
||||
|
||||
class CharacterInfoScreen extends UISubstateWindow {
|
||||
public var character:Character;
|
||||
|
||||
public var spriteTextBox:UITextBox;
|
||||
public var iconTextBox:UITextBox;
|
||||
public var iconSprite:FlxSprite;
|
||||
public var gameOverCharTextBox:UITextBox;
|
||||
public var antialiasingCheckbox:UICheckbox;
|
||||
public var flipXCheckbox:UICheckbox;
|
||||
public var iconColorWheel:UIColorwheel;
|
||||
public var positionXStepper:UINumericStepper;
|
||||
public var positionYStepper:UINumericStepper;
|
||||
public var cameraXStepper:UINumericStepper;
|
||||
public var cameraYStepper:UINumericStepper;
|
||||
public var scaleStepper:UINumericStepper;
|
||||
public var singTimeStepper:UINumericStepper;
|
||||
public var customPropertiesButtonList:UIButtonList<PropertyButton>;
|
||||
public var isPlayerCheckbox:UICheckbox;
|
||||
|
||||
public var saveButton:UIButton;
|
||||
public var closeButton:UIButton;
|
||||
|
||||
public var onSave:(xml:Xml) -> Void = null;
|
||||
|
||||
public function new(character:Character, ?onSave:(xml:Xml) -> Void) {
|
||||
this.character = character;
|
||||
this.onSave = onSave;
|
||||
super();
|
||||
}
|
||||
|
||||
public override function create() {
|
||||
winTitle = "Editing Character";
|
||||
winWidth = 1014;
|
||||
winHeight = 600;
|
||||
|
||||
super.create();
|
||||
|
||||
function addLabelOn(ui:UISprite, text:String)
|
||||
add(new UIText(ui.x, ui.y - 24, 0, text));
|
||||
|
||||
var title:UIText;
|
||||
add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Sprite Data", 28));
|
||||
|
||||
spriteTextBox = new UITextBox(title.x, title.y + title.height + 38, character.sprite, 200);
|
||||
add(spriteTextBox);
|
||||
addLabelOn(spriteTextBox, "Sprite");
|
||||
|
||||
iconTextBox = new UITextBox(spriteTextBox.x + 200 + 26, spriteTextBox.y, character.getIcon(), 150);
|
||||
iconTextBox.onChange = (newIcon:String) -> {updateIcon(newIcon);}
|
||||
add(iconTextBox);
|
||||
addLabelOn(iconTextBox, "Icon");
|
||||
|
||||
updateIcon(character.getIcon());
|
||||
|
||||
gameOverCharTextBox = new UITextBox(iconTextBox.x + 150 + (75 + 12), iconTextBox.y, character.gameOverCharacter, 200);
|
||||
add(gameOverCharTextBox);
|
||||
addLabelOn(gameOverCharTextBox, "Game Over Character");
|
||||
|
||||
antialiasingCheckbox = new UICheckbox(spriteTextBox.x, spriteTextBox.y + 10 + 32 + 28, "Antialiasing", character.antialiasing);
|
||||
add(antialiasingCheckbox);
|
||||
addLabelOn(antialiasingCheckbox, "Antialiased");
|
||||
|
||||
flipXCheckbox = new UICheckbox(antialiasingCheckbox.x + 172, spriteTextBox.y + 10 + 32 + 28, "FlipX", character.flipX);
|
||||
add(flipXCheckbox);
|
||||
addLabelOn(flipXCheckbox, "Flipped");
|
||||
|
||||
iconColorWheel = new UIColorwheel(gameOverCharTextBox.x + 200 + 20, gameOverCharTextBox.y, character.iconColor);
|
||||
add(iconColorWheel);
|
||||
addLabelOn(iconColorWheel, "Icon Color");
|
||||
|
||||
add(title = new UIText(spriteTextBox.x, spriteTextBox.y + 10 + 46 + 84, 0, "Character Data", 28));
|
||||
|
||||
positionXStepper = new UINumericStepper(title.x, title.y + title.height + 36, character.globalOffset.x, 0.001, 2, null, null, 84);
|
||||
add(positionXStepper);
|
||||
addLabelOn(positionXStepper, "Position (X,Y)");
|
||||
|
||||
add(new UIText(positionXStepper.x + 84 - 32 + 0, positionXStepper.y + 9, 0, ",", 22));
|
||||
|
||||
positionYStepper = new UINumericStepper(positionXStepper.x + 84 - 32 + 26, positionXStepper.y, character.globalOffset.y, 0.001, 2, null, null, 84);
|
||||
add(positionYStepper);
|
||||
|
||||
cameraXStepper = new UINumericStepper(positionYStepper.x + 36 + 84 - 32, positionYStepper.y, character.cameraOffset.x, 0.001, 2, null, null, 84);
|
||||
add(cameraXStepper);
|
||||
addLabelOn(cameraXStepper, "Camera Position (X,Y)");
|
||||
|
||||
add(new UIText(cameraXStepper.x + 84 - 32 + 0, cameraXStepper.y + 9, 0, ",", 22));
|
||||
|
||||
cameraYStepper = new UINumericStepper(cameraXStepper.x + 84 - 32 + 26, cameraXStepper.y, character.cameraOffset.y, 0.001, 2, null, null, 84);
|
||||
add(cameraYStepper);
|
||||
|
||||
scaleStepper = new UINumericStepper(cameraYStepper.x + 84 - 32 + 90, cameraYStepper.y, character.scale.x, 0.001, 2, null, null, 74);
|
||||
add(scaleStepper);
|
||||
addLabelOn(scaleStepper, "Scale");
|
||||
|
||||
singTimeStepper = new UINumericStepper(scaleStepper.x + 74 - 32 + 36, scaleStepper.y, character.holdTime, 0.001, 2, null, null, 74);
|
||||
add(singTimeStepper);
|
||||
addLabelOn(singTimeStepper, "Sing Duration (Steps)");
|
||||
|
||||
customPropertiesButtonList = new UIButtonList<PropertyButton>(singTimeStepper.x + singTimeStepper.width + 200, singTimeStepper.y, 290, 200, '', FlxPoint.get(280, 35), null, 5);
|
||||
customPropertiesButtonList.frames = Paths.getFrames('editors/ui/inputbox');
|
||||
customPropertiesButtonList.cameraSpacing = 0;
|
||||
customPropertiesButtonList.addButton.callback = function() {
|
||||
customPropertiesButtonList.add(new PropertyButton("newProperty", "valueHere", customPropertiesButtonList));
|
||||
}
|
||||
for (prop=>val in character.extra)
|
||||
customPropertiesButtonList.add(new PropertyButton(prop, val, customPropertiesButtonList));
|
||||
add(customPropertiesButtonList);
|
||||
addLabelOn(customPropertiesButtonList, "Custom Values (Advanced)");
|
||||
|
||||
isPlayerCheckbox = new UICheckbox(positionXStepper.x, positionXStepper.y + 10 + 32 + 28, "isPlayer", character.playerOffsets);
|
||||
add(isPlayerCheckbox);
|
||||
addLabelOn(isPlayerCheckbox, "Is Player");
|
||||
|
||||
for (checkbox in [isPlayerCheckbox, antialiasingCheckbox, flipXCheckbox])
|
||||
{checkbox.y += 4; checkbox.x += 6;}
|
||||
|
||||
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight- 20, "Save & Close", function() {
|
||||
saveCharacterInfo();
|
||||
close();
|
||||
}, 125);
|
||||
saveButton.x -= saveButton.bWidth;
|
||||
saveButton.y -= saveButton.bHeight;
|
||||
|
||||
closeButton = new UIButton(saveButton.x - 20, saveButton.y, "Close", function() {
|
||||
if (onSave != null) onSave(null);
|
||||
close();
|
||||
}, 125);
|
||||
closeButton.x -= closeButton.bWidth;
|
||||
closeButton.color = 0xFFFF0000;
|
||||
add(closeButton);
|
||||
add(saveButton);
|
||||
}
|
||||
|
||||
function updateIcon(icon:String) {
|
||||
if (iconSprite == null) add(iconSprite = new FlxSprite());
|
||||
|
||||
if (iconSprite.animation.exists(icon)) return;
|
||||
@:privateAccess iconSprite.animation.clearAnimations();
|
||||
|
||||
var path:String = Paths.image('icons/$icon');
|
||||
if (!Assets.exists(path)) path = Paths.image('icons/face');
|
||||
|
||||
iconSprite.loadGraphic(path, true, 150, 150);
|
||||
iconSprite.animation.add(icon, [0], 0, false);
|
||||
iconSprite.antialiasing = true;
|
||||
iconSprite.animation.play(icon);
|
||||
|
||||
iconSprite.scale.set(0.5, 0.5);
|
||||
iconSprite.updateHitbox();
|
||||
iconSprite.setPosition(iconTextBox.x + 150 + 8, (iconTextBox.y + 16) - (iconSprite.height/2));
|
||||
}
|
||||
|
||||
function saveCharacterInfo() {
|
||||
for (stepper in [positionXStepper, positionYStepper, cameraXStepper, cameraYStepper, singTimeStepper, scaleStepper])
|
||||
@:privateAccess stepper.__onChange(stepper.label.text);
|
||||
|
||||
var xml = Xml.createElement("character");
|
||||
xml.set("isPlayer", isPlayerCheckbox.checked ? "true" : "false");
|
||||
xml.set("x", Std.string(positionXStepper.value));
|
||||
xml.set("y", Std.string(positionYStepper.value));
|
||||
xml.set("gameOverChar", gameOverCharTextBox.label.text);
|
||||
xml.set("camx", Std.string(cameraXStepper.value));
|
||||
xml.set("camy", Std.string(cameraYStepper.value));
|
||||
xml.set("holdTime", Std.string(singTimeStepper.value));
|
||||
xml.set("flipX", Std.string(flipXCheckbox.checked));
|
||||
xml.set("icon", iconTextBox.label.text);
|
||||
xml.set("scale", Std.string(scaleStepper.value));
|
||||
xml.set("antialiasing", antialiasingCheckbox.checked ? "true" : "false");
|
||||
xml.set("sprite", spriteTextBox.label.text);
|
||||
if (iconColorWheel.colorChanged)
|
||||
xml.set("color", iconColorWheel.curColor.toWebString());
|
||||
for (val in customPropertiesButtonList.buttons.members)
|
||||
xml.set(val.propertyText.label.text, val.valueText.label.text);
|
||||
|
||||
for (anim in character.animDatas)
|
||||
{
|
||||
var animXml:Xml = Xml.createElement('anim');
|
||||
animXml.set("name", anim.name);
|
||||
animXml.set("anim", anim.anim);
|
||||
animXml.set("loop", Std.string(anim.loop));
|
||||
animXml.set("fps", Std.string(anim.fps));
|
||||
var offset:FlxPoint = character.getAnimOffset(anim.name);
|
||||
animXml.set("x", Std.string(offset.x));
|
||||
animXml.set("y", Std.string(offset.y));
|
||||
if (anim.indices.length > 0)
|
||||
animXml.set("indices", anim.indices.join(","));
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
|
||||
if (onSave != null) onSave(xml);
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,9 @@ class UISliceSprite extends UISprite {
|
||||
}
|
||||
|
||||
public override function draw() @:privateAccess {
|
||||
var lastPixelPerfect:Bool = cameras[0].pixelPerfectRender;
|
||||
cameras[0].pixelPerfectRender = false;
|
||||
|
||||
var x:Float = this.x;
|
||||
var y:Float = this.y;
|
||||
|
||||
@@ -184,6 +187,7 @@ class UISliceSprite extends UISprite {
|
||||
}
|
||||
alpha = oldAlpha;
|
||||
}
|
||||
cameras[0].pixelPerfectRender = true;
|
||||
|
||||
setPosition(x, y);
|
||||
super.drawMembers();
|
||||
|
||||
Reference in New Issue
Block a user