mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-23 08:07:54 -05:00
Tweaks and improvements to the animation editor
This commit is contained in:
parent
c17d48f39e
commit
338342ad5e
4 changed files with 128 additions and 47 deletions
|
@ -58,6 +58,7 @@ class BaseCharacter extends Bopper
|
|||
*/
|
||||
public var dropNoteCounts(default, null):Array<Int>;
|
||||
|
||||
@:allow(funkin.ui.animDebugShit.DebugBoundingState)
|
||||
final _data:CharacterData;
|
||||
final singTimeSec:Float;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
return globalOffsets = value;
|
||||
}
|
||||
|
||||
@:allow(funkin.ui.animDebugShit.DebugBoundingState)
|
||||
var animOffsets(default, set):Array<Float> = [0, 0];
|
||||
|
||||
public var originalPosition:FlxPoint = new FlxPoint(0, 0);
|
||||
|
|
|
@ -32,6 +32,9 @@ import openfl.net.FileReference;
|
|||
import openfl.net.URLLoader;
|
||||
import openfl.net.URLRequest;
|
||||
import openfl.utils.ByteArray;
|
||||
import funkin.input.Cursor;
|
||||
import funkin.play.character.CharacterData.CharacterDataParser;
|
||||
import funkin.util.SortUtil;
|
||||
|
||||
using flixel.util.FlxSpriteUtil;
|
||||
|
||||
|
@ -71,7 +74,7 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
Paths.setCurrentLevel('week1');
|
||||
|
||||
var str = Paths.xml('ui/offset-editor-view');
|
||||
var str = Paths.xml('ui/animation-editor/offset-editor-view');
|
||||
uiStuff = RuntimeComponentBuilder.fromAsset(str);
|
||||
|
||||
// uiStuff.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET;
|
||||
|
@ -109,6 +112,8 @@ class DebugBoundingState extends FlxState
|
|||
initSpritesheetView();
|
||||
initOffsetView();
|
||||
|
||||
Cursor.show();
|
||||
|
||||
uiStuff.cameras = [hudCam];
|
||||
|
||||
add(uiStuff);
|
||||
|
@ -124,7 +129,7 @@ class DebugBoundingState extends FlxState
|
|||
spriteSheetView = new FlxGroup();
|
||||
add(spriteSheetView);
|
||||
|
||||
var tex = Paths.getSparrowAtlas('characters/temp');
|
||||
var tex = Paths.getSparrowAtlas('characters/BOYFRIEND');
|
||||
// tex.frames[0].uv
|
||||
|
||||
bf = new FlxSprite();
|
||||
|
@ -239,11 +244,15 @@ class DebugBoundingState extends FlxState
|
|||
txtOffsetShit.cameras = [hudCam];
|
||||
offsetView.add(txtOffsetShit);
|
||||
|
||||
animDropDownMenu = new FlxUIDropDownMenu(630, 20, FlxUIDropDownMenu.makeStrIdLabelArray(['weed'], true));
|
||||
animDropDownMenu = new FlxUIDropDownMenu(0, 0, FlxUIDropDownMenu.makeStrIdLabelArray(['weed'], true));
|
||||
animDropDownMenu.cameras = [hudCam];
|
||||
// Move to bottom right corner
|
||||
animDropDownMenu.x = FlxG.width - animDropDownMenu.width - 20;
|
||||
animDropDownMenu.y = FlxG.height - animDropDownMenu.height - 20;
|
||||
offsetView.add(animDropDownMenu);
|
||||
|
||||
var characters:Array<String> = CoolUtil.coolTextFile(Paths.txt('characterList'));
|
||||
var characters:Array<String> = CharacterDataParser.listCharacterIds();
|
||||
characters.sort(SortUtil.alphabetically);
|
||||
|
||||
var charDropdown:DropDown = cast uiStuff.findComponent('characterDropdown');
|
||||
for (char in characters)
|
||||
|
@ -265,19 +274,16 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
if (FlxG.mouse.justPressed)
|
||||
{
|
||||
mouseOffset.set(FlxG.mouse.x - -swagChar.offset.x, FlxG.mouse.y - -swagChar.offset.y);
|
||||
// oldPos.set(swagChar.offset.x, swagChar.offset.y);
|
||||
// oldPos.set(FlxG.mouse.x, FlxG.mouse.y);
|
||||
mouseOffset.set(FlxG.mouse.x - -swagChar.animOffsets[0], FlxG.mouse.y - -swagChar.animOffsets[1]);
|
||||
}
|
||||
|
||||
if (FlxG.mouse.pressed)
|
||||
{
|
||||
swagChar.offset.x = (FlxG.mouse.x - mouseOffset.x) * -1;
|
||||
swagChar.offset.y = (FlxG.mouse.y - mouseOffset.y) * -1;
|
||||
swagChar.animOffsets = [(FlxG.mouse.x - mouseOffset.x) * -1, (FlxG.mouse.y - mouseOffset.y) * -1];
|
||||
|
||||
swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, [Std.int(swagChar.offset.x), Std.int(swagChar.offset.y)]);
|
||||
swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, swagChar.animOffsets);
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.offset;
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +298,11 @@ class DebugBoundingState extends FlxState
|
|||
swagText.text = str + ": " + Std.string(value);
|
||||
}
|
||||
|
||||
function clearInfo()
|
||||
{
|
||||
txtGrp.clear();
|
||||
}
|
||||
|
||||
function checkLibrary(library:String)
|
||||
{
|
||||
trace(Assets.hasLibrary(library));
|
||||
|
@ -321,7 +332,7 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
var lv:DropDown = cast uiStuff.findComponent("swapper");
|
||||
lv.selectedIndex = 1;
|
||||
curView = OFFSETSHIT;
|
||||
curView = ANIMATIONS;
|
||||
if (swagChar != null)
|
||||
{
|
||||
FlxG.camera.focusOn(swagChar.getMidpoint());
|
||||
|
@ -335,7 +346,7 @@ class DebugBoundingState extends FlxState
|
|||
spriteSheetView.visible = true;
|
||||
offsetView.visible = false;
|
||||
offsetView.active = false;
|
||||
case OFFSETSHIT:
|
||||
case ANIMATIONS:
|
||||
spriteSheetView.visible = false;
|
||||
offsetView.visible = true;
|
||||
offsetView.active = true;
|
||||
|
@ -365,14 +376,14 @@ class DebugBoundingState extends FlxState
|
|||
+ 1);
|
||||
else
|
||||
animDropDownMenu.selectedId = Std.string(0);
|
||||
animDropDownMenu.callback(animDropDownMenu.selectedId);
|
||||
playCharacterAnimation(animDropDownMenu.selectedId, true);
|
||||
}
|
||||
if (FlxG.keys.justPressed.LBRACKET || FlxG.keys.justPressed.Q)
|
||||
{
|
||||
if (Std.parseInt(animDropDownMenu.selectedId) - 1 >= 0) animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) - 1);
|
||||
else
|
||||
animDropDownMenu.selectedId = Std.string(animDropDownMenu.length - 1);
|
||||
animDropDownMenu.callback(animDropDownMenu.selectedId);
|
||||
playCharacterAnimation(animDropDownMenu.selectedId, true);
|
||||
}
|
||||
|
||||
// Keyboards controls for general WASD "movement"
|
||||
|
@ -380,16 +391,29 @@ class DebugBoundingState extends FlxState
|
|||
// and then it's just played and updated from the animDropDownMenu callback, which is set in the loadAnimShit() function probabbly
|
||||
if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S || FlxG.keys.justPressed.D || FlxG.keys.justPressed.A)
|
||||
{
|
||||
var missShit:String = '';
|
||||
var suffix:String = '';
|
||||
var targetLabel:String = '';
|
||||
|
||||
if (FlxG.keys.pressed.SHIFT) missShit = 'miss';
|
||||
if (FlxG.keys.pressed.SHIFT) suffix = 'miss';
|
||||
|
||||
if (FlxG.keys.justPressed.W) animDropDownMenu.selectedLabel = 'singUP' + missShit;
|
||||
if (FlxG.keys.justPressed.S) animDropDownMenu.selectedLabel = 'singDOWN' + missShit;
|
||||
if (FlxG.keys.justPressed.A) animDropDownMenu.selectedLabel = 'singLEFT' + missShit;
|
||||
if (FlxG.keys.justPressed.D) animDropDownMenu.selectedLabel = 'singRIGHT' + missShit;
|
||||
if (FlxG.keys.justPressed.W) targetLabel = 'singUP$suffix';
|
||||
if (FlxG.keys.justPressed.S) targetLabel = 'singDOWN$suffix';
|
||||
if (FlxG.keys.justPressed.A) targetLabel = 'singLEFT$suffix';
|
||||
if (FlxG.keys.justPressed.D) targetLabel = 'singRIGHT$suffix';
|
||||
|
||||
animDropDownMenu.callback(animDropDownMenu.selectedId);
|
||||
if (targetLabel != animDropDownMenu.selectedLabel)
|
||||
{
|
||||
// Play the new animation if the IDs are the different.
|
||||
// Override the onion skin.
|
||||
animDropDownMenu.selectedLabel = targetLabel;
|
||||
playCharacterAnimation(animDropDownMenu.selectedId, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replay the current animation if the IDs are the same.
|
||||
// Don't override the onion skin.
|
||||
playCharacterAnimation(animDropDownMenu.selectedId, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.F)
|
||||
|
@ -401,16 +425,16 @@ class DebugBoundingState extends FlxState
|
|||
if (FlxG.keys.justPressed.SPACE)
|
||||
{
|
||||
animDropDownMenu.selectedLabel = 'idle';
|
||||
animDropDownMenu.callback(animDropDownMenu.selectedId);
|
||||
playCharacterAnimation(animDropDownMenu.selectedId, true);
|
||||
}
|
||||
|
||||
// Playback the animation
|
||||
if (FlxG.keys.justPressed.ENTER) animDropDownMenu.callback(animDropDownMenu.selectedId);
|
||||
if (FlxG.keys.justPressed.ENTER) playCharacterAnimation(animDropDownMenu.selectedId, false);
|
||||
|
||||
if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.UP || FlxG.keys.justPressed.DOWN)
|
||||
{
|
||||
var animName = animDropDownMenu.selectedLabel;
|
||||
var coolValues:Array<Float> = swagChar.animationOffsets.get(animName);
|
||||
var coolValues:Array<Float> = swagChar.animationOffsets.get(animName).copy();
|
||||
|
||||
var multiplier:Int = 5;
|
||||
|
||||
|
@ -433,18 +457,38 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
if (FlxG.keys.justPressed.ESCAPE)
|
||||
{
|
||||
var outputString:String = "";
|
||||
|
||||
for (i in swagChar.animationOffsets.keys())
|
||||
{
|
||||
outputString += i + " " + swagChar.animationOffsets.get(i)[0] + " " + swagChar.animationOffsets.get(i)[1] + "\n";
|
||||
}
|
||||
|
||||
outputString.trim();
|
||||
saveOffsets(outputString);
|
||||
var outputString = FlxG.keys.pressed.CTRL ? buildOutputStringOld() : buildOutputStringNew();
|
||||
saveOffsets(outputString, FlxG.keys.pressed.CTRL ? swagChar.characterId + "Offsets.txt" : swagChar.characterId + ".json");
|
||||
}
|
||||
}
|
||||
|
||||
function buildOutputStringOld():String
|
||||
{
|
||||
var outputString:String = "";
|
||||
|
||||
for (i in swagChar.animationOffsets.keys())
|
||||
{
|
||||
outputString += i + " " + swagChar.animationOffsets.get(i)[0] + " " + swagChar.animationOffsets.get(i)[1] + "\n";
|
||||
}
|
||||
|
||||
outputString.trim();
|
||||
|
||||
return outputString;
|
||||
}
|
||||
|
||||
function buildOutputStringNew():String
|
||||
{
|
||||
var charData:CharacterData = swagChar._data.copy();
|
||||
|
||||
for (charDataAnim in animations)
|
||||
{
|
||||
var animName:String = charDataAnim.name;
|
||||
charDataAnim.offsets = swagChar.animationOffsets.get(animName);
|
||||
}
|
||||
|
||||
return SerializerUtil.toJson(charData, true);
|
||||
}
|
||||
|
||||
var swagChar:BaseCharacter;
|
||||
|
||||
/*
|
||||
|
@ -467,35 +511,51 @@ class DebugBoundingState extends FlxState
|
|||
generateOutlines(swagChar.frames.frames);
|
||||
bf.pixels = swagChar.pixels;
|
||||
|
||||
var animThing:Array<String> = [];
|
||||
clearInfo();
|
||||
addInfo(swagChar._data.assetPath, "");
|
||||
addInfo('Width', bf.width);
|
||||
addInfo('Height', bf.height);
|
||||
|
||||
characterAnimNames = [];
|
||||
|
||||
for (i in swagChar.animationOffsets.keys())
|
||||
{
|
||||
animThing.push(i);
|
||||
characterAnimNames.push(i);
|
||||
trace(i);
|
||||
trace(swagChar.animationOffsets[i]);
|
||||
}
|
||||
|
||||
animDropDownMenu.setData(FlxUIDropDownMenu.makeStrIdLabelArray(animThing, true));
|
||||
animDropDownMenu.setData(FlxUIDropDownMenu.makeStrIdLabelArray(characterAnimNames, true));
|
||||
animDropDownMenu.callback = function(str:String) {
|
||||
playCharacterAnimation(str, true);
|
||||
};
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
dropDownSetup = true;
|
||||
}
|
||||
|
||||
private var characterAnimNames:Array<String>;
|
||||
|
||||
function playCharacterAnimation(str:String, setOnionSkin:Bool = true)
|
||||
{
|
||||
if (setOnionSkin)
|
||||
{
|
||||
// clears the canvas
|
||||
onionSkinChar.pixels.fillRect(new Rectangle(0, 0, FlxG.width * 2, FlxG.height * 2), 0x00000000);
|
||||
|
||||
onionSkinChar.stamp(swagChar, Std.int(swagChar.x - swagChar.offset.x), Std.int(swagChar.y - swagChar.offset.y));
|
||||
onionSkinChar.stamp(swagChar, Std.int(swagChar.x), Std.int(swagChar.y));
|
||||
onionSkinChar.alpha = 0.6;
|
||||
}
|
||||
|
||||
var animName = animThing[Std.parseInt(str)];
|
||||
swagChar.playAnimation(animName, true); // trace();
|
||||
trace(swagChar.animationOffsets.get(animName));
|
||||
var animName = characterAnimNames[Std.parseInt(str)];
|
||||
swagChar.playAnimation(animName, true); // trace();
|
||||
trace(swagChar.animationOffsets.get(animName));
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.offset;
|
||||
};
|
||||
dropDownSetup = true;
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
}
|
||||
|
||||
var _file:FileReference;
|
||||
|
||||
function saveOffsets(saveString:String)
|
||||
function saveOffsets(saveString:String, fileName:String)
|
||||
{
|
||||
if ((saveString != null) && (saveString.length > 0))
|
||||
{
|
||||
|
@ -503,7 +563,7 @@ class DebugBoundingState extends FlxState
|
|||
_file.addEventListener(Event.COMPLETE, onSaveComplete);
|
||||
_file.addEventListener(Event.CANCEL, onSaveCancel);
|
||||
_file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError);
|
||||
_file.save(saveString, swagChar.characterId + "Offsets.txt");
|
||||
_file.save(saveString,);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -543,5 +603,5 @@ class DebugBoundingState extends FlxState
|
|||
enum abstract ANIMDEBUGVIEW(String)
|
||||
{
|
||||
var SPRITESHEET;
|
||||
var OFFSETSHIT;
|
||||
var ANIMATIONS;
|
||||
}
|
||||
|
|
|
@ -26,4 +26,23 @@ class SortUtil
|
|||
{
|
||||
return FlxSort.byValues(order, a.data.strumTime, b.data.strumTime);
|
||||
}
|
||||
|
||||
public static inline function alphabetically(a:String, b:String)
|
||||
{
|
||||
a = a.toUpperCase();
|
||||
b = b.toUpperCase();
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue