Universal-LPC-Spritesheet multiple animation sets.

edited April 2014 in Help request
Some time ago I posted about the Universal-LPC-Spritesheet. After spending some time in getting all the animations done in orx, I finally got an ini file and the code that have the animation set and all the needed links workinh.

Now my question is: How do I reuse it?
Each graphic of the spritesheet have the same sprite sizes and coordinates, and you need to play them in the same order as the other sprites. I am pretty sure I would have to create the same partitions and animation sets for each object.

I think the best way to reuse the coords and animations defined in the ini file would be to load a base object and set a new graphic by code. But I think there might be a better way to do so with the ini file and the heritage system.

The ini is quite big, in case anyone is interested in using it in a future game, the ini can be found here:

https://docs.google.com/file/d/0B0UdeUM9pB-nVmJQQkNZVU9NRUk/edit

Another problem I am having is that the hair files are not loading, they give me this error:
[20:37:41] [DISPLAY] [orxTexture.c:orxTexture_CreateFromFile():428] Failed to load bitmap [../../art/raven.png] and link it to texture.
[20:37:41] [DISPLAY] [orxGraphic.c:orxGraphic_CreateFromConfig():688] Couldn't get text or texture for graphic (Hair_Graphic).

Comments

  • edited April 2014
    Knolan wrote:
    Some time ago I posted about the Universal-LPC-Spritesheet. After spending some time in getting all the animations done in orx, I finally got an ini file and the code that have the animation set and all the needed links workinh.

    Now my question is: How do I reuse it?

    I'll answer this at the end of this post. Note that my answer is theory-only as I haven't tried it myself. :)
    Each graphic of the spritesheet have the same sprite sizes and coordinates, and you need to play them in the same order as the other sprites. I am pretty sure I would have to create the same partitions and animation sets for each object.

    I think the best way to reuse the coords and animations defined in the ini file would be to load a base object and set a new graphic by code. But I think there might be a better way to do so with the ini file and the heritage system.

    I think there's a config trick that could help, indeed. Lydesik asked me the exact same question a couple of weeks ago. I don't know if he followed the suggestion I'm about to give you, but if he did, he should be able to let us know if it works or not.
    The ini is quite big, in case anyone is interested in using it in a future game, the ini can be found here:

    https://docs.google.com/file/d/0B0UdeUM9pB-nVmJQQkNZVU9NRUk/edit

    Got it, thanks. Reading the full paths for textures in it, I believe you're not using the resource system, are you? I'd recommend having a look at my tutorial on bitbucket (no wiki entry yet) which shows how to add new resource types (such as how to store one's game content in an archive, for example).

    In this case, here's how it would be used:
    [Resource]
    Texture = ../../art ; Add other paths as needed with #
    ; Sound = ...
    ; Config = ...
    ; WatchList = ... ; This is used during dev for resource hotloading support
    
    [Character_Graphic]
    Texture = light.png
    
    [Hair_Graphic]
    Texture = leather_cap_male.png
    
    Another problem I am having is that the hair files are not loading, they give me this error:
    [20:37:41] [DISPLAY] [orxTexture.c:orxTexture_CreateFromFile():428] Failed to load bitmap [../../art/raven.png] and link it to texture.
    [20:37:41] [DISPLAY] [orxGraphic.c:orxGraphic_CreateFromConfig():688] Couldn't get text or texture for graphic (Hair_Graphic).
    

    I'm afraid I don't have enough details to diagnose the problem. I can think of two main reasons why that would fail: either raven.png isn't in the ../../art folder, or that .png file isn't readable by the library orx uses (stb_image), and I'd recommend re-saving it with gimp/photoshop and making sure it's not interlaced.

    Now for the re-use problem, I'd cheat by relying on the inheritance system.
    Knowing that both orxTEXTUREs and ORXANIMSETs are unique in memory, respectively identified by their file path and config name, as long as all the data defined for all the graphics doesn't change (ie. same sprite coordinates in all the textures), the trick would be to:
    - Create another animset with a new name but having the exact same content as the original one (can be done offline)
    - Reference this animset in the new object (can also be done offline)
    - Change the texture reference in the parent of all graphics (done at runtime)
    - Create the new object, hopefully everything would work just fine

    Let's say we want to create a "NewCharacter" that adopts the same animation pattern as "Character" but with the texture dark.png instead of light.png.

    Here's the data:
    [Character_Graphic]
    Texture = light.png
    TextureSize = (64, 64, 0) ; The Z component can remain 0
    Pivot = (32, 32, 0) ; Same remark here
    
    [Character]
    AnimationSet = CharacterAnimationSet
    
    [CharacterAnimationSet]
    ; ...
    
    [NewCharacter]
    AnimationSet = NewCharacterAnimationSet
    
    [NewCharacterAnimationSet@CharacterAnimationSet]
    

    And here's the code:
    orxConfig_PushSection("Character_Graphic");
    orxConfig_SetString("Texture", "dark.png");
    orxConfig_PopSection();
    orxOBJECT *pstNewCharacter = orxObject_CreateFromConfig("NewCharacter");
    

    Now, when you want to create a "Character", you'll need to replace the Texture before doing so:
    orxConfig_PushSection("Character_Graphic");
    orxConfig_SetString("Texture", "light.png");
    orxConfig_PopSection();
    orxOBJECT *pstCharacter = orxObject_CreateFromConfig("Character");
    

    Lastly, this approach could be rendered a bit more generic by adding a custom config property to your object, let's call it "Texture" to keep things simple. We'll also create the new animation set on the fly.
    We'll assume we set the config property RunTime.Character with the type of character we want to create (in this case, it's "NewCharacter") prior to creating the character itself.

    Here's an example, this time done as a simple timeline/commands. :)
    [Character]
    Texture = light.png
    ; Everything else in it as before
    
    [NewCharacter]
    Texture = dark.png
    ; No need to add the AnimationSet manually
    
    [T-CreateGenericCharacter]
    0 =>>>Get RunTime Character # ; We push the content of RunTime.Character 3 times on the stack
        > Config.SetParent "<_AS" CharacterAnimationSet # ; This will create the section "NewCharacter_AS", inheriting from CharacterAnimationSet and push the name of the new section on the stack
        > Get RunTime Character # ; Re-pushing the content of RunTime.Character on the stack as we'll need it prior to the animset section
          Set < AnimationSet < # ; Here we set NewCharacter.AnimationSet = NewCharacter_AS
        > Get < Texture # ; Pushing the name of the texture stored in NewCharacter.Texture (dark.png) on the stack
          Set Character_Graphic Texture < # ; Setting Character_Graphic.Texture = dark.png
          Object.Create < ; Finally creating an instance of NewCharacter
    

    Let me know if this work (and if you have any other questions)! :)
  • edited April 2014
    The Resource didn't work, is there a version required? I am using 1.4 right now.

    [strike]I tried the Section overload method and the object is created, but it is not rendered. Any Ideas?[/strike]

    EDIT: The object was being rendered at Z: -1, thus not appearing in my scene.

    Another very strange thing is that this code is getting my unity stuck a lot o.O


    [strike]I tried changing the graphic with:
        //orxOBJECT* baseBow = orxObject_CreateFromConfig("Character");
        //orxGRAPHIC* bowGraphic = orxGraphic_CreateFromConfig("Equip_Bow_Graphic");
        //orxGraphic_SetData(orxOBJECT_GET_STRUCTURE(baseBow, GRAPHIC), orxGraphic_GetData(bowGraphic));
    

    But that doesn't work either.[/strike]
  • edited April 2014
    Knolan wrote:
    The Resource didn't work, is there a version required? I am using 1.4 right now.
    Ah yes, you'll need at least 1.5 but I'd recommend using the latest from the repository as always. =)
    Another very strange thing is that this code is getting my unity stuck a lot o.O

    That's very strange indeed, I don't see why that would be related but you can always turn the physics debug on to see if bodies are different in done way out not.
  • edited April 2014
    By unity I meant the Ubuntu graphic interface. I had 3 crashes using this code at work. I will test on windows today.

    Edit:

    Just adding, I think I finally got it done in the way I needed it. Not sure it this is the best way, but it i have not complains this far.
    orxOBJECT* createLPC_Object(const orxSTRING name, groupIds id){
    
        orxConfig_PushSection("Character_Graphic");
        orxConfig_SetString("Texture", name);
        orxConfig_PopSection();
    
        char newSection[64], animSet[64], heritage[64];
        orxString_NPrint(newSection, sizeof(newSection), "NewLPC_Sprite%u", lpcCount);
        orxString_NPrint(animSet, sizeof(animSet), "NewLPC_SpriteAnimSet%u", lpcCount);
        orxString_NPrint(heritage, sizeof(heritage), "NewLPC_SpriteAnimSet%u@CharacterAnimationSet", lpcCount);
    
        orxConfig_PushSection(heritage);
        orxConfig_PopSection();
    
        orxConfig_PushSection(newSection);
        orxConfig_SetString("AnimationSet", animSet);
        orxConfig_SetString("Position", "(0, 0, 1.0)");
        orxConfig_SetString("Graphic", "Character_Graphic_Start");
        orxConfig_PopSection();
    
        orxOBJECT* newObject = orxObject_CreateFromConfig(newSection);
        orxObject_SetGroupID(newObject, groupIdsIndex.id[id]);
    
        lpcCount++;
    
        return newObject;
    
    }
    
    

    lpcCount is a static global orxU32 that is used to avoid overloading an object (if I use the same section name the graphics will change for everyone).

    groupIdsIndex keeps track of the ids, since they are an orxU32 in the code and a string is the config.
  • edited April 2014
    Sounds good!

    The only issue I see with your code is that you'll have one animset per instance of character and not per type of character, which means animsets get duplicated in memory. It's really a minor inconvenience though as I don't think you have 10 000's units live at the same time.
Sign In or Register to comment.