New! Unlimited audio, video & web asset downloads! Unlimited audio, video & web assets! From $16.50/m
Advertisement
  1. Game Development
  2. Game Development
Gamedevelopment

Creating Playing Cards Dynamically Using Code for Game Jams

by
Difficulty:BeginnerLength:MediumLanguages:
Final product image
What You'll Be Creating

This tutorial is different from my earlier tutorials as this one is oriented towards game jams and game prototyping, specifically card games. We are going to create a 2D playing card deck in Unity without using any art—purely with code.

1. Components of a Playing Card Deck

A playing card deck has a total of 52 cards with 13 cards each of 4 different symbols. In order to create one using code, we will need to create these 4 symbols, the rounded rectangular base for the card, and the design on the back of the card.

The design on the back of the card can be any abstract pattern, and there are numerous ways to create one. We will be creating a simple tileable pattern which will then be tiled to create the design. We won't have any special design for the A, K, Q, and J cards.

2. Alternative Solutions

Before we start, I have to mention that there are easier solutions out there which we can use to create a deck of cards. Some of those are listed below.

  1. The obvious one is to use pre-rendered art for all the designs.
  2. The less obvious one is to use a font which contains all the necessary symbols. We can also turn the said font into a bitmap font to reduce draw calls and increase performance.

The font-based solution is the fastest and easiest one if you want to do quick prototypes.

3. Creating Textures During Runtime

The first step is to learn how to create a Texture2D using code which can then be used to create a Sprite in Unity. The following code shows the creation of a 256x256 blank texture.

The idea is to draw all the designs onto the texture before we use the Apply method. We can draw designs onto the texture pixel by pixel using the SetPixel method, as shown below.

For example, if we wanted to fill out the entire texture with a color, we could use a method like this.

Once we have a Texture2D created, we can use it to create a Sprite to be displayed on screen.

The complicated part in all this is the creation of the necessary designs on the texture.

4. Creating the Heart Shape

When it comes to the creation of the heart shape, there are many different approaches which we could use, among which are some complicated equations as well as simple mixing of shapes. We will use the mixing of shapes method as shown below, specifically the one with the triangle.

heart shape combining primitive shapes

As you have observed, we can use two circles and a square or a triangle to create the basic heart shape. This means it would miss those extra beautiful curves but would fit our purpose perfectly.

Painting a Circle

Let's brush up on some equations to paint a circle. For a circle with centre at origin and radius r, the equation for the point (x,y) on the circle is x2 + y2 = r2. Now if the centre of the circle is at (h,k) then the equation becomes  (x-h)2 + (y-k)2 = r2. So if we have a square bounding box rectangle then we can loop through all the points within that rectangle and determine which points fall inside the circle and which do not. We can easily create our PaintCircle method based on this understanding, as shown below.

Once we have the PaintCircle method, we can proceed to create our heart shape as shown below.

The variable resolution is the width and height of the texture.

5. Creating the Diamond Shape

We will discuss two ways to draw the diamond shape.

Painting a Simple Diamond

The easiest one is to extend the code used for the triangle and add an inverted triangle on the top to create the necessary shape, as shown below.

Painting a Curvy Diamond

The second one is to use another equation to create a better, curvy version of our diamond shape. We will be using this one to create the tiling design for the back side of our card. The equation for a circle derives from the original equation of an ellipse, which is (x/a)2 + (y/b)2 = r2.

This equation is the same as that of the circle when the variables a and b are both 1. The ellipse equation can then be extended into a superellipse equation for similar shapes just by changing the power, (x/a)n + (y/b)n = rn. So when n is 2 we have the ellipse, and for other values of n we will have different shapes, one of which is our diamond. We can use the approach used to arrive at the PaintCircle method to arrive at our new PaintDiamond method.

Painting a Rounded Rectangle

The same equation can be used to create our rounded rectangle card base shape by varying the value of n.

Painting a Tiling Design

Using this PaintDiamond method, we can draw five diamonds to create the tiling texture for the design on the back of our card.

tiling design and tiled back side of the card

The code for drawing the tiling design is as below.

6. Creating the Spades Shape

The spades shape is just the vertical flip of our heart shape along with a base shape. This base shape will be the same for the clubs shape as well. The below figure illustrates how we can use two circles to create this base shape.

primitive shapes used to define spades shape

The PaintSpades method will be as shown below.

7. Creating the Clubs Shape

At this point, I am sure that you can figure out how easy it has become to create the clubs shape. All we need are two circles and the base shape we created for the spades shape.

primitive shapes used to define clubs shape

The PaintClubs method will be as shown below.

8. Packing Textures

If you explore the Unity source files for this project, you'll find a TextureManager class which does all the heavy lifting. Once we have created all the necessary textures, the TextureManager class uses the PackTextures method to combine them into a single texture, thereby reducing the number of draw calls required when we use these shapes.

Using the packedAssets array, we can retrieve the bounding boxes of individual textures from the master texture named packedTexture.

Conclusion

With all the necessary components created, we can proceed to create our deck of cards as it is just a matter of properly laying out the shapes. We can either use the Unity UI to composite cards or we can create the cards as individual textures. You can explore the sample code to understand how I have used the first method to create card layouts.

We can follow the same method for creating any kind of dynamic art at runtime in Unity. Creating art at runtime is a performance-hungry operation, but it only needs to be done once if we save and reuse those textures efficiently. By packing the dynamically created assets into a single texture, we also gain the advantages of using a texture atlas.

Now that we have our playing card deck, let me know what games you are planning to create with it.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.