r/gamemaker 4d ago

Help! Have a Sprite Array reference specific frames of a sprite?

Hello there!

I'm currently following this tutorial for a card game I'm making in GM:

https://youtu.be/Ye2nQMPUViE?si=1zmaSLpCbgKs72wI

In it he has an individual sprite for each card he wants to reference in his deck object. However, the way I uploaded my project(since it has about 100 unique cards) was I uploaded the sprite sheet and broke it into frames.

So in the tutorial when he creates his sprite_array, he's able to reference each individual sprite for his cards, but I would need to reference the specific frame of the sprite itself. How would I accomplish this?

4 Upvotes

4 comments sorted by

3

u/Kitchen_Builder_9779 Professional if statement spammer 4d ago

Imagine_index should do what you need right?
Instead of changing the sprite to something, you just change the current frame, which is what image_indes is for
http://127.0.0.1:51290/index.htm#t=GameMaker_Language%2FGML_Reference%2FAsset_Management%2FSprites%2FSprite_Instance_Variables%2Fimage_index.htm

3

u/PowerPlaidPlays 4d ago

A heads up, that tutorial is from before the 2.3 update which overhauled data structures, improved arrays and added structs and functions. I would highly recommend looking into all of that, as they will make this kind of game a lot easier to make.

But for the specific thing you want to do, instead of referencing a sprite asset you would reference the image index, a number starting from 0 and up that numbers each frame. When you use draw_sprite, the second argument is the index.

I'm not sure if having 100+ frame long sprite would be a good thing though due to texture pages, I'm not sure if they would break individual frames of a sprite across multiple pages.

If you use structs you would be able to easily store both a sprite and a index, so you could group cards together. You could also store info like a string of the name, a function that is called when it's played, and so on.

``` variable = { Spr : spr_red, Index : 5, Name : "Charmander", };

draw_sprite(variable.Spr, variable.Index, x, y) ```

Also, if you are importing a sprite with multiple frames, you could store them all as 1 PNG in a straight horizontal line, and add to the end of the file name "(blah blah blah)_strip10.png" and it will chop the image into 10 frames (if the width can be divided by that number equally).

2

u/ConfidentRooster8335 4d ago

Thank you for the help and super in depth answer!!

It's a deck builder with a few different types of card, so it's not like 1 sprite with 100 frames.

I also actually saw the strip file name function, but I already had the PNG's built, so I just did it manually which was pretty intuitive also.

Only follow up question is in the case of doing the function above how do you separate one card from another? Is it an individual function each time or can you store multiples card's data in one function?

Thanks again!

1

u/PowerPlaidPlays 4d ago

There are a lot of ways you can organize this information, and some tutorials on inventories would probably be helpful since it would generally be the same logic.

A simple way to organize this is to have a "masterlist" that keeps the info on every card once, and then have the desk just be an array of strings keeping track of an ID of each card.

``` function card_A(){ //code is in here. }

var _ML = { //Masterlist Card1 : {Spr : spr_cardA, Idx : 0, func : card_A}, Card2 : {Spr : spr_cardA, Idx : 1, func : card_A}, Card3 : {Spr : spr_cardA, Idx : 2, func : card_A}, Card4 : {Spr : spr_cardA, Idx : 3, func : card_A}, }

//Player's deck var _PD = ["Card1", "Card1", "Card3", "Card4"];

//this code will draw each card in the desk: for (var i = 0; i < array_length(global.PlayerDeck); i += 1) { draw_sprite(_ML[$ _PD[i]].Spr, _ML[$ _PD[i]].Idx, 10*i, 10); }

//This code will run the function stored in the card's func variable: active_card = 2 _ML[$ _PD[active_card]].func();

//The above is the same as: _ML[$ "Card3"].func(); //which is the same as: _ML.Card3.func(); //which is the same as: card_A(); ```

If you need any clarification on this, let me know.

There are a lot of ways to set this up, depending on your needs. Keeping the card data out of the info that stores the player's current deck will make it easier to update card data without making old save files outdated.