-1

I added more prompts now and the message boxes should say different things but they are stuck at "You go forward and hit a wall" and "You are now facing the opposite direction" They don't change when they should and the third option that I added isn't showing up. I can already get the messages to display right the first time but after you make the first decision and the buttons change, the message boxes do not. Again, here's my code:

package game;

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

public class game extends JFrame implements ActionListener {

JLabel prompt;
JTextField name;
JTextField name1;
JButton click;
JButton click1;
String storeName;
String storeName1;
JButton click2;
private int gameState = 0;



public game(){

    setLayout(null);
    setSize(550,250);
    setTitle("Text Adventure");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    prompt = new JLabel("You find yourself in a tunnel.");
    click = new JButton("Go forward!");
    click1 = new JButton("Turn around!");
    click2 = new JButton();
    name = new JTextField();
    name1 = new JTextField();
    prompt.setBounds(170,30,1300,30);
    click.setBounds(100,130,100,30);
    click.addActionListener(this);
    click1.setBounds(300,130,125,30);
    click1.addActionListener(this);
    click2.setBounds(185,175,145,30);
    click2.addActionListener(this);
    add(click);
    add(click1);
    add(name);
    add(name1);
    add(prompt);


}

public void actionPerformed(ActionEvent e) {

    if (gameState == 0){

    if(e.getSource() == click) {

        JOptionPane.showMessageDialog(null, "You go forward and hit a wall.");
    }

    if(e.getSource() == click1) {

        JOptionPane.showMessageDialog(null, "You are now facing the opposite direction.");
        prompt.setBounds(50,30,1300,30);
        prompt.setText("What would you like to do now that you are facing the opposite direction?");
        click.setText("Go forward!");
        click1.setText("Turn on light.");
    }
        gameState = 1;
    }

    else if (gameState == 1){

        if(e.getSource() == click) {

            JOptionPane.showMessageDialog(null, "You walk down the tunnel until you hit an intersection.");
            prompt.setBounds(100,30,1300,30);
            prompt.setText("Which way would you like to go at the intersection?");
            click.setText("Left!");
            click1.setText("Right!");
            add(click2);
            click2.setText("Keep going!");
        }
        if(e.getSource() == click1){

            JOptionPane.showMessageDialog(null, "You turn on your light.");
            prompt.setBounds(220,30,1300,30);
            prompt.setText("What now?");
            click.setText("Go forward!");
            click1.setText("Sit down.");

        }
        gameState = 2;
    }
    else if (gameState == 2) {

        if (e.getSource() == click) {

            JOptionPane.showMessageDialog(null, "You turn left and walk into a dark room.");
            prompt.setBounds(210,30,1300,30);
            prompt.setText("What do you do?");
            click.setText("Cry");
            click1.setText("Shout 'Hello?'");
            click2.setText("Explore the room");

        }

}
}

public static void main(String args[]){

    game s = new game();
    s.setVisible(true);
    }
}
Dogrules23
  • 21
  • 1
  • 5
  • Possible duplicate of [How to present a simple alert message in java?](http://stackoverflow.com/questions/9119481/how-to-present-a-simple-alert-message-in-java) – Christoph Nov 17 '15 at 14:26
  • I edited to explain more about my problem. – Dogrules23 Nov 17 '15 at 14:29
  • Adding `this` as an action listener means that the class' `actionPerformed` method will be called, every time. Your `actionPerformed1` method is never called. – Mage Xy Nov 17 '15 at 14:34
  • What would I do to call `actionPerformed1` ? – Dogrules23 Nov 17 '15 at 14:36
  • You would have to manually call it, probably from `actionPerformed`. Truthfully, unless the game has only a handful of rooms, I would rethink the architecture of the program, because if you keep going the way you are, you'll end up with a massive `actionPerformed` method with hundreds of if conditions. – Mage Xy Nov 17 '15 at 14:38
  • So I would just use the same `actionPerformed` statement? I didn't think that would work. – Dogrules23 Nov 17 '15 at 14:45
  • Yes. You would have to keep track of what the current state of the game was, and then act accordingly depending on which button was pressed and what the current state is. – Mage Xy Nov 17 '15 at 14:53
  • When I make the first "Turn Around!" choice, it now displays "You are now facing the opposite direction" and then immediately displays "You turn on your light". It makes no sense. What happened? – Dogrules23 Nov 17 '15 at 15:42
  • @Dogrules23: See my answer and let me know if you have any questions. – Mage Xy Nov 17 '15 at 15:57

2 Answers2

2

Mage Xy gave you one solution in his answer. He also told you the biggest drawback.

HOWEVER, the major downside to this solution is the massive code bloat. As you can already see, just two rooms takes up a lot of space code-wise... what if you want to have 100 rooms? Your actionPerformed method is going to be thousands of lines of code long!

You can look at your rooms as a tree. Based on what you said in your question, you have this structure.

Tunnel <-> Room

In other words, you can move from the tunnel to the room, and the room to the tunnel.

When you want to construct a Java Swing GUI game, it helps to separate the game model from the game view and game controllers. This separation of concerns allows you to focus on one part of the game at a time.

So, what would a game model for your game look like?

Let's start with a room definition. Based on your code and Mage Xy's code, here's one possibility

package com.ggl.text.adventure;

import java.util.List;

public class Room {

    private final int roomNumber;

    private int northRoomNumber;
    private int eastRoomNumber;
    private int southRoomNumber;
    private int westRoomNumber;

    private List<String> objectsInRoom;

    private String roomName;

    public Room(int roomNumber) {
        this.roomNumber = roomNumber;
    }

    public int getNorthRoomNumber() {
        return northRoomNumber;
    }

    public void setNorthRoomNumber(int northRoomNumber) {
        this.northRoomNumber = northRoomNumber;
    }

    public int getEastRoomNumber() {
        return eastRoomNumber;
    }

    public void setEastRoomNumber(int eastRoomNumber) {
        this.eastRoomNumber = eastRoomNumber;
    }

    public int getSouthRoomNumber() {
        return southRoomNumber;
    }

    public void setSouthRoomNumber(int southRoomNumber) {
        this.southRoomNumber = southRoomNumber;
    }

    public int getWestRoomNumber() {
        return westRoomNumber;
    }

    public void setWestRoomNumber(int westRoomNumber) {
        this.westRoomNumber = westRoomNumber;
    }

    public List<String> getObjectsInRoom() {
        return objectsInRoom;
    }

    public void setObjectsInRoom(List<String> objectsInRoom) {
        this.objectsInRoom = objectsInRoom;
    }

    public String getRoomName() {
        return roomName;
    }

    public void setRoomName(String roomName) {
        this.roomName = roomName;
    }

    public int getRoomNumber() {
        return roomNumber;
    }

}

This class allows you to define the name for each room and the objects contained in each room. A room can have zero or more objects. The room number is a unique number for each room that starts with zero or one and goes up.

You also define the room numbers that you enter when you go north, east, south, or west. You can set a direction room number to -1 when there's no room in that direction.

Defining these rooms happens in another class. You create a List of rooms and define each room. Once you've created this List of rooms, creating the Swing view and controllers becomes much easier.

Community
  • 1
  • 1
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
1

Following up on the discussin we had in the comments of your question:

Implementing ActionListener tells other parts of your program that this class (game) has an actionPerformed(ActionEvent) method. When you assign this as a button's actionListener, that button will looks for the actionPerformed method when it is clicked. The button has no idea the actionPerformed1 method even exists (since, programmatically, these two methods are completely unrelated).

So how can you include the code for your next room? Well, it gets tedious.

First, you need a way to keep track of the state of the game. In your case, perhaps you can just keep track of which "room" the player is in. This can probably be done with a simple int field:

private int gameState = 0;

Then, using your game's state, you need to determine what actions are currently tied to the buttons. This is the part that would go into your actionPerformed method.

public void actionPerformed(ActionEvent e)
{
    if (gameState == 0)
    {
        if(e.getSource() == click) 
        {
            JOptionPane.showMessageDialog(null, "You go forward and hit a wall.");
        }
        if(e.getSource() == click1)
        {
            JOptionPane.showMessageDialog(null, "You are now facing the opposite direction.");
            prompt.setText("What would you like to do now?");
            click.setText("Go forward!");
            click1.setText("Turn on light.");
            gameState = 1; // Update the current state of the game to represent the new "room"
        }
    }
    else if (gameState == 1)
    {
        if(e.getSource() == click) {

            JOptionPane.showMessageDialog(null, "You walk down the tunnel until you hit an intersection.");
            prompt.setText("Which way would you like to go?");
            click.setText("Left!");
            click1.setText("Right!");
            add(click2);
            click2.setText("Keep going!");
            gameState = 2;
        }
        if(e.getSource() == click1)
        {

        }
    }
    else if (gameState == 3)
    {
        // etc.
    }
}

This quickly and easily solves the problem and allows the player to progress through the game the way you want.

HOWEVER, the major downside to this solution is the massive code bloat. As you can already see, just two rooms takes up a lot of space code-wise... what if you want to have 100 rooms? Your actionPerformed method is going to be thousands of lines of code long! That's completely ridiculous.

There are several ways to solve this problem, but they are more involved and which one you pick depends largely on the needs of your application.

Mage Xy
  • 1,803
  • 30
  • 36
  • Thanks so much! I appreciate it, I'm just going to have a few to start off with. I just want this to be a small game that my friends can play if they want. – Dogrules23 Nov 17 '15 at 16:05
  • 95 lines and two rooms. – Dogrules23 Nov 17 '15 at 17:51
  • I got it working the way I want now, thanks so much! – Dogrules23 Nov 17 '15 at 18:00
  • @Dogrules23 Glad I could help. Remember to mark whichever answer helped you the most as accepted. – Mage Xy Nov 17 '15 at 21:17
  • I'm having another issue, when someone selects "Go forward!" first then chooses "Turn around!" it shows the message "You turn on your light." I want it to just say "You are facing the opposite direction." like it should. – Dogrules23 Nov 18 '15 at 02:28
  • That sounds like you're setting your game states incorrectly. – Mage Xy Nov 18 '15 at 14:43
  • You're setting the game state in the wrong place - look at your curly brackets. You're setting `gameState = 1` whenever `gameState` is 0, regardless of whether the player has chosen. That goes for the other ones too - only update `gameState` when you actually want to change the current "room" or state of the game. – Mage Xy Nov 18 '15 at 15:44