“If you want it to be playable and more interesting you need to jazz it up a bit!”
That’s what’s been cooking in my head from the time I’ve finished implementing the back end for the game of Memory (Match Up, Concentration, or whatever you are used to call it). As a proof of concept, I’ve coded a very simple application, aka the front end for the game – juts to have a workable user interface.
Now, the time has come to finish the series and introduce a more eye candy version of the game, one that’s not using dull buttons with numbers for field display values but that actually looks like card game type of Memory, with nice fancy images/icons for game fields. Why stop there? Why not go a step forward and introduce a new dimension for the game: make it 3D having fields appear on planes/layers, so players need to switch between planes to match a pair.
I guess you know you can run your browser in full screen mode using the F11 shortcut key. Windows Explorer also supports this feature.
Running in full screen, where an application UI covers the entire screen, over the TaskBar and any Desktop/Tool bars, is handy when a user has a limited screen size (laptops) or when you just want more to be visible by the browser or the Windows Explorer.
Running your application in full screen might also be handy if your users want to be focused only on your application’s window.
In my previous post, Coding a Game of Memory in Delphi – OOP Model, I’ve been developing the model, aka the back end, for the Memory (Match Up, Concentration, …) game. The idea was to separate the game logic from the user interface (aka the front end). As a result a few classes were introduced: TPlayer, TField and, of course, the main class/object TMemoryGame implementing all the code required to run the game.
Having only the model does not help us much if we actually want to play the game. Therefore, this time, we go into building the user interface in Delphi.
Since the TMemoryGame class is framework agnostic (and not platform specific), it is up for you to decide if you would like to do a classic Windows VCL application, a FireMonkey Android mobile game or something that works on a Mac. To make it quick and simple, I’ll go old-style VCL school.
Memory, Match Up, Concentration … there are many names for a simple card game I’m certain you’ve been playing with your friends at some point during your childhood. I’m also certain you are still playing it from time to time (at least I do with my kids). Just a few months ago, I’ve tried my “luck” against a robot in CosmoCaixa, Barcelona (image).
The rules of the game are simple: cards are laid face down on a surface and two, per turn, are flipped face up. If the flipped cards are a match pair (same looking, same rank, save value) the player claims (wins) the pair and plays again. If they are not a match, cards are flipped face down again, and the next player takes turn. The game ends when all the pairs have been claimed and the player with the most claimed pairs is the winner. If all players have the same number of claimed pairs we can agree to have a tie, or to have the last player be the winner.
I’ve always been a fan of such simple games – from my point of view they are a perfect pick if you want to start learning programming – have fun and sharpen your developer skills at the same time.
While there are Delphi implementations of the game you can find online – most of them have heavily mixed the visual presentation of the game (user interface) with the model (implementation of the game logic).
In my version of Memory, I’d like to separate the user interface (front end) from the game logic (back end) as much as possible. I want to create a game model in OOP style – where the game logic does not interact (or as less as possible) with the front end.
Have you ever needed for a specific Delphi control, like a TButton, to have just one more property or a method that is a “must have” for your current application?
Most Delphi developers, when they need a TMySuperButton, would either look for a third-party VCL solution or would try creating a derived control.
What if you do not want to have this MySuperButton permanently in the Component/Tool Palette – since it solves one problem only for this particular application you are developing?
What’s more … how about having a TButton with more properties and methods, some application specific extra behavior, and not TMySupperButton?
How about extending what TButton has without the need to create a derived class with a different name?
As the Help states, The TStatusBar Delphi control displays a row of panels, usually aligned at the bottom of a form. Each panel is represented by a TStatusPanel object listed in the Panels property.
Much like any other VCL control, the TStatusBar can be adopted and extended to offer greater functionality. A simple case would be to use the status bar to display long hints from other controls.
What does not come out of the box is the possibility to have each panel on a status bar display its own hint (tooltip) when the mouse “stops” over a panel.
Even though the TStatusBar provides the Hint and ShowHint properties to let you assign the tooltip text which appears when the user moves the mouse over the control – you cannot have each panel on a status bar have its own specific hint!
You cannot? You can! Here’s how to implement TStatusPanel.Hint for each panel on a status bar…
Tab set controls are commonly used to display tabbed pages within a dialog box.
The TTabControl control can be used to add a control with multiple tab settings to a form. The TTabSet control presents horizontal tabs users can click to initiate actions.
Both TTabSet and TTabControl are a single object (not made up of several pages hosting different controls, like the case is with TPageControl). When the current tab changes, the tab control must directly update its contents to reflect the change in an OnChange event handler.
To have a set of tabs for the tab set control you specify a list of strings as the value of the Tabs property. Ever wondered how to have specific hint for each tab?
Say you are developing a game like Chess, Go, Checkers, Tic-Tac-Toe or Memory. In each of those games the game board is a rectangle looking playfield of different size (rows x columns). Tic-Tac-Toe is 3×3, Checkers is 8×8, while Go can be 19×19 or 13×13 and similar.
In a game with an arbitrary number of game fields you might want to have the board look as closely to square as possible (rectangle where height and width are the same). Think of Memory. Let’s say we have 24 cards, that is 12 pairs. If you want to place them in a rectangular grid, most similar to square, you would go for 4 x 6 (or 6 x 4) board size (as it would look more square like than 3 x 8 and 2 x 12 or 1 x 24 would be too wide).
Delphi’s TGridPanel control is an ideal pick when you want to create grid-flow like user interface layout for your controls.
To place controls on a grid panel you specify the number of rows and columns (RowCollection and ColumnCollection properties) and simply drop a control on it. Unlike standard TPanel, when you drop a control on a GridPanel it will be placed in the next available empty cell in the grid. As you add more controls the grid will grow either by rows or columns being added automagically (or not, if the ExpandStyle poroperty is set to emFixedSize). What’s more you can even determine how each cell will be sized: will it have a fixed size, or a percentage of the grid size – so you can have controls nicely uniformly distributed in a grid.
That’s all great when you know the design at design-time – and you know what number of controls you want to be hosted by the grid panel.