Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.84k stars 819 forks source link

AssetManager, getTextures, wrong sorting (now only alphabetic, need to be alphabetic/numeric) #934

Closed corcimaria closed 7 years ago

corcimaria commented 7 years ago

if i have resources image_1 ... image_14,

var out:Vector.<String> = new <String>[];
for (var u:Number = 1; u < 15; u++) {
 out.push("image_" + u);
 }

out.sort(Array.CASEINSENSITIVE);
trace(out); 
// image_1,image_10,image_11,image_12,image_13,image_14,image_2,image_3,image_4,image_5,image_6,image_7,image_8,image_9

now Movieclip will play in wrong order frames

PrimaryFeather commented 7 years ago

Mhm, the reason for that is that "Array.sort" doesn't support numeric sorting of strings. Typically, people simply add leading zeros to their image names, e.g. image_01, image_02, etc.

Would that be possible for you, as well?

JohnBlackburne commented 7 years ago

If you want them to sort in the expected order, you could add a zero before numbers less than 10, e.g.

out.push( _u < 10 ? "image0" + u : "image" + u);

corcimaria commented 7 years ago

if i add 0 before number, same results //image_01,image_010,image_011,image_012,image_013,image_014,image_02,image_03,image_04,image_05,image_06,image_07,image_08,image_09

corcimaria commented 7 years ago

i use custom sorting in getTextures, like:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var aA = a.replace(reA, "");
    var bA = b.replace(reA, "");
    if(aA === bA) {
        var aN = parseInt(a.replace(reN, ""), 10);
        var bN = parseInt(b.replace(reN, ""), 10);
        return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
        return aA > bA ? 1 : -1;
    }
}

and this work

PrimaryFeather commented 7 years ago

I wan't clear enough — please follow John's advice: the zero only needs to be added when the number is smaller than ten (i.e., 0-9).

corcimaria commented 7 years ago

yes, this work, tnx

PrimaryFeather commented 7 years ago

i use custom sorting in getTextures, like [...]

Yes, perhaps I should add such a method, too. On the other hand, the built-in sort doesn't create any temporary objects, which is an advantage for a long list of textures. Nevertheless: I agree, it would be nice not to have to fall back to such workarounds.

PrimaryFeather commented 7 years ago

Thanks for the heads-up, in any case!

corcimaria commented 7 years ago

when desigher save for me somting animation, i need any time add this 0, and this can be many times, when we check animation, not very comfortable.

JohnBlackburne commented 7 years ago

You can use the other behaviour of Vector.sort(), and not pass constant like Array.CASEINSENSITIVE but pass a function. Inside that function you can extract the numbers from the strings and compare them numerically.

PrimaryFeather commented 7 years ago

Yes, I could definitely do that — I put it on my TODO list!