Log in to reply
 

Help C# Array/Collection - Cycle through Images in Custom Library



  • I should put @Jitnaught in the topic since he's the only scripting expert here. I'm still struggling with arrays. I've been successful with the "easy" ones but now I have one which is a little bit more difficult.

    By the easy ones, I mean:

    Ped[] all_ped = World.GetAllPeds();
    foreach (Ped SpawnedPed in all_ped)

    Vehicle[] all_vecs = World.GetAllVehicles();
    foreach (Vehicle vehicle in all_vecs)

    Now I'd like to do something similar cycling through a custom sprite library so that on each key press the next sprite/image would be displayed on screen. I know how to draw sprites and @Jitnaught was gracious in showing me how to display them on a key press in this post:
    https://forums.gta5-mods.com/topic/36611/c-shvdn3-change-or-delete-displayed-sprite/2

    So I've got most of the pieces, just don't know how to fill in the gaps and put them all together.

    Here are the snippets, only the first pic is displayed.

    public static Array ImageCollection;

    if (e.KeyCode == Keys.NumPad7)
    {
    ImageCollection = new string[] { "one", "two", "three" };
    foreach (String ImgString in ImageCollection)
    {
    SpriteLibrary = "john"; SpriteName = ImgString;
    }



  • readonly (string dict, string name)[] SPRITES = { ("dict1", "name1"), ("dict2", "name2") }; //the sprites you want to cycle through
    int spriteIndex = 0; //the sprite you're currently on (0 is the first sprite in the list)
    string spriteDict, spriteName; //you'll probably want to set these to SPRITES[0].dict and SPRITES[0].name in your constructor
    
    if (e.KeyCode == Keys.NumPad7)
    {
    	spriteIndex++; //go to next sprite
    	if (spriteIndex >= SPRITES.Length) spriteIndex = 0; //reset back to beginning if got to end
    	
    	//set sprite to draw with (use these in Tick)
    	spriteDict = SPRITES[spriteIndex].dict;
    	spriteName = SPRITES[spriteIndex].name;
    }
    


  • @Jitnaught Once again you simplify all the complexity for me. Once more, I'm very grateful for you help and expertise. I do have another question for you. Going through a dozen or more images would not be practical, is there a way to do this without specifying the names of the images? Using an index? Or is there a way to break up the code so that it can accommodate say 20 or more images?

    The video below is just a test with random images, not resized, not positioned. The final output will be to preview the cars and peds I have installed - but not one by one, rather by images showing all 12 cylinder Ferraris for example, or all Mustangs installed etc.



  • Not exactly sure what you mean. You're wanting to separate groups of sprites? You'd have to make an array for each group and have a variable to indicate which array to cycle through and draw.

    Let me know if that's what you're talking about so I can write an example, or if you mean something else.



  • @Jitnaught
    Sorry if my post wasn't clear.
    The line in question is
    readonly (string dict, string name)[] SPRITES = { ("dict1", "name1"), ("dict2", "name2") };

    If i had 20 images, or even a 100 images, it would be impractical to use the code above. So instead the array would be defined as holding 20 images and then each keypress would increment by 1, from 0 to 19.

    Or alternatively what would you suggest to keep the line to a reasonable length.

    Ofc the code you supplied is perfect for individual previews and that was my must have. Looping through is a nice to have.

    P.s. i would only be using one dictionary/library, filled with pictures, for a specific task.



  • If you're only using one sprite dictionary then you don't have to use the Tuple (the (string dict, string name) part). You could do this instead:

    readonly string[] SPRITE_NAMES = { "name1", "name2" }; //the sprite names you want to cycle through
    const string SPRITE_DICT = "dict1";
    int spriteIndex = 0; //the sprite you're currently on (0 is the first sprite in the list)
    string curSpriteName; //you'll probably want to set this to SPRITE_NAMES[0] in your constructor
    
    if (e.KeyCode == Keys.NumPad7)
    {
    	spriteIndex++; //go to next sprite
    	if (spriteIndex >= SPRITE_NAMES.Length) spriteIndex = 0; //reset back to beginning if got to end
    	
    	//set sprite to draw with (use this in Tick)
    	curSpriteName = SPRITE_NAMES[spriteIndex];
    }
    
    
    //draw sprite using SPRITE_DICT and curSpriteName
    


  • @Jitnaught Understood, but I'll still have to explicitly name all the images, correct?

    readonly string[] SPRITE_NAMES = { "name1", "name2", "name3"................"name20" };



  • Oh, I understand what you mean now.

    const string SPRITE_DICT = "dict1", NAME_PREFIX = "name"; //change NAME_PREFIX to whatever your sprite names start with
    const int MAX_SPRITE_NUM = 20; //the number of sprites you have in your dictionary named like "name1" "name20"
    int spriteNum = 1; //the sprite number you're on
    string curSpriteName; //you'll probably want to set this to SPRITE_NAMES[0] in your constructor
    
    if (e.KeyCode == Keys.NumPad7)
    {
    	spriteNum++; //go to next sprite number
    	if (spriteNum > MAX_SPRITE_NUM) spriteNum = 1; //reset back to beginning if got to end
    	
    	//generate sprite name using spriteNum
    	curSpriteName = NAME_PREFIX + spriteNum.ToString();
    }
    
    
    //draw sprite using SPRITE_DICT and curSpriteName
    

    This will go through sprites named "name1" "name2" ... "name20"



  • @Jitnaught Fantastic! Thank you so much.



  • @Jitnaught Just wanted to give you some feedback. Everything worked in all 3 methods and I've documented all of them. On the lighter side, I wasted 30 minutes with the last one making two really dumb mistakes, neither of which were compiler issues.

    1. After the last picture was displayed it didn't return to the first one. This took me about a minute to realize I had the Max to 20 but for the test I only had 6 images. Change to 6, problem fixed.

    2. This one took me the other 29 minutes. My original pics were numbered 1 to 6 so I toyed with the idea of removing the prefix and then thought it might come in handy. I use Img as the prefix. Then I went into OpenIV to rename the pics but since I was tired I just put an I in front instead of the full Img. So I1, I2, etc. Then I went back into the code and changed the name of the prefix.

    Or so I thought. Instead of replacing Img with I, I guess due to fatigue I forgot the last g had to be deleted too, so I had Ig instead of I.

    When I ran the code in GTA5 I could see a little white dot (super small) that I knew was my image. I screwed around making unnecessary changes to the code when I finally realized my stupid typing mistake.

    All good! Thanks again, you're a great teacher.


Log in to reply
 

Looks like your connection to GTA5-Mods.com Forums was lost, please wait while we try to reconnect.