|
In the following tutorial we introduce to the fundamental ideas of the JCardGame framework. The paradigm of "Learning by Examples" is applied where each little example is fully functional and has a special didactical intension. The examples are not yet real games to play with, but serves as demonstration of a specific feature of JCardGame. All sources and sprite images are included in the JCardGame distribution. |
Ex07: Tool Bars
In all card games you need a minimum of user interaction. Output information is passed to the user by the card movements and arrangements, additional actor images and text in the status bar. Input information is taken from mouse actions like card clicks or double-clicks. In many situations more input information is necessary (selecting a number, a suit, a rank, a single card, etc.) Instead of using a full-fledged GUI builder and embed the card game window as a Java Bean, a simpler design is possible by adding items in a tool bar as standard game grid actors in the card game window. A tool bar may contain many different items or only one item like a button. We show how to use tool bars in the next example where the user can select a specific card out of a standard 52 card deck.
In the upper part of the window a tool bar with a text item, four stack items (one for each suit) and a button item is shown. The user selects a card by clicking through the suit stack. A surrounding rectangle shows which card is selected. The user then clicks OK to process his/her choice. The card is inserted into a hand, visible in the center of the window. The card is appended to the right of the hand, but if the user wants to sort the hand (by rank priority), he/she may press the Sort button (shown as soon as two cards are in the hand).
Here some comments about the code:
- Tool bar items are instances of the class ToolBarItem (or one of its subclasses). They are added to the tool bar by the method addItem() that takes as many items as given (variable-length parameter list, ellipses)
- The items are automatically aligned from left to right. All items should have the same height, but the width may vary
- Instances of the class ToolBarText creates an item with text centered in a background rectangle. The text color, text font, background color are user selectable
- Instances of the class ToolBarSeparator creates a rectangle with given height, width and color. It is used to show a separating vertical line between succeeding items
- Instances of the class ToolBarStack creates one single actor with twice the given number of sprite images. They are loaded from the disk using the given filename. Like standard JGameGrid actors the filename is appended by a _n followed by the file extension. The first half of files corresponds to the items in the normal state, the second half to the items in selected state
- By registering a ToolBarListener you get notifications on every kind of mouse events (press, release, click, double-click, enter, exit)
- The static method ToolBarStack.getSelectedItemIds() returns an array containing the index of the selected item on each stack. It can be used to find out which item(s) are currently selected
import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;
import java.awt.Color;
public class Ex07 extends CardGame
{
public enum Suit
{
SPADES, HEARTS, DIAMONDS, CLUBS
}
public enum Rank
{
ACE, KING, QUEEN, JACK, TEN, NINE, EIGHT, SEVEN, SIX, FIVE, FOUR, THREE, TWO
}
//
private int nbRanks = Rank.values().length;
private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
private Hand hand = new Hand(deck);
private ToolBarText textItem =
new ToolBarText("Select Card:", 30);
private ToolBarSeparator separator0 =
new ToolBarSeparator(2, 30, Color.black);
private ToolBarStack spades =
new ToolBarStack("sprites/spades.gif", nbRanks);
private ToolBarStack hearts =
new ToolBarStack("sprites/hearts.gif", nbRanks);
private ToolBarStack diamonds =
new ToolBarStack("sprites/diamonds.gif", nbRanks);
private ToolBarStack clubs =
new ToolBarStack("sprites/clubs.gif", nbRanks);
private ToolBarSeparator separator1 =
new ToolBarSeparator(2, 30, Color.black);
private ToolBarItem okBtn =
new ToolBarItem("sprites/ok30.gif", 2);
public Ex07()
{
super(300, 250, 30);
setStatusText("Select a card by clicking on the card stacks and press OK.");
hand.setView(this, new RowLayout(new Location(150, 125), 290));
hand.draw();
initToolBar();
}
private void initToolBar()
{
ToolBar toolBar = new ToolBar(this);
toolBar.addItem(textItem, separator0, spades, hearts, diamonds,
clubs, separator1, okBtn);
toolBar.show(new Location(10, 10));
toolBar.addToolBarListener(new ToolBarAdapter()
{
public void leftPressed(ToolBarItem item)
{
if (item == okBtn)
{
okBtn.show(1);
Card card = getSelectedCard(deck);
if (card != null)
{
if (hand.insert(card, true))
{
setStatusText("Card " + card + " successfully inserted.");
if (hand.getNumberOfCards() == 2)
initSortBtn();
}
else
setStatusText("Failed to insert card " + card
+ " (no duplication allowed)");
}
}
else
{
ToolBarStack stackItem = (ToolBarStack)item;
if (stackItem.isSelected())
stackItem.showNext();
else
{
deselectAll();
stackItem.setSelected(true);
}
}
}
public void leftReleased(ToolBarItem item)
{
if (item == okBtn)
item.show(0);
}
});
}
private void initSortBtn()
{
ToolBar toolBar = new ToolBar(this);
final ToolBarItem sortBtn = new ToolBarItem("sprites/sortBtn.gif", 2);
toolBar.addItem(sortBtn);
toolBar.show(new Location(233, 212));
toolBar.addToolBarListener(new ToolBarAdapter()
{
public void leftPressed(ToolBarItem item)
{
sortBtn.show(1);
hand.sort(Hand.SortType.RANKPRIORITY, true);
}
public void leftReleased(ToolBarItem item)
{
sortBtn.show(0);
}
});
}
private void deselectAll()
{
spades.setSelected(false);
hearts.setSelected(false);
diamonds.setSelected(false);
clubs.setSelected(false);
}
private Card getSelectedCard(Deck deck)
// Assumes that only one card stack is selected
// Returns null, if no card is selected
{
Card card = null;
int[] ids = ToolBarStack.getSelectedItemIds();
for (int i = 0; i < ids.length; i++)
{
int id = ids[i];
if (id != -1) // Selected item found
{
deck.getSuit(i);
deck.getRank(id);
card = new Card(deck, deck.getSuit(i), deck.getRank(id));
break;
}
}
return card;
}
public static void main(String[] args)
{
new Ex07();
}
} |
Execute the program locally using WebStart.
|
Download Android app for installation on a smartphone or emulator.
Download sources (CardEx07.zip).
Create QR code to download Android app to your smartphone.
Install/Start app on a USB connected smartphone or a running emulator.
(This is a WebStart signed by the University of Berne, Switzerland. It installs some helper files in <userhome>.jdroidtools.If you did not install the Android SDK, you may install a slim version of the Android-Emulator in <userhome>.jdroidemul using this link, To start the emulator, execute ExecEmul.jar found in <userhome>.jdroidemul) |
|
Ex08: Cutting a Deck
After the dealer completes the shuffle the card deck it is set face-down on the table and a designated player cuts the deck, e.g. breaks it into two batches and reverse the batch order. Despite the algorithm is simple, the class Hand provides a method cut() with an integer parameter. The method divides the hand considered as a card pile into two batches, one with the given number of cards taken from the top of the pile, one with the remaining cards. Then the two batches are reassembled in reverse order. In the following example the user can select the number of cards to take from the top. A tool bar with a number item is used to select a number between zero and nine. It is evident that such types of items are frequently used to select one of several choices of any kind (colors, dates, etc.) without the need of a drop-down GUI selection dialog.
import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;
import java.awt.Color;
public class Ex08 extends CardGame
{
public enum Suit
{
SPADES, HEARTS, DIAMONDS, CLUBS
}
public enum Rank
{
ACE, KING, QUEEN, JACK, TEN, NINE, EIGHT, SEVEN, SIX
}
private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
private Hand hand = deck.dealingOut(1, 5, false)[0];
public Ex08()
{
super(300, 200);
hand.setView(this, new RowLayout(new Location(150, 80), 290));
hand.draw();
initToolBar();
}
private void initToolBar()
{
final ToolBarStack numbers =
new ToolBarStack("sprites/number30.gif", 10);
ToolBarSeparator separator =
new ToolBarSeparator(2, 30, Color.black);
final ToolBarItem cutBtn =
new ToolBarItem("sprites/cutBtn.gif", 3);
ToolBar toolBar = new ToolBar(this);
toolBar.addItem(numbers, separator, cutBtn);
toolBar.show(new Location(7, 160));
toolBar.addToolBarListener(new ToolBarAdapter()
{
public void leftPressed(ToolBarItem item)
{
if (item == cutBtn)
{
cutBtn.show(1);
hand.cut(numbers.getItemId(), true);
}
else
((ToolBarStack)item).showNext();
}
public void leftReleased(ToolBarItem item)
{
if (item == cutBtn)
item.show(0);
}
});
}
public static void main(String[] args)
{
new Ex08();
}
} |
Execute the program locally using WebStart.
|
Download Android app for installation on a smartphone or emulator.
Download sources (CardEx08.zip).
Create QR code to download Android app to your smartphone.
Install/Start app on a USB connected smartphone or a running emulator.
(This is a WebStart signed by the University of Berne, Switzerland. It installs some helper files in <userhome>.jdroidtools.If you did not install the Android SDK, you may install a slim version of the Android-Emulator in <userhome>.jdroidemul using this link, To start the emulator, execute ExecEmul.jar found in <userhome>.jdroidemul) |
|
Ex09: Selecting Cards Randomly
If you want to take out a number of cards randomly and inserting them into another hand, just call randomBatchTransfer() with the number of card you need. In the following example you select the number of cards by clicking the tool bar stack item. Then you choose if you want to transfer the cards from the upper to the lower hand or vice vesa. If you studied thoroughly the tutorial, the code is completely self-explaining, isn't it?
import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;
public class Ex09 extends CardGame
{
public enum Suit
{
SPADES, HEARTS, DIAMONDS, CLUBS
}
public enum Rank
{
ACE, KING, QUEEN, JACK, TEN, NINE, EIGHT, SEVEN, SIX
}
private Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
private Hand upperHand;
private Hand lowerHand;
public Ex09()
{
super(460, 400);
Hand[] hands = deck.dealingOut(2, 5, true);
upperHand = hands[0];
upperHand.setView(this, new RowLayout(new Location(230, 100), 400));
lowerHand = hands[1];
lowerHand.setView(this, new RowLayout(new Location(230, 300), 400));
sortAndDrawHands();
initToolBar();
}
private void sortAndDrawHands()
{
upperHand.sort(Hand.SortType.RANKPRIORITY, true);
lowerHand.sort(Hand.SortType.RANKPRIORITY, true);
}
private void initToolBar()
{
final ToolBarItem upBtn = new ToolBarItem("sprites/up30.gif", 2);
final ToolBarStack numbers = new ToolBarStack("sprites/number30.gif", 10);
final ToolBarItem downBtn = new ToolBarItem("sprites/down30.gif", 2);
ToolBar toolBar = new ToolBar(this);
toolBar.addItem(upBtn, numbers, downBtn);
toolBar.show(new Location(160, 185));
numbers.show(3); // Default start number
toolBar.addToolBarListener(new ToolBarAdapter()
{
public void leftPressed(ToolBarItem item)
{
if (item == upBtn)
{
upBtn.show(1);
Hand.randomBatchTransfer(numbers.getItemId(),
lowerHand, upperHand, false);
sortAndDrawHands();
}
if (item == downBtn)
{
downBtn.show(1);
Hand.randomBatchTransfer(numbers.getItemId(),
upperHand, lowerHand, false);
sortAndDrawHands();
}
if (item == numbers)
((ToolBarStack)item).showNext();
}
public void leftReleased(ToolBarItem item)
{
if (item == upBtn)
upBtn.show(0);
if (item == downBtn)
downBtn.show(0);
}
});
}
public static void main(String[] args)
{
new Ex09();
}
}
|
Execute the program locally using WebStart.
|
Download Android app for installation on a smartphone or emulator.
Download sources (CardEx09.zip).
Create QR code to download Android app to your smartphone.
Install/Start app on a USB connected smartphone or a running emulator.
(This is a WebStart signed by the University of Berne, Switzerland. It installs some helper files in <userhome>.jdroidtools.If you did not install the Android SDK, you may install a slim version of the Android-Emulator in <userhome>.jdroidemul using this link, To start the emulator, execute ExecEmul.jar found in <userhome>.jdroidemul) |
|
| |