6
\$\begingroup\$

A while ago I got bored and being the beginner programmer I am I made a Russian Roulette game in Java using JFrame. The first few windows are JOptionPanes that are a welcoming screen, an update log and a how to play. The object of the game is you get 5 lives and when you lose all of your lives, you die. At the very end there is a JOptionPane that says the amount of trigger clicks you survived. If you have any suggestions please feel free to reply! Here is the source code:

Main Class

@SuppressWarnings("static-access")
    public static void main(String[] args) throws IOException, FontFormatException {

    RussianRouletteGame newGame = new RussianRouletteGame();
    newGame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    newGame.setSize(220, 200);
    newGame.setResizable(false);

    JFrame messageFrame = new JFrame();
    JOptionPane openingPane = new JOptionPane();

    @SuppressWarnings("unused")
    int openingMessage = openingPane.showOptionDialog(null,
            "Welcome To Russian Roulette Alpha 1.1!\nFor this one and all upcoming windows (besides the game) click the \"OK\", \"Cancel\", or \"X\" button to continue.",
            "Welcome!", openingPane.OK_CANCEL_OPTION, openingPane.INFORMATION_MESSAGE, null, null, null);
    messageFrame.add(openingPane);

    JFrame uLogFrame = new JFrame();
    JOptionPane uLogPane = new JOptionPane();
    @SuppressWarnings("unused")
    int uLogMessage = uLogPane.showOptionDialog(null,
            "Alpha 1.1 (July 12, 2015) \n-Added welcome window \n-Added update log (duh)\n-Added how to play window \n-Removed \"Thanks for playing\" at end of game \n\nAlpha 1.0 (July 5, 2015)\n-Released",
            "Update Log", uLogPane.OK_CANCEL_OPTION, uLogPane.INFORMATION_MESSAGE, null, null, null);
    uLogFrame.add(uLogPane);


    JFrame howToFrame = new JFrame();
    JOptionPane howToPane = new JOptionPane();
    int howToMessage = howToPane.showOptionDialog(null,
            "1. Click the button with the gun on it to start \n2. You can continue to click or use the spacebar to shoot after the first click \n3. Once you lose all 5 of your lives the game is over \n4. At the end it gives you your total amount of trigger clicks until death \n5. Compete with your friends to see who can get the most trigger clicks before death \n6. And last but not least... HAVE FUN!",
            "How To Play", howToPane.OK_CANCEL_OPTION, howToPane.INFORMATION_MESSAGE, null, null, null);
    howToFrame.add(howToPane);

    if (howToMessage == howToPane.OK_OPTION || howToMessage == howToPane.CANCEL_OPTION
            || howToMessage == howToPane.CLOSED_OPTION) {
        newGame.setVisible(true);
     }

   }
}

Sub Class (Brains of the game)

@SuppressWarnings("serial")
    public class RussianRouletteGame extends JFrame {

int lives = 5;
JTextField livesDisplay;
JButton gunButton;
ImageIcon gunCold;
ImageIcon gunActive;
JOptionPane endPane = new JOptionPane();
int endProgram;
int clicked = 0;
JTextField display;

public RussianRouletteGame() throws IOException, FontFormatException {
    super("Russian Roulette");
    Font westernOGFont = Font.createFont(Font.TRUETYPE_FONT,
            RussianRouletteGame.class.getClassLoader().getResourceAsStream("resources/WEST____.TTF"));
    Font westernNewFont = westernOGFont.deriveFont(westernOGFont.getSize() * 20F);

    gunCold = new ImageIcon(getClass().getClassLoader().getResource("resources/guncold.gif"));
    gunActive = new ImageIcon(getClass().getClassLoader().getResource("resources/gunactive.gif"));

    JPanel buttonPanel = new JPanel();
    JPanel livesPanel = new JPanel();
    JPanel displayPanel = new JPanel();

    display = new JTextField("  Click Gun To Play!", 15);

    livesDisplay = new JTextField("Lives: " + lives, 8);
    livesDisplay.setEditable(false);
    livesDisplay.setFont(westernNewFont);
    livesDisplay.setBackground(Color.BLACK);
    livesDisplay.setForeground(Color.WHITE);

    livesPanel.add(livesDisplay);
    livesPanel.setBackground(Color.BLACK);

    displayPanel.add(display);
    displayPanel.setBackground(Color.BLACK);
    display.setFont(westernNewFont);
    display.setEditable(false);
    display.setBackground(Color.BLACK);
    display.setForeground(Color.WHITE);

    LayoutManager overlay = new OverlayLayout(buttonPanel);
    buttonPanel.setLayout(overlay);
    buttonPanel.setBackground(Color.BLACK);
    gunButton = new JButton(gunCold);
    gunButton.setToolTipText("Click To Pull Trigger");
    gunButton.setAlignmentX(0.4f);
    gunButton.setAlignmentY(0.0f);
    buttonPanel.add(gunButton);

    add(buttonPanel, BorderLayout.CENTER);
    add(livesPanel, BorderLayout.NORTH);
    add(displayPanel, BorderLayout.SOUTH);

    gunButton.addActionListener(new ActionListener() {
        @SuppressWarnings("static-access")
        public void actionPerformed(ActionEvent event) {
            Random r = new Random();
            int rand = r.nextInt(6);
            clicked++;
            switch (rand) {
            case 0:
                display.setText(" Bang! You lost a life.");
                lives--;
                livesDisplay.setText("Lives: " + lives);
                break;
            case 1:
                display.setText("      You're alive!");
                break;
            case 2:
                display.setText("      You're alive!");
                break;
            case 3:
                display.setText("      You're alive!");
                break;
            case 4:
                display.setText("      You're alive!");
                break;
            case 5:
                display.setText("      You're alive!");
                break;
            }

            Timer imageSwitch = new Timer(984, new TimerListener());
            imageSwitch.setRepeats(false);
            if (rand == 0) {
                imageSwitch.start();
                gunButton.setIcon(gunActive);
            } else {
                gunButton.setIcon(gunCold);
            }

            if (lives == 0) {
                JFrame end = new JFrame();
                endPane = new JOptionPane();
                end.add(endPane);
                endProgram = endPane.showOptionDialog(null, "You survived " + clicked + " trigger pulls!",
                        "Game Over", endPane.OK_CANCEL_OPTION, endPane.INFORMATION_MESSAGE, null, null, null);

                if (endProgram == endPane.OK_OPTION || endProgram == endPane.CANCEL_OPTION
                        || endProgram == endPane.CLOSED_OPTION) {
                    System.exit(0);

                }
            }

        }

    });
}

private class TimerListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        gunButton.setIcon(gunCold);

    }

    {
        if (lives == 0) {
            display.setText("  Bang! You're dead.");
        }
     }

   }
}
\$\endgroup\$
  • \$\begingroup\$ Curious why five lives? And maybe add an option for which model of revolver to use so we can explore the odds of using a 6-chamber Colt SAA versus a 9-chamber .22, etc. More advanced version could also model stopping power and skull density, etc. because not every headshot is a killshot (just ask Serpico and Mrs. Buttafuoco). \$\endgroup\$ – nothingisnecessary Oct 1 '15 at 15:03
7
\$\begingroup\$

In the ActionListener code you are adding to gunButton, you have this switch statement:

Random r = new Radom();
int rand = r.nextInt(6);
...
switch(rand) {
    case 0:
        [lost a life text]
        break;
    case 1:
        [alive text]
        break;
    case 2:
        [alive text]
        break;
    case 3:
        [alive text]
        break;
    case 4:
        [alive text]
        break;
    case 5:
        [alive text]
        break;
    case 6:
        [alive text]
        break;
}

See something similar about the cases 1 through 6? They do the same exact thing. The only different one is case 0.

To make this much more efficient and clean, just simple replace this switch statement with an if statement checking that the random number is 0.

That would look like this:

if(rand == 0) {
    ...
} else {

}

In the else section is where you would put the whatever you did for cases 1 through 6.


In Java (and most every other language that I know), it is bad practice/a bad idea to reseed the random number generator every single time you go to use it.

That is what you are doing here:

public void actionPerformed(ActionEvent event) {
    Random r = new Random();
    int rand = r.nextInt(6);

By re-instantiating the Random class every time this method is called, you are re-seeding the random number generator.

Rather than doing this, you should set a Random instance to a field of this RussianRoulette class, instantiate it once, and then simple call nextInt on that field.

That way, you aren't constantly re-seeding the random number generator.


This seems a little fishy to me:

display.setText("      You're alive!");

And

display = new JTextField("  Click Gun To Play!", 15);

Why are you putting all those spaces before to message? I'm no detective, but it seems to me that you are using these spaces as a quick and dirty way to position text.

This makes your code quite ugly in these sections, and it would be a lot more cleaner and structured if you correctly positioned the text boxes in the right place in the first part.


These fields of RussianRouletteGame

int lives = 5;
JTextField livesDisplay;
JButton gunButton;
ImageIcon gunCold;
ImageIcon gunActive;
JOptionPane endPane = new JOptionPane();
int endProgram;
int clicked = 0;
JTextField display;

Should all have scope modifiers. By that I mean either public, private, protected etc.

Read here for more information on these modifiers.


Everything inside your RussianRouletteGame should have a single indent, then everything inside this class's methods should have another indent.

I do not think that it is very next to remove the indentation from the code inside the class, because it makes it less clear what code belongs to what.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the feedback! But the indentation is correct just not in Stack Exchange, I pasted it poorly, but in Eclipse it is indented correctly. But everything else is spot on and helps me a lot. Thanks again! \$\endgroup\$ – Ethan Cotler Jul 22 '15 at 1:44
1
\$\begingroup\$

Instead of:

livesDisplay = new JTextField("Lives: " + lives, 8);

I'd use:

JLabel livesLabel = new JLabel("Lives:");

...

livesDisplay = new JTextField(lives, 8);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.