• entries
2
5
• views
322

Deck Selection Dialog

In my last post, I gave an overview of the Solitaire project that I am working on, along with an explanation of the features that I have currently implemented, and the feature that I was to work on next. The next feature of Solitaire that I wanted to implement is the deck selection dialog, where you choose from a list of predefined deck images, the image you would like to use on your deck backside when playing the game.  Here is what my dialog looks like. The goal of this dialog is to try to mimic the original Solitaire deck selection dialog.     Here is a list of features that were required for me to implement for this task. 1. I had to implement the initial dialog window along with its dimensions and specifications, such as making it a modal window, not allowing the window to be resized, and other options like that. This was pretty straightforward as I have done this many times before, and was simply a matter of testing the old dialog to see what I could and could not do. 2. I had to create the skeleton of the dialog, so I used a BoxLayout with a Y-Axis alignment, this is where I added two panel types, one that holds the deck button images, and the other that holds the OK and Cancel button. The first panel within my BoxLayout was a JPanel that uses a GridBagLayout with two rows and six columns. The second JPanel uses a FlowLayout centered about the x-axis. Note: The 2 row 6 column deck images that you see are actually JButton components. Here is how the dimensions of a button looks like from up close.   The button size is 45px in width by 74px in height. The border is removed by default on all buttons except for the one that was last selected. Within the button is the icon image, this is 39px wide by 68 px in height. When the button is selected, a 2px blue border is rendered around the button, leaving a gap of a few pixels between the button image and the border itself, similar to what was done in the original Solitaire game, or at least what I thought was implemented based on my research. I also disabled some events such as hovering your mouse over a button to prevent the background image from changing color because the mouse hovered over the button. I also disabled that same effect when clicking on the button. 3. Clicking on a button should show a border, and deselect any other button that was previously selected. This was very straightforward to do. 4. Fetch the deck images and load them into the button. 5. Adding events to the button such as double-clicking on a button to choose a deck image, or pressing on the enter key in the dialog to simulate an OK button click. 6. Update the deck images of all the cards in the game, including the image of the Stock view (the card at the top-left of the game) when a selected took place and the OK button was selected. To get this done, I had all my CardModel objects register to an event that I created called EVENT_UPDATE_BACKSIDE public static final String EVENT_UPDATE_BACKSIDE = "EVENT_UPDATE_BACKSIDE"; Here is the code that the CardModel uses for registering this event addSignalListener(EVENT_UPDATE_BACKSIDE, new ISignalReceiver<EventArgs>() { @Override public void signalReceived(EventArgs event) { OptionsPreferences preferences = new OptionsPreferences(); preferences.load(); _cardEntity.setBackside(preferences.deck); refresh(); } }); So I look at the options preferences, and based on what was saved from the deck selection dialog, I go into my card entity (a reference that each CardModel owns) and I set the deck to be whatever was saved. I then issue a refresh on the model that causes all the views that are data-bound to my model to perform an update(), which will then render their backside which will show the updated deck image. Here is how I make the call so that the registered event above gets fired // Update all the backsides of all the cards in the game EventArgs args = new EventArgs(this, CardModel.EVENT_UPDATE_BACKSIDE); AbstractFactory.getFactory(ModelFactory.class).multicastSignalListeners(CardModel.class, args); So what I do here is I create an EventArgs which is a base class for passing arguments around in my game. I indicate the sender and the signal name which is the same signal name that was used to register the event listener in the CardModel from above. I then perform a call onto all CardModel type objects that have been registered by my ModelFactory. This will dispatch my EventArgs to all the CardModel types that were created with my factory, that are listening in to the specified message. From there, the information is updated within each CardModel, and the view(s) that are bound to those models are updated accordingly, very straightforward stuff. The code that I wrote above comes from my own take on a much friendlier version of the Observer design pattern. I first started using the Observer provided to me by the Java SDK about two years ago, however over time I found it to be very limiting, so I eventually wrote my own version of it, and one day I will write an article outlining what I did and why I like it a lot more, but for now this is what I have been using in it's place for two years and it has worked out great for me. 7. Persist the selected deck image for future games played.  So that's all that there is. My next task is to implement the Draw Three feature, where every time you click on the Stock view (top-left card), three cards come into play instead of one. You can always follow my progress by following the game located at https://github.com/danielricci/solitaire, and if you have any questions I will do my best to answer them. Take care, until my next blog post.

Status Update

For the past year during my spare time, I have been working on re-creating the Windows 98 version of Solitaire using Java. Prior to working on Solitaire, I made a few others board games while re-using a code base that I have built up over time that makes Swing a bit more bearable and re-usable. I recently remade a Windows 98 version of Minesweeper, available on my GitHub as well. I have decided to try and keep an updated blog on this website, posting updates about my progress as a Computer Scientist. Hopefully, the work that I am doing is able to help motivate others in completing their own personal projects, and I hope everyone is able to make use of some of the work that I am doing. Before I go into where I am at right now for the Solitaire remake, I want to share with everyone a bit of background history.  For the past two years since I left my full-time job working at a gaming company in Montreal, I decided to go back to my roots and work on some games that would teach me the fundamental concepts of completing a project, among other core experiences such as not losing focus on a task, and always moving forward even when there are roadblocks. Fast-forward to today, and I have completed a few games such as Tic-Tac-Toe, Checkers, Chess, Minesweeper, and am currently working on a Solitaire game. I have been learning a lot about myself during my experiences making these games, and I am using that knowledge to make bigger and better things, and posting it all on GitHub for everyone to use, hopefully to one day make an impact in other peoples lives. I could spend a lot more time talking about myself and my journey, however right now at this time I want to show off a bit of the Solitaire game that I am working on and where I am at right now. Maybe in other blog posts, I will go a bit more into my own details as a Computer Scientist. This is what the game looks like right now in its current state. I will go through the features that I have implemented so far, and will then go through what I am working on right now.   So far I have implemented the following.   1. The options menu. I have implemented everything in the options menu except for the Draw Three feature, and the sub-features associated to Draw Three such as the number of times you can go through the deck, scoring with respect to Draw Three, etc. You can play a timed game, change the visibility of the status bar at the bottom of the game, you can go from an outline view to a non-outline view when dragging the cards, and you can choose between three scoring modes along with a cumulative scoring option when playing in Vegas 2. Outline vs non-outline dragging Here is outline dragging and non-outline dragging when playing the game. I tried to make the outline highlight work the same as the original game, which was simply by using an XOR bit-mask whenever a collision between the border of the proxy card was dragged over a particular card, as you can see with the Queen of Diamonds and the Jack of Spades.    Here is a non-outline drag. Notice that the card is moved and you can see the backside of the card that it was originally hiding.   Here is a list of other features that I worked on so far. Setting up the board and where the cards will be positioned Being able to cycle through the cards at the top-left Being able to drag a card from one location to another Being able to place a card somewhere, the logic and architecture used to detect when this is possible
and to place the card or put it back where it started from Placing a card on the foundation stacks (the four placeholder squares that you see right now), and determining if the game has been won The options menu shown above Timed game, which will show at the bottom right of your screen when you have a status bar that is visible Scoring Standard which uses some basic rules, I just had to research them and implement it Vegas scoring. I also looked this up and implemented it, also some slight formatting changes Cumulative scoring, this wasn't too difficult to implemented, it was just a matter of persisting your score when playing a new game Saving the options chosen within the options menu, and when certain options would change such as how many cards were drawn, a game reset would occur Outline dragging. This was by far one of the most interesting things that I implemented throughout this game. Normal dragging. I implemented this first before going into the outline dragging mode Double-clicking on a card to auto move it to the foundation pile (if applicable) Lots of bug fixes along the way   Right now I am working on being able to choose which deck image you want to play the game with. I have the images on hand and I have imported them into my game, all that is left is to mock up the dialog window and position the images similar to the original game. So far this is where I am at with my game. You can always follow my progress by following the game located at https://github.com/danielricci/solitaire Sorry that I did not go into any technical details, this is my first blog post and I am nervous enough as it is. I hope you all enjoy reading this, and I will try to answer any questions in the comments. Take care, until my next blog post.