Matteo Graizzaro

Game Programmer


This project is the polished version of a prototype I developed in 4 days during a tech test for an application.
It was originally a mobile game but I repurposed it to the PC market to increase the amout of games of that type in my portfolio.

Specifications

Project goals

  • Polishing the prototype I made as a tech test for an application
  • Increasing my portfolio of PC games

One of the first challenges I had to face while prototyping the game, was how to build the card sprites. Why? Because the company provided me only sprites depicting the figures (heart, diamond, club, spade), and the numbers.
I had two possibilities in front of me:

Atlas

Use external software to combine sprites and form an atlas with all the necessary variations

VS

Combination

Generate the card sprites in real time by combining the different parts as needed

The first had the advantage of simplicity of implementation, with a dictionary and just some parameters for card size, at the cost of build size.
The latter was unexplored territory and therefore a risk, but had the big advantage of flexibility. For example, I wouldn't have struggled much replacing sprites when adding the project to my portfolio, as I had to get rid of all proprietary material.

How a card is formed

Sprite generation, I discovered, was simpler than I thought, expecially thanks to this tutorial playlist.

  • I start by creating a blank texture of the size of a card
  • I add the first layer depicting the front or back of the card, based on the card visibility
  • If the card is visible I move on to adding its number, and the two suits

Everything is made using a method called CreateLayer, that adds a texture to a list of layers, that is later processed to define the final aspect of the card, by multiplying each layer pixel colour with those of the other layers in the same position.
The result is converted into a sprite which is then assigned to a SpriteRendeder to be displayed to the player.

The main problem with this approach is how much it is dependant on the source sprites. Each position is specified by coordinates expressed in pixels, and therefore each change to the sprites will change the card appearance too.

You can explore in more detail all the processes by reading the game code itself here.

Klondike Solitaire

It's Klondike Solitaire with the classic rules, that you can find here.
From a game logic perspective there are 3 types of what in the came are coded as card containers, each with its own little quirk:

Some terms to better understand the following list:
  • Unlocked/Locked: the player can/can't interact with the card
  • Visible/Hidden: the value of the card is/is not revealed to the player

Pile

Random hidden cards followed by visible ones, that are ordered from higher to lower. When empty it can only accept a group of cards starting with a King.

Foundation

Cards ordered but lower to higher. All the cards below the last are locked. When all the foundations are full, the player wins.

Stack

Random cards the player can draw. The drawn cards are moved to a temporary different list (Waste Pile), and all but the last one are locked. If the stack is empty, all the drawn cards are recycled into it.

A big part of the game development was building strong controls to avoid wrong behaviours, and dedicate a special class to each of these card containers types helped to keep the code organized.
One flaw with my approach that later feedback revealed, was the interdependency of the card position with the gameplay logic, making me impossible to check the validity of some moves without changing the visuals, therefore making it difficult to implement a hint system.

Gameplay section

...

...
However, if I could go back in time I would:

  • ...
  • ...
  • ...