tagwolf
Member
GM Version: GMS2
Target Platform: ALL
Download: https://host-a.net/f/226890-cardsyyz
(I found a place to upload thanks to a community suggestion! The project has all the card assets I reference but code doesn't exactly match the tutorial as it was part of some prototyping. It's got some fun goodies in it though. ENJOY!!)
Summary:
While replicating gambling machine logic, I did some research and found out that standard video poker machines are performing a continual shuffle on the card deck.
This is optional in the following tutorial. But overall, this should show you how to create a deck of card objects and shuffle them, then map the correct value to the objects you create in the gamespace.
If I get a good place to share the project files I'll upload my deck sprites and whole project. For now we'll do what we can! PM me if you would like the project or deck images to play with!
Tutorial:
Optional (depending on what you are trying to make)
I usually create several sprites, spr_spades, spr_diamonds, spr_clubs, spr_hearts, spr_cardback.
I then create multiple frames on each sprite with a value of A,2,3,4,5,6,7,8,9,J,Q,K
It's not important for the scope of this tutorial as it will depend on your game. But I'm going to move forward with the assumption that you want to use a 52 card deck of standard playing cards.
Create a script called scr_init_deck
This will fill a ds_list with 52 playing cards.
Now that we have a script that creates a deck, understand that this is only creating a list of names. In order to perform logic operations on these cards, we need some more information available. So now create another script called scr_map_card
Granted it might be a bit expressive, but for our purposes it should do fine.
For our last script, call it scr_shuffle_deck
This script does the leg work of randomizing every time we shuffle the deck (both the seed and the deck itself). If verbose is enabled it will also output our results, which is good for debugging purposes.
Object Code
** NOTE: Everything below is project specific. You don't need any of it and it's included as example of how to use the scripts above. ***
obj_deck - Create Event
obj_deck - Step Event
For the cards themselves, you can place 52 in your room or setup a for loop to stack them onto a deck you can grab, whatever works best for your use-case!
obj_card - Create Event
obj_card - Step Event (if you want card dragging and stuff include the things below)
obj_card - Left Pressed Event
obj_card - Left Released Event
Then just put the obj_deck (no sprite) in a room and you're good to go! In this example the obj_card doesn't need a sprite either as it's dynamically assigned one. obj_card's do not need to be added to your room (in THIS example).
Target Platform: ALL
Download: https://host-a.net/f/226890-cardsyyz
(I found a place to upload thanks to a community suggestion! The project has all the card assets I reference but code doesn't exactly match the tutorial as it was part of some prototyping. It's got some fun goodies in it though. ENJOY!!)
Summary:
While replicating gambling machine logic, I did some research and found out that standard video poker machines are performing a continual shuffle on the card deck.
This is optional in the following tutorial. But overall, this should show you how to create a deck of card objects and shuffle them, then map the correct value to the objects you create in the gamespace.
If I get a good place to share the project files I'll upload my deck sprites and whole project. For now we'll do what we can! PM me if you would like the project or deck images to play with!
Tutorial:
Optional (depending on what you are trying to make)
I usually create several sprites, spr_spades, spr_diamonds, spr_clubs, spr_hearts, spr_cardback.
I then create multiple frames on each sprite with a value of A,2,3,4,5,6,7,8,9,J,Q,K
It's not important for the scope of this tutorial as it will depend on your game. But I'm going to move forward with the assumption that you want to use a 52 card deck of standard playing cards.
Create a script called scr_init_deck
This will fill a ds_list with 52 playing cards.
Code:
// Destroy any existing deck
if ds_exists(deck, ds_type_list) {
ds_list_clear(deck);
show_debug_message("Deck cleared.");
} else {
deck = ds_list_create();
show_debug_message("Deck created.");
}
// Factory Card Deck Order
// Spades
ds_list_add(deck, "Ace_Spades");
ds_list_add(deck, "2_Spades");
ds_list_add(deck, "3_Spades");
ds_list_add(deck, "4_Spades");
ds_list_add(deck, "5_Spades");
ds_list_add(deck, "6_Spades");
ds_list_add(deck, "7_Spades");
ds_list_add(deck, "8_Spades");
ds_list_add(deck, "9_Spades");
ds_list_add(deck, "10_Spades");
ds_list_add(deck, "Jack_Spades");
ds_list_add(deck, "Queen_Spades");
ds_list_add(deck, "King_Spades");
// Diamonds
ds_list_add(deck, "Ace_Diamonds");
ds_list_add(deck, "2_Diamonds");
ds_list_add(deck, "3_Diamonds");
ds_list_add(deck, "4_Diamonds");
ds_list_add(deck, "5_Diamonds");
ds_list_add(deck, "6_Diamonds");
ds_list_add(deck, "7_Diamonds");
ds_list_add(deck, "8_Diamonds");
ds_list_add(deck, "9_Diamonds");
ds_list_add(deck, "10_Diamonds");
ds_list_add(deck, "Jack_Diamonds");
ds_list_add(deck, "Queen_Diamonds");
ds_list_add(deck, "King_Diamonds");
// Clubs
ds_list_add(deck, "Ace_Clubs");
ds_list_add(deck, "2_Clubs");
ds_list_add(deck, "3_Clubs");
ds_list_add(deck, "4_Clubs");
ds_list_add(deck, "5_Clubs");
ds_list_add(deck, "6_Clubs");
ds_list_add(deck, "7_Clubs");
ds_list_add(deck, "8_Clubs");
ds_list_add(deck, "9_Clubs");
ds_list_add(deck, "10_Clubs");
ds_list_add(deck, "Jack_Clubs");
ds_list_add(deck, "Queen_Clubs");
ds_list_add(deck, "King_Clubs");
// Hearts
ds_list_add(deck, "Ace_Hearts");
ds_list_add(deck, "2_Hearts");
ds_list_add(deck, "3_Hearts");
ds_list_add(deck, "4_Hearts");
ds_list_add(deck, "5_Hearts");
ds_list_add(deck, "6_Hearts");
ds_list_add(deck, "7_Hearts");
ds_list_add(deck, "8_Hearts");
ds_list_add(deck, "9_Hearts");
ds_list_add(deck, "10_Hearts");
ds_list_add(deck, "Jack_Hearts");
ds_list_add(deck, "Queen_Hearts");
ds_list_add(deck, "King_Hearts");
show_debug_message("Deck initialized.");
// Return deck data structure
return deck;
Now that we have a script that creates a deck, understand that this is only creating a list of names. In order to perform logic operations on these cards, we need some more information available. So now create another script called scr_map_card
Code:
// Card Value Mapping
card = argument0;
switch (card) {
// Spades
case ("Ace_Spades"): sprite_index = spr_spades; image_index = 0; value = 1; suit = "spades"; break;
case ("2_Spades"): sprite_index = spr_spades; image_index = 1; value = 2; suit = "spades"; break;
case ("3_Spades"): sprite_index = spr_spades; image_index = 2; value = 3; suit = "spades"; break;
case ("4_Spades"): sprite_index = spr_spades; image_index = 3; value = 4; suit = "spades"; break;
case ("5_Spades"): sprite_index = spr_spades; image_index = 4; value = 5; suit = "spades"; break;
case ("6_Spades"): sprite_index = spr_spades; image_index = 5; value = 6; suit = "spades"; break;
case ("7_Spades"): sprite_index = spr_spades; image_index = 6; value = 7; suit = "spades"; break;
case ("8_Spades"): sprite_index = spr_spades; image_index = 7; value = 8; suit = "spades"; break;
case ("9_Spades"): sprite_index = spr_spades; image_index = 8; value = 9; suit = "spades"; break;
case ("10_Spades"): sprite_index = spr_spades; image_index = 9; value = 10; suit = "spades"; break;
case ("Jack_Spades"): sprite_index = spr_spades; image_index = 10; value = 11; suit = "spades"; break;
case ("Queen_Spades"): sprite_index = spr_spades; image_index = 11; value = 12; suit = "spades"; break;
case ("King_Spades"): sprite_index = spr_spades; image_index = 12; value = 13; suit = "spades"; break;
// Diamonds
case ("Ace_Diamonds"): sprite_index = spr_diamonds; image_index = 0; value = 1; suit = "diamonds"; break;
case ("2_Diamonds"): sprite_index = spr_diamonds; image_index = 1; value = 2; suit = "diamonds"; break;
case ("3_Diamonds"): sprite_index = spr_diamonds; image_index = 2; value = 3; suit = "diamonds"; break;
case ("4_Diamonds"): sprite_index = spr_diamonds; image_index = 3; value = 4; suit = "diamonds"; break;
case ("5_Diamonds"): sprite_index = spr_diamonds; image_index = 4; value = 5; suit = "diamonds"; break;
case ("6_Diamonds"): sprite_index = spr_diamonds; image_index = 5; value = 6; suit = "diamonds"; break;
case ("7_Diamonds"): sprite_index = spr_diamonds; image_index = 6; value = 7; suit = "diamonds"; break;
case ("8_Diamonds"): sprite_index = spr_diamonds; image_index = 7; value = 8; suit = "diamonds"; break;
case ("9_Diamonds"): sprite_index = spr_diamonds; image_index = 8; value = 9; suit = "diamonds"; break;
case ("10_Diamonds"): sprite_index = spr_diamonds; image_index = 9; value = 10; suit = "diamonds"; break;
case ("Jack_Diamonds"): sprite_index = spr_diamonds; image_index = 10; value = 11; suit = "diamonds"; break;
case ("Queen_Diamonds"): sprite_index = spr_diamonds; image_index = 11; value = 12; suit = "diamonds"; break;
case ("King_Diamonds"): sprite_index = spr_diamonds; image_index = 12; value = 13; suit = "diamonds"; break;
// Clubs
case ("Ace_Clubs"): sprite_index = spr_clubs; image_index = 0; value = 1; suit = "clubs"; break;
case ("2_Clubs"): sprite_index = spr_clubs; image_index = 1; value = 2; suit = "clubs"; break;
case ("3_Clubs"): sprite_index = spr_clubs; image_index = 2; value = 3; suit = "clubs"; break;
case ("4_Clubs"): sprite_index = spr_clubs; image_index = 3; value = 4; suit = "clubs"; break;
case ("5_Clubs"): sprite_index = spr_clubs; image_index = 4; value = 5; suit = "clubs"; break;
case ("6_Clubs"): sprite_index = spr_clubs; image_index = 5; value = 6; suit = "clubs"; break;
case ("7_Clubs"): sprite_index = spr_clubs; image_index = 6; value = 7; suit = "clubs"; break;
case ("8_Clubs"): sprite_index = spr_clubs; image_index = 7; value = 8; suit = "clubs"; break;
case ("9_Clubs"): sprite_index = spr_clubs; image_index = 8; value = 9; suit = "clubs"; break;
case ("10_Clubs"): sprite_index = spr_clubs; image_index = 9; value = 10; suit = "clubs"; break;
case ("Jack_Clubs"): sprite_index = spr_clubs; image_index = 10; value = 11; suit = "clubs"; break;
case ("Queen_Clubs"): sprite_index = spr_clubs; image_index = 11; value = 12; suit = "clubs"; break;
case ("King_Clubs"): sprite_index = spr_clubs; image_index = 12; value = 13; suit = "clubs"; break;
// Hearts
case ("Ace_Hearts"): sprite_index = spr_hearts; image_index = 0; value = 1; suit = "hearts"; break;
case ("2_Hearts"): sprite_index = spr_hearts; image_index = 1; value = 2; suit = "hearts"; break;
case ("3_Hearts"): sprite_index = spr_hearts; image_index = 2; value = 3; suit = "hearts"; break;
case ("4_Hearts"): sprite_index = spr_hearts; image_index = 3; value = 4; suit = "hearts"; break;
case ("5_Hearts"): sprite_index = spr_hearts; image_index = 4; value = 5; suit = "hearts"; break;
case ("6_Hearts"): sprite_index = spr_hearts; image_index = 5; value = 6; suit = "hearts"; break;
case ("7_Hearts"): sprite_index = spr_hearts; image_index = 6; value = 7; suit = "hearts"; break;
case ("8_Hearts"): sprite_index = spr_hearts; image_index = 7; value = 8; suit = "hearts"; break;
case ("9_Hearts"): sprite_index = spr_hearts; image_index = 8; value = 9; suit = "hearts"; break;
case ("10_Hearts"): sprite_index = spr_hearts; image_index = 9; value = 10; suit = "hearts"; break;
case ("Jack_Hearts"): sprite_index = spr_hearts; image_index = 10; value = 11; suit = "hearts"; break;
case ("Queen_Hearts"): sprite_index = spr_hearts; image_index = 11; value = 12; suit = "hearts"; break;
case ("King_Hearts"): sprite_index = spr_hearts; image_index = 12; value = 13; suit = "hearts"; break;
}
return;
For our last script, call it scr_shuffle_deck
Code:
deck = argument0;
//TODO: error checking, better randomization, cards remaining,
// confirm shuffle, confirm random, confirm deck integrity.
//check if should be shuffling currently, if flipping a card we want to make sure we delete the
//correct value.
randomize()
ds_list_shuffle(deck);
var cards_in_deck = ds_list_size(deck);
if verbose
{
for (i = 0; i <= cards_in_deck; i++)
{
card = ds_list_find_value(deck, i);
show_debug_message(string(card));
}
}
show_debug_message(string(cards_in_deck)+" cards shuffled.");
return;
Object Code
** NOTE: Everything below is project specific. You don't need any of it and it's included as example of how to use the scripts above. ***
obj_deck - Create Event
Code:
// Uncomment for continuous shuffling
//shuffling = true;
//verbose = true;
deck = scr_init_deck()
// Let's create a deck card pile
// You can easily add mouse events to the cards that spawn on top of each other to pick them up.
// If I find a good place to host project files I'll include it and my tiny card deck sprites that I love a lot :)
for (var i = 0; i <= ds_list_size(deck) - 1; i++) {
var card = ds_list_find_value(deck,i);
show_debug_message(string(card));
scr_assign_card(card);
// spawn card in pile
new_card = instance_create_depth(random_range(63, 65), random_range(63, 65), 0, obj_card);
// randomize angle
new_card.image_angle = random_range(-5,5);
// set values
new_card.card_name = card;
new_card.card_suit = card_suit;
new_card.card_value = card_value
new_card.card_sprite = card_sprite;
new_card.card_image = card_image;
// set card image
//new_card.sprite_index = card_sprite;
//new_card.image_index = card_image;
// set card image face down
new_card.sprite_index = spr_cardback;
}
Code:
/// @description Main deck logic
// Determine if we need to shuffle
if (shuffling) {
scr_shuffle_deck(deck);
}
obj_card - Create Event
Code:
card_drag = false;
card_name = 0;
card_suit = 0;
card_value = 0;
card_image = 0;
card_sprite = 0;
Code:
if (card_drag) {
x = mouse_x;
y = mouse_y;
}
Code:
show_debug_message("Card Clicked");
show_debug_message("NAME: " + string(card_name));
show_debug_message("VALUE: " + string(card_value));
show_debug_message("SUIT: " + string(card_suit));
show_debug_message("SPRITE: " + string(card_sprite));
show_debug_message("IMAGE: " + string(card_image));
if (global.any_card_drag == false) {
global.any_card_drag = true;
card_drag = true;
sprite_index = card_sprite;
image_index = card_image;
}
Code:
if (card_drag == true) {
card_drag = false;
global.any_card_drag = false;
}
Last edited: