I would first define the cards as pure data. At least until GMS 2.3 update comes out with various new stuff (lightweight data objects etc), the most straightforward method to define data - at least I use this a lot - is enumerator indexed arrays. For basic example, let's assume all the data we have for the cards is name, cost, attack and defense. Let's also define just two cards, a Goblin and a Knight.
First we define all our cards as enumerator values. An enumerator assigns an integer value for each of its member, starting from zero. Enumerators are global variables and can be referenced anywhere. (When game is compiled, enumerator references are replaced with actual numbers. You use them in code for convenience so you don't need to remember a bunch of numbers and have descriptive names instead.)
Code:
// Set these enumerators up in some descriptively named object, like obj_cards
enum Card_Type {
Goblin,
Knight
}
This means Card.Goblin stands for value 0, and Card.Knight is 1. We define card data in same manner.
Code:
enum Card_Data {
Name,
Cost,
Attack,
Defense
}
With these, we can define arrays to hold the card data, and a convenience function that creates the cards, to save us some typing time.
Code:
// Card creation function:
///@function scr_card_create(type, name, cost, attack, defense)
///@description Creates a card data array.
///@param enum Card type enumerator.
///@param name Card name.
///@param cost Cost value.
///@param attack Attack value.
///@param defense Defense value.
var _Card = [];
_Card[Card_Data.Name] = argument[1];
_Card[Card_Data.Cost] = argument[2];
_Card[Card_Data.Attack] = argument[3];
_Card[Card_Data.Defense] = argument[4];
global.Cards[@ argument[0]] = _Card;
Code:
// Setting up the cards in obj_cards continues with this:
global.Cards = [];
scr_card_create(Card_Type.Goblin, "Goblin", 1, 1, 1);
scr_card_create(Card_Type.Knight, "Knight", 3, 4, 4);
Now you have a
global.Cards array tha contains an array in each entry for a specific card. To for example figure out the attack value of the knight, you would:
Code:
var _This_Card = global.Cards[Card_Type.Knight];
var _Attack_Value = _This_Card[Card_Data.Attack];
Now you can just create a generic
obj_card object and when you create instances out of it, you pass it the
Card_Type enumerator value, which the instance can then use to fetch and display correct sprite, values and so on.
Code:
var _New_Card = instance_create_layer(_PosX, _PosY, "Card_Layer", obj_card);
_New_Card.Type = Card_Type.Knight;