Here's a sample code to create a Blackjack game in Java.
Blackjack's rule is pretty simple so I think it's a good start for developing card games :)
Screenshots from the game:
I used some free images for the title screen and the playing cards. You don't really need the image for the title screen but please prepare playing card images and put them in the res folder.
I got the playing card image from here:
https://chicodeza.com/freeitems/torannpu-illust.html
You can also get images from websites such as pixabay:
https://pixabay.com/ja/illustrations/search/playing%20cards/
Here's the video preview:
Here's the code:
import java.awt.Color;
import java.net.URL;
import java.util.Random;
import javax.swing.ImageIcon;
public class Game{
// CLASS
ActionHandler aHandler = new ActionHandler(this);
UI ui = new UI(this);
Cards cards = new Cards();
Random random = new Random();
AudioAsset aa = new AudioAsset();
SE se = new SE();
Music music = new Music();
// CARD STUFF
int pickedCardNum;
int playerHas = 0;
int dealerHas = 0;
int playerCardNum[] = new int[6];
int dealerCardNum[] = new int[6];
int playerCardValue[] = new int[6];
int dealerCardValue[] = new int[6];
int playerTotalValue;
int dealerTotalValue;
// OTHERS
String situation = "";
ImageIcon dealerSecondCard;
public static void main(String[] args) {
new Game();
}
public void titleToGame() {
ui.titlePanel.setVisible(false);
ui.startB.setVisible(false);
ui.exitB.setVisible(false);
ui.table.setVisible(true);
ui.dealerPanel.setVisible(true);
ui.playerPanel.setVisible(true);
ui.messageText.setVisible(true);
ui.buttonPanel.setVisible(true);
ui.getContentPane().setBackground(Color.black);
playMusic(aa.bgm);
startGame();
}
public void gameToTitle() {
ui.titlePanel.setVisible(true);
ui.table.setVisible(false);
ui.dealerPanel.setVisible(false);
ui.playerPanel.setVisible(false);
ui.messageText.setVisible(false);
ui.buttonPanel.setVisible(false);
ui.getContentPane().setBackground(new Color(0,81,0));
ui.titlePanel.alphaValue = 0f;
ui.titlePanel.timer.start();
stopMusic(aa.bgm);
}
public void startGame() {
dealerDraw();
playerDraw();
dealerDraw();
ui.dealerCardLabel[2].setIcon(cards.front);
ui.dealerScore.setText("Dealer: ?");
playerTurn();
}
public void dealerDraw() {
playSE(aa.cardSound01);
dealerHas++;
ImageIcon pickedCard = pickRandomCard(); // pickRandomCard: return an ImageIcon
if(dealerHas==2) {
dealerSecondCard = pickedCard; // Save the second card for revealing it later
}
dealerCardNum[dealerHas] = pickedCardNum; // Register what card the dealer got
dealerCardValue[dealerHas] = checkCardValue(); // Register the card value. If it's from Jack to King, it returns 10
ui.dealerCardLabel[dealerHas].setVisible(true);
ui.dealerCardLabel[dealerHas].setIcon(pickedCard); // Display the card
dealerTotalValue = dealerTotalValue();
ui.dealerScore.setText("Dealer: " + dealerTotalValue);
}
public void playerDraw() {
playSE(aa.cardSound01);
playerHas++;
ImageIcon pickedCard = pickRandomCard();
playerCardNum[playerHas] = pickedCardNum;
playerCardValue[playerHas] = checkCardValue();
ui.playerCardLabel[playerHas].setVisible(true);
ui.playerCardLabel[playerHas].setIcon(pickedCard);
playerTotalValue = playerTotalValue(); // Count total player card value
ui.playerScore.setText("You: " + playerTotalValue);
}
public void playerTurn() {
situation = "playerTurn";
playerDraw(); // Hit a card
if(playerTotalValue > 21) { // If the total value surpassed 21, the game is over
dealerOpen();
}
else if(playerTotalValue == 21 && playerHas == 2) {
playerNatural();
}
else {
if(playerHas > 1 && playerHas < 5) { // If the total value is less than 22 and has 4 or less cards, you can still hit
ui.messageText.setTextPlus("Do you want to hit one more card?");
ui.button[1].setVisible(true);
ui.button[1].setText("Hit");
ui.button[2].setVisible(true);
ui.button[2].setText("Stand");
}
if(playerHas == 5) { // If the player has 5 cards, the player's turn is over
dealerOpen();
}
}
}
public void playerNatural() {
situation = "playerNatural";
ui.messageText.setTextPlus("You got natural. Let's open the dealer's card.");
ui.button[1].setVisible(true);
ui.button[1].setText("Continue");
}
public void dealerOpen() {
playSE(aa.cardSound01);
ui.dealerCardLabel[2].setIcon(dealerSecondCard); // Reveal the second card
ui.dealerScore.setText("Dealer: " + dealerTotalValue);
if(playerHas == 2 && playerTotalValue == 21) { // If player got natural
checkResult();
}
else if(dealerTotalValue < 17 && playerTotalValue <= 21) {
dealerTurnContinue();
}
else {
checkResult();
}
}
public void dealerTurn() {
if(dealerTotalValue < 17) { // If it's less than 17, the dealer must hit one more card
dealerDraw();
if(dealerHas == 5 || dealerTotalValue >= 17) { // If the player has 5 cards, the player's turn is over
checkResult();
}
else {
dealerTurnContinue();
}
}
else {
checkResult();
}
}
public void dealerTurnContinue() {
situation = "dealerTurnContinue";
ui.messageText.setTextPlus("The dealer is going to hit another card.");
ui.button[1].setVisible(true);
ui.button[1].setText("Continue");
}
public void checkResult() {
situation = "checkResult";
if(playerTotalValue > 21) {
playSE(aa.youlost);
ui.messageText.setTextPlus("You lost!");
gameFinished();
}
else {
if(playerTotalValue == 21 && dealerHas == 2) { // If player is natural
if(dealerTotalValue == 21) {
playSE(aa.draw);
ui.messageText.setTextPlus("Draw!");
gameFinished();
}
else {
playSE(aa.youwon);
ui.messageText.setTextPlus("You won!");
gameFinished();
}
}
else {
if(dealerTotalValue < 22 && dealerTotalValue > playerTotalValue) {
playSE(aa.youlost);
ui.messageText.setTextPlus("You lost!");
gameFinished();
}
else if(dealerTotalValue == playerTotalValue) {
playSE(aa.draw);
ui.messageText.setTextPlus("Draw!");
gameFinished();
}
else {
playSE(aa.youwon);
ui.messageText.setTextPlus("You won!");
gameFinished();
}
}
}
}
public void gameFinished() {
situation = "gameFinished";
ui.button[1].setVisible(true);
ui.button[1].setText("Play Again");
ui.button[2].setVisible(true);
ui.button[2].setText("Quit");
}
public void resetEverything() {
for(int i=1; i < 6; i++ ){
ui.playerCardLabel[i].setVisible(false);
ui.dealerCardLabel[i].setVisible(false);
}
for(int i=1; i < 6; i++) {
playerCardNum[i]=0;
playerCardValue[i]=0;
dealerCardNum[i]=0;
dealerCardValue[i]=0;
}
playerHas=0;
dealerHas=0;
removeButtons();
startGame();
}
public int playerTotalValue() {
playerTotalValue = playerCardValue[1] + playerCardValue[2] + playerCardValue[3] + playerCardValue[4] + playerCardValue[5];
if(playerTotalValue > 21) {
adjustPlayerAceValue();
}
playerTotalValue = playerCardValue[1] + playerCardValue[2] + playerCardValue[3] + playerCardValue[4] + playerCardValue[5];
return playerTotalValue;
}
public int dealerTotalValue() {
dealerTotalValue = dealerCardValue[1] + dealerCardValue[2] + dealerCardValue[3] + dealerCardValue[4] + dealerCardValue[5];
if(dealerTotalValue > 21) {
adjustDealerAceValue();
}
dealerTotalValue = dealerCardValue[1] + dealerCardValue[2] + dealerCardValue[3] + dealerCardValue[4] + dealerCardValue[5];
return dealerTotalValue;
}
public void adjustPlayerAceValue() {
for(int i=1; i<6; i++) {
if(playerCardNum[i]==1) {
playerCardValue[i]=1;
playerTotalValue = playerCardValue[1] + playerCardValue[2] + playerCardValue[3] + playerCardValue[4] + playerCardValue[5];
if(playerTotalValue < 21) {
break;
}
}
}
}
public void adjustDealerAceValue() {
for(int i=1; i<6; i++) {
if(dealerCardNum[i]==1) {
dealerCardValue[i]=1;
dealerTotalValue = dealerCardValue[1] + dealerCardValue[2] + dealerCardValue[3] + dealerCardValue[4] + dealerCardValue[5];
if(dealerTotalValue < 21) {
break;
}
}
}
}
public ImageIcon pickRandomCard() {
ImageIcon pickedCard = null;
pickedCardNum = random.nextInt(13)+1;
int pickedMark = random.nextInt(4)+1;
switch(pickedMark) {
case 1: pickedCard = cards.spade[pickedCardNum]; break;
case 2: pickedCard = cards.heart[pickedCardNum]; break;
case 3: pickedCard = cards.club[pickedCardNum]; break;
case 4: pickedCard = cards.diamond[pickedCardNum]; break;
}
return pickedCard;
}
public int checkCardValue() {
int cardValue = pickedCardNum;
if(pickedCardNum==1) {
cardValue=11;
}
if(pickedCardNum>10) {
cardValue=10;
}
return cardValue;
}
public void removeButtons() {
ui.button[1].setVisible(false);
ui.button[2].setVisible(false);
ui.button[3].setVisible(false);
ui.button[4].setVisible(false);
ui.button[5].setVisible(false);
}
public void playSE(URL url) {
se.setFile(url);
se.play(url);
}
public void playMusic(URL url) {
music.setFile(url);
music.play(url);
music.loop(url);
}
public void stopMusic(URL url) {
music.stop(url);
}
}
import javax.swing.ImageIcon;
public class Cards {
ImageIcon front = new ImageIcon();
ImageIcon spade[] = new ImageIcon[14];
ImageIcon heart[] = new ImageIcon[14];
ImageIcon club[] = new ImageIcon[14];
ImageIcon diamond[] = new ImageIcon[14];
public Cards() {
front = new ImageIcon(getClass().getClassLoader().getResource("front.png"));
// SPADE
for(int num=1; num<14; num++) {
spade[num] = new ImageIcon(getClass().getClassLoader().getResource(num + "S.png"));
}
// HEART
for(int num=1; num<14; num++) {
heart[num] = new ImageIcon(getClass().getClassLoader().getResource(num + "H.png"));
}
// CLUB
for(int num=1; num<14; num++) {
club[num] = new ImageIcon(getClass().getClassLoader().getResource(num + "C.png"));
}
// DIAMOND
for(int num=1; num<14; num++) {
diamond[num] = new ImageIcon(getClass().getClassLoader().getResource(num + "D.png"));
}
}
}
UI.java
This class handles all the UI elements.
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class UI extends JFrame{
// Title Screen UI
PaintPanel titlePanel;
JButton startB,exitB;
// Table UI
JPanel table;
JPanel dealerPanel;
JPanel playerPanel;
JLabel playerCardLabel[] = new JLabel[6];
JLabel dealerCardLabel[] = new JLabel[6];
// Message UI
JTextAreaPlus messageText;
JPanel scorePanel;
JLabel playerScore, dealerScore;
JPanel buttonPanel = new JPanel();
JButton button[] = new JButton[6];
Game game;
int cardWidth = 150;
int cardHeight = 213;
public UI(Game game) {
this.game = game;
this.setTitle("SUPER BlACKJACK");
this.setIconImage(new ImageIcon(getClass().getClassLoader().getResource("ui_glass.png")).getImage());
this.setSize(1200,900);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.getContentPane().setBackground(new Color(0,81,0));
createTitleScreen();
createTableUI();
createOtherUI();
this.setVisible(true);
}
public void createTitleScreen() {
titlePanel = new PaintPanel(this);
titlePanel.setBounds(0,0,1200,600);
titlePanel.setOpaque(false);
this.add(titlePanel);
startB = new JButton("START");
startB.setBounds(500,700,200,50);
startB.setBorder(null);
startB.setBackground(null);
startB.setFocusPainted(false);
startB.setForeground(Color.white);
startB.setFont(new Font("Book Antiqua", Font.PLAIN,36));
startB.setVisible(false);
startB.addActionListener(game.aHandler);
startB.setActionCommand("start");
startB.setContentAreaFilled(false);
this.add(startB);
exitB = new JButton("EXIT");
exitB.setBounds(500,750,200,50);
exitB.setBorder(null);
exitB.setBackground(null);
exitB.setFocusPainted(false);
exitB.setForeground(Color.white);
exitB.setFont(new Font("Book Antiqua", Font.PLAIN,36));
exitB.setVisible(false);
exitB.addActionListener(game.aHandler);
exitB.setActionCommand("exit");
exitB.setContentAreaFilled(false);
this.add(exitB);
titlePanel.timer.start();
}
public void createTableUI() {
table = new JPanel();
table.setBackground(new Color(0,81,0));
table.setBounds(50,50,850,600);
table.setLayout(null);
table.setVisible(false);
dealerPanel = new JPanel();
dealerPanel.setBounds(100,120,cardWidth*5,cardHeight);
dealerPanel.setBackground(null);
dealerPanel.setOpaque(false);
dealerPanel.setLayout(new GridLayout(1,5));
dealerPanel.setVisible(false);
this.add(dealerPanel);
playerPanel = new JPanel();
playerPanel.setBounds(100,370,cardWidth*5,cardHeight);
playerPanel.setOpaque(false);
playerPanel.setLayout(new GridLayout(1,5));
playerPanel.setVisible(false);
this.add(playerPanel);
for(int i = 1; i < 6; i++) {
playerCardLabel[i] = new JLabel();
playerCardLabel[i].setVisible(false);
playerPanel.add(playerCardLabel[i]);
}
for(int i = 1; i < 6; i++) {
dealerCardLabel[i] = new JLabel();
dealerCardLabel[i].setVisible(false);
dealerPanel.add(dealerCardLabel[i]);
}
dealerScore = new JLabel();
dealerScore.setBounds(50,10,200,50);
dealerScore.setForeground(Color.white);
dealerScore.setFont(new Font("Times New Roman", Font.PLAIN, 42));
table.add(dealerScore);
playerScore = new JLabel();
playerScore.setBounds(50,540,200,50);
playerScore.setForeground(Color.white);
playerScore.setFont(new Font("Times New Roman", Font.PLAIN, 42));
table.add(playerScore);
this.add(table);
}
public void createOtherUI() {
messageText = new JTextAreaPlus();
messageText.setBounds(230,680,720,100);
messageText.setBackground(null);
messageText.setForeground(Color.white);
messageText.setFont(new Font("Times New Roman", Font.PLAIN, 40));
messageText.setEditable(false);
this.add(messageText);
buttonPanel = new JPanel();
buttonPanel.setBounds(920,340,200,300);
buttonPanel.setBackground(null);
buttonPanel.setLayout(new GridLayout(6,1));
this.add(buttonPanel);
for(int i = 1; i < 6; i++) {
button[i] = new JButton();
button[i].setBackground(null);
button[i].setForeground(Color.white);
button[i].setFocusPainted(false);
button[i].setBorder(null);
button[i].setFont(new Font("Times New Roman", Font.PLAIN, 42));
button[i].addActionListener(game.aHandler);
button[i].setActionCommand(""+i);
button[i].setVisible(false);
buttonPanel.add(button[i]);
}
}
}
PaintPanel.java
This class handles the title screen animation
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;
public class PaintPanel extends JPanel implements ActionListener{
public Timer timer = new Timer(30,this);
float alphaValue = 0f;
BufferedImage titleImage;
UI ui;
public PaintPanel(UI ui) {
this.ui = ui;
try {
titleImage = ImageIO.read(getClass().getClassLoader().getResource("titleimage.png"));
}catch(IOException e) {
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaValue));
if(alphaValue < 0.99) {
g2d.setColor(Color.white);
}
else {
g2d.setColor(Color.yellow);
}
g2d.setFont(new Font("Book Antiqua", Font.PLAIN, 110));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
String text = "SUPER BLACKJACK";
int stringLength = (int)g.getFontMetrics().getStringBounds(text, g).getWidth();
int start = this.getWidth()/2 - stringLength/2;
g.drawString(text, start, 200);
g.drawImage(titleImage, 280,320,640,280,null);
}
@Override
public void actionPerformed(ActionEvent e) {
alphaValue = alphaValue +0.01f;
if(alphaValue > 1) {
alphaValue = 1;
timer.stop();
ui.startB.setVisible(true);
ui.exitB.setVisible(true);
}
repaint();
}
}
ActionHandler.java
This class handles the button actions
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ActionHandler implements ActionListener{
Game game;
public ActionHandler(Game game) {
this.game = game;
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
game.removeButtons();
switch(command) {
case "start":
game.titleToGame();
break;
case "exit":
System.exit(0);
break;
case "1":
if(game.situation.equals("playerTurn")) {
game.playerTurn();
}
else if(game.situation.equals("playerNatural")) {
game.dealerOpen();
}
else if(game.situation.equals("dealerTurnContinue")) {
game.dealerTurn();
}
else if(game.situation.equals("gameFinished")) {
game.resetEverything();
}
break;
case "2":
if(game.situation.equals("playerTurn")) {
game.dealerOpen();
}
else if(game.situation.contentEquals("gameFinished")) {
game.gameToTitle();
}
break;
}
}
}
JTextAreaPlus.java
This is a modified version of JTextArea which can display texts letter by letter.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class JTextAreaPlus extends JTextArea implements ActionListener{
int i=0;
String text;
Timer timer = new Timer(10, this);
public JTextAreaPlus() {
}
public JTextAreaPlus(String text) {
super(text);
}
public void setTextPlus(String text) {
this.text = text;
setText("");
timer.start();
}
@Override
public void actionPerformed(ActionEvent e) {
char character[] = text.toCharArray();
int arrayNum = character.length;
String s = String.valueOf(character[i]);
append(s);
i++;
if(i == arrayNum){
i = 0;
timer.stop();
}
}
}
(Optional) If you want to play SE and Music
AudioAsset.java
This class imports all the sound data
import java.net.URL;
public class AudioAsset {
URL cardSound01 = getClass().getClassLoader().getResource("cardSound01.wav");
URL youwon = getClass().getClassLoader().getResource("Ryan_youwon.wav");
URL youlost = getClass().getClassLoader().getResource("Ryan_youlost.wav");
URL draw = getClass().getClassLoader().getResource("Ryan_draw.wav");
URL isee = getClass().getClassLoader().getResource("Ryan_isee.wav");
URL ok = getClass().getClassLoader().getResource("Ryan_ok.wav");
URL hitanother = getClass().getClassLoader().getResource("Ryan_hitanother.wav");
URL bgm = getClass().getClassLoader().getResource("bensound-theelevatorbossanova.wav");
}
SE.java
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class SE {
Clip clip;
public void setFile(URL name) {
try {
AudioInputStream sound = AudioSystem.getAudioInputStream(name);
clip = AudioSystem.getClip();
clip.open(sound);
}
catch(Exception e) {
}
}
public void play(URL name) {
clip.setFramePosition(0);
clip.start();
}
public void loop(URL name) {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
public void stop(URL name) {
clip.stop();
}
}
Music.java
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class Music {
Clip clip;
public void setFile(URL name) {
try {
AudioInputStream sound = AudioSystem.getAudioInputStream(name);
clip = AudioSystem.getClip();
clip.open(sound);
}
catch(Exception e) {
}
}
public void play(URL name) {
clip.setFramePosition(0);
clip.start();
}
public void loop(URL name) {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
public void stop(URL name) {
clip.stop();
}
}
end
aa
ReplyDeletequestion do i need to pick one card picture and rename it to "front" because i'm getting an error when running the program
ReplyDelete