13 Replies - 5502 Views - Last Post: 01 June 2010 - 01:52 AM Rate Topic: -----

#1 Guest_Tronsho*


Reputation:

BlackJack game

Posted 30 May 2010 - 08:38 PM

Hi All

I work on a GUI Blackjack game in java.
I took some ideas from this site, from Dogstopper blog about game state machines.
this is how I implement my abstaract class for the game state:
package blackjack;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import java.awt.event.ActionListener;

public abstract class BlackJackState implements ActionListener{

	protected BlackJackPanel root;
	protected JPanel controlPanel;
	
	protected BlackJackState(BlackJackPanel root){
		this.root = root;
		this.controlPanel = new JPanel();
		this.root.add(controlPanel, BorderLayout.SOUTH);
		this.root.setBackground(new Color(100, 150, 60));
		this.controlPanel.setBackground(this.root.getBackground());
	}
	
	public abstract void draw(Graphics g);
	
	public void clearCurrentControlPanel(){
		this.controlPanel.setVisible(false);
	}
}


now, my question considers the controlPanel Object I create.
you see, for every state in the game I'll have different JComponents to add (different buttons, different sliders etc.)
now, I create the controlPanel inside each of the state classes, and add it to the "root" Object I get as parameter.
then, I add the components in the state classes.

when I switch between the states i use the setVisible(false) on the current controlPanel and add the new one.

Now this approach works fine. My question However is: what do you think on such design? is it safe? is it a good design?
Or should I somehow create the controlPanel only inside the BlackJackPanel class?

I'll be happy to hear any ideas! Thanks!

Is This A Good Question/Topic? 0

Replies To: BlackJack game

#2 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 31 May 2010 - 03:24 AM

Normally, unless there's a very good reason otherwise, you should keep state objects uncoupled from gui classes
Was This Post Helpful? 0
  • +
  • -

#3 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 06:54 AM

Thanks!
But any ideas how I can do it?
I chose to do so because I thoght there is no other way...
Was This Post Helpful? 0

#4 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 31 May 2010 - 06:58 AM

Well i'm not sure what your state object does, but you could make a linkage between it and your gui classes via another class
Was This Post Helpful? 0
  • +
  • -

#5 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 08:17 AM

Thanks for all the time and help g00se!
I'll post my BlackJackPanel and my BlackJacTitle class:
BlackJackTitle.java
package blackjack;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JOptionPane;

public class BlackJackTitle extends BlackJackState{

	private JButton newGameButton;
	private JButton quitButton;
	
	public BlackJackTitle(BlackJackPanel root){
		super(root);
		//set buttons
		this.initButtons();
		//add buttons
		this.controlPanel.add(newGameButton);
		this.controlPanel.add(quitButton);
	}
	
	private void initButtons(){
		this.newGameButton = new JButton("New Game");
		this.newGameButton.addActionListener(this);
		this.quitButton = new JButton("Quit");
		this.quitButton.addActionListener(this);
	}
	
	
	public void draw(Graphics g){
		g.setColor(Color.black);
		Font font = new Font(Font.SERIF, Font.ITALIC, 48);
		g.setFont(font);
		g.drawString("Nir's BlackJack", this.root.getX() + this.root.getWidth() / 4, this.root.getY() + this.root.getHeight() / 2);
	}
	
	public void actionPerformed(ActionEvent e){
		if(e.getActionCommand() == "New Game"){
			this.clearCurrentControlPanel();
			this.root.setState(BlackJackPanel.PLAY_STATE);
		}
		else if(e.getActionCommand() == "Quit"){
			int ans = JOptionPane.showConfirmDialog(this.root, "Are you sure you want to quit?", "Quit Game", JOptionPane.YES_NO_OPTION);
			if(ans == JOptionPane.YES_OPTION){
				System.exit(0);
			}
		}
	}
	
}


BlackJackPanel.java
package blackjack;

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class BlackJackPanel extends JPanel implements ActionListener{
	
	public final static int TITLE_STATE = 0;
	public final static int PLAY_STATE = 1;
	
	private BlackJackState currState;
	private Timer timer;
	
	public BlackJackPanel(){
		this.setPreferredSize(new Dimension(600, 400));
		this.setLayout(new BorderLayout());
		timer = new Timer(15, this);
		this.setState(TITLE_STATE);
		timer.start();
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		this.currState.draw(g);
	}
	
	public void setState(int state){
		switch(state){
		case TITLE_STATE:
			this.currState = new BlackJackTitle(this);
			break;
		case PLAY_STATE:
			this.currState = new BlackJackGame(this);
			break;
		}
	}
	
	public void actionPerformed(ActionEvent e){
		repaint();
	}
}


as you can see, different GUI components are needed for each state.
for the title state i need a quit and new game buttons.
then for the game state i need a bet button, deal button, a JSlider to decide amount of money to bet and so on.
I don't know how to link the classes in other way than i did in that code...
Was This Post Helpful? 0

#6 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 31 May 2010 - 08:20 AM

I need to understand what states you're modelling
Was This Post Helpful? 0
  • +
  • -

#7 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 09:39 AM

One example for a state is the BlackJackTitle class I posted.
another state is my BlacKJackGame state, it is not yet finished completely so I havn't posted it.
when the game starts, it goes to the BlackJackTitle state. when i press the newGame button in the BlackJackTitle state, it goes to the Game state (setting the visibility of the controlPanel of BlackJackTitle state to false).
Was This Post Helpful? 0

#8 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 31 May 2010 - 11:16 AM

To enable the gui to interact with the state machine, you could make the latter Observable (see the 'Observer' design pattern). Making a class Observable in Java is probably best done through custom events. You would then make the gui or a class of your gui a 'state listener' and add that listener to a list of listeners kept by the state machine

http://www.examplede.../CustEvent.html

This post has been edited by g00se: 31 May 2010 - 11:17 AM

Was This Post Helpful? 0
  • +
  • -

#9 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 12:01 PM

Thanks a lot g00se for the help!
Then just to see if I understand, I should create the controlPanel Object inside the BlackJackPanel class.
then, add the controlPanel a statelistener.
my abstract BlackJackState class should have a listener list.
then, I should add the controlPanel to the listener list of the BlackJackState?

but then, where should go the code for adding components to that controlPanel? and add actionListeners to those JComponents?
Was This Post Helpful? 0

#10 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 31 May 2010 - 12:23 PM

Well that sounds broadly right - although you must appreciate i don't know the full design. There should probably be one chief listener class, which is the main one in charge of managing the gui. I assume this is the one that you're calling your 'control panel'. Its own components can be added in the normal way. Your state class would have no gui components
Was This Post Helpful? 0
  • +
  • -

#11 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 12:37 PM

Thanks g00se, again I really appreciate all that help! :)
However, Now we are back to my first problem... each state uses different JButtons. in each state different buttons should be available to the player to interact with.
As I said, In the title satate (the BlackJackTitle) I have newGame button and quitButton.
when the newGame button is pressed, the state switches to the BlackJackGame state. there i have different JButtons (Bet, Deal, etc).
The Jbuttons I used in the title state should be replaced by those new Buttons of the game state.
How do I code the button's listeners and logic if I don't do it inside the state classes?

As I understand what you say, It seems that I should add all buttons to the controlPanel at the begining, and code all their logic and game flow in one class, seperate from the states.. It makes it much harder to control...
Again, I really thankful to you!
Was This Post Helpful? 0

#12 Guest_Tronsho*


Reputation:

Re: BlackJack game

Posted 31 May 2010 - 04:01 PM

After thinking again on my problem, perhaps I should use a cardlayout and design my state classes to extend JPanels. then, I can add my JComponents there, and switch those state - panels when necessary.
What do you think?

However, I liked better my previous design. It worked perfectly. So I would be happy to hear any more suggestions how to make it better designed.
(g00se, if you can provide some more details on how to make it better, I'll appreciate it)

Thanks!
Was This Post Helpful? 0

#13 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8347
  • View blog
  • Posts: 31,912
  • Joined: 06-March 08

Re: BlackJack game

Posted 31 May 2010 - 04:30 PM

Or make a GridLayout(1, nbState);
fill hit of Jpanel (one for every state)
make all of them setVisible(false) but the one of your current state
when the state changes, make the previous one setVisible(false) and the new state one setVisible(true)
Was This Post Helpful? 0
  • +
  • -

#14 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2832
  • View blog
  • Posts: 12,000
  • Joined: 20-September 08

Re: BlackJack game

Posted 01 June 2010 - 01:52 AM

Quote

After thinking again on my problem, perhaps I should use a cardlayout and design my state classes to extend JPanels. then, I can add my JComponents there, and switch those state - panels when necessary.
What do you think?


I think it's a good idea - and as matter of fact, the first thing that came into my head when writing my last comments ;)

The 'controller' class, which is the principal (or even sole) state listener, can handle the program flow by showing the appropriate card for each state change

This post has been edited by g00se: 01 June 2010 - 01:58 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1