Sign in to follow this  

[java] loop help with swing

This topic is 4783 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've made a text based turn based fighting application game. You fight an enemy until your enemy or your life points run out. It works perfectly as a plain application, but I'm running into problems converting it to swing, so I can make it look nice with a GUI. I'm having the text display in a JTextArea. Problem is when it loops it never gives me the chance to attack, it only allows the enemy to attack until my life points reach 0. What can I do to have it stop when its my turn, so I can type in my attack? Here is the part of the code that is creating this problem:
           
     while(!gameover) //loops until gameover
  {
    if(first_player) //what happens if the player or eggman is chosen first
    {
      players[r] = 0; //eggman's turn
   
     //attack damages
      int E_attack1 = 5;
      int E_attack2 = 10;
      int E_attack3 = 15;
       
      //attacks in an array
      int[] attacks = { E_attack1, E_attack2, E_attack3 };
      int A = attacks.length;
      int p = (int) (Math.random() * A); //makes the attacks random
 
      //the effects of what the damages will do to the Player's Life Points
      if(attacks[p] == E_attack1)
     {
       
      Player_LP -=E_attack1;
       
      }
      else
      if(attacks[p] == E_attack2)
      {
       
      Player_LP -=E_attack2;
 
      }
      else
      if(attacks[p] == E_attack3)
      {
       
      Player_LP -=E_attack3;
       
       }
       text.append("Eggman does "+ attacks[p] + " damage." + "\n"); //the print out of the attack and damage
     
       }
       //players turn
       else
      {
         
        //players attack damages
        int attack1 = 5;
        int attack2 = 10;
        int attack3 = 15;
        text.append( "Choose attack1 , attack2, or attack3: "  + "\n"); //gives player a choice of attacks
        inputField.getText(); //gets the text
        text.getText(); //gets the text from the text area
 
        //what happens when one of the attacks is chose
        if(text.equals("attack1"))
       {
    //the effect of the attack on Eggman's life points
        Eggman_LP -=attack1;
        text.append( "\n" + "You attack with attack1 causing " + attack1 + " damage to Eggman."+"\n"); //the print out of the attack and the damage
        }
        else
 
       if (text.equals("attack2"))
      {
        Eggman_LP -=attack2;
        text.append( "\n" + "You attack with attack2 causing " + attack2 + " damage to Eggman."+"\n");
      }
      else
      if(text.equals("attack3"))
     {
     Eggman_LP -=attack3;
     text.append( "\n" + "You attack with attack3 causing " + attack3 + " damage to Eggman."+"\n");
     }
     }
     first_player = !first_player; //make it turn base
   
     //how to determine gameover
     if (Player_LP <=0)  
    {
        gameover = true;
        text.append("Eggman Wins");
    }
    else
    if (Eggman_LP <=0)
   {
    gameover = true;
    text.append("You Win");  
   
   }
  } 

And the game appears like this when I run it:
Quote:
What is your player name: DKN You chose DKN as your player name. Your enemy will be Eggman. You and your opponent will have 100 life points. The player to lose all of their life points loses the game. You go first Choose attack1 , attack2, or attack3: Eggman does 10 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 10 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 15 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 15 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 5 damage. Choose attack1 , attack2, or attack3: Eggman does 15 damage. Eggman Wins
[Edited by - Javacell on October 10, 2004 11:26:59 PM]

Share this post


Link to post
Share on other sites
Well, you didn't give the types of any of the variables, but if "text" and "inputField" are Swing objects, it's pretty safe to say that

inputField.getText(); //gets the text
text.getText(); //gets the text from the text area

won't do anything useful. Also, for debugging, try adding an else clause to that big series of ifs so you can see when text (I think you should have inputField.getText() there?) isn't any of the "legal" inputs.

Share this post


Link to post
Share on other sites
Quote:
Original post by NightMonkey
The JTextArea.getText() function only reads the text currently in the text area it does not wait for the enter key to be pressed. You need to use some kind of keyListener/actionListener to know when the user has finished typing.


This monkey is telling the truth! Also, unless this is supposed to be real-time, you might want to put the whole thing in a modal dialog - that way, you can just call dialog.show() and then collect the answer.

Share this post


Link to post
Share on other sites

// Description : testing out key listeners on a text area.

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

public class KeyTest
{
private final static int WIDTH = 500;
private final static int HEIGHT = 400;

public static void main(String[] args)
{
JFrame frame;
frame = new JFrame("Testing Keys");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(new KeyPanel());
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
}
}

class KeyPanel extends JPanel
{
private JTextArea textA;

KeyPanel()
{
textA = new JTextArea();
textA.addKeyListener(new MyTextListener());
setLayout(new GridLayout(1,1));
add(textA);
}

private class MyTextListener implements KeyListener
{
public void keyPressed(KeyEvent event)
{
System.out.println("Enter key pressed.");
}

public void keyTyped(KeyEvent event)
{
}

public void keyReleased(KeyEvent event)
{
}
}
}



I did a little test, and in the above code keyPressed is called every time I press enter in the text area. So I suggest putting logic in the keyPressed method to either continue with your attack, or cancel your attack if it's not your turn. I thought that maybe text area's could not have key listeners so I made the little test to see.

Share this post


Link to post
Share on other sites
First Post! Hope it's helpful.


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

public class ActionGrabber extends JFrame implements Runnable
{
private JTextField inputField;
private boolean inputEntered, gameOver;

public ActionGrabber()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);

inputField = new JTextField();

getContentPane().add(inputField);
getContentPane().setLayout(null);
inputField.setBounds(50,50, 100, 20);
inputField.addActionListener(new TextListener());
setSize(256,256);
setVisible(true);

inputEntered = false;

new Thread(this).start();
}

public void run()
{
while(!gameOver)
{
if (inputEntered)
{
//Do whatever you want to do with the text here
inputEntered = false;
}

Thread.sleep(1);
}
}

private class TextListener extends ActionListener
{
public void ActionPerformed(ActionEvent e)
{
inputEntered = true;
}
}

public static void main(String[] args)
{
ActionGrabber me = new ActionGrabber();
}
}



Basically, this will loop until you flip gameOver to true. At each cycle, it will see if a boolean is flipped. This boolean is flipped by an ActionListener focused on a JTextField.
Whenever enter is pressed in the JTextField, the ActionListener will fire, the boolean will trip, and next game cycle whatever code you want will execute. Just replace the comment with your code. Make sure you leave in the code to flip the boolean back to false, or else every cycle the class will think text has been entered.

PS: The Thread.sleep(1) at the end of the loop is there to prevent the CPU usage from jumping to 100%.

Share this post


Link to post
Share on other sites
Here is what I tried:

     
public void run()
{
String name = inputField.getText()
text.append("\n" + "You chose " + name + " as your player name."+ "\n"); //print name
text.append("Your enemy will be Eggman."+ "\n");
text.append("You and your opponent will have 100 life points."+ "\n");
text.append("The player to lose all of their life points loses the game."+ "\n");

if(choose_name) //what happens when a player is chosen
{
players[r] = 0;
text.append("\n" + "Eggman goes first." + "\n");
}
else
{
text.append("\n" + "You go first." + "\n");
}
while(!gameOver)//loops until gameover
{
if(first_player) // what to do with the first player
{
players[r] = 0; //eggman's turn
//attack damage
int E_attack1 = 5;
int E_attack2 = 10;
int E_attack3 = 15;

//random attacks
int[] attacks = { E_attack1, E_attack2, E_attack3 };
int A = attacks.length;
int p = (int) (Math.random() * A);

//what happens when an attack is chosen
if(attacks[p] == E_attack1)
{
Player_LP -=E_attack1;
}
else
if(attacks[p] == E_attack2)
{
Player_LP -=E_attack2;

}
else
if(attacks[p] == E_attack3)
{
Player_LP -=E_attack3;

}
//display the attack
text.append( "\n" + "Eggman does "+ attacks[p] + " damage." + "\n");
}
else
{
int attack1 = 5;
int attack2 = 10;
int attack3 = 15;


//get input for attacks
String battacks = inputField.getText();

//display attack
text.append( "\n" + "Choose attack1 , attack2, or attack3: " + battacks);




//what happens when an attack is chosen
if(battacks.equals("attack1"))
{
Eggman_LP -=attack1;
text.append("\n" + "You attack with attack1 causing " + attack1 + " damage to Eggman."+"\n");

}
else

if (battacks.equals("attack2"))
{
Eggman_LP -=attack2;
text.append("\n" + "You attack with attack2 causing " + attack2 + " damage to Eggman."+"\n");
}
else
if(battacks.equals("attack3"))
{
Eggman_LP -=attack3;
text.append("\n" + "You attack with attack3 causing " + attack3 + " damage to Eggman."+"\n");
}
}

first_player = !first_player; //make it turn base

//how to determine gameover
if (Player_LP <=0)
{
gameover = true;
text.append("Eggman Wins");
}
else
if (Eggman_LP <=0)
{
gameover = true;
text.append("You Win");

}


if (inputEntered)
{
inputEntered = false;
}
try
{
Thread.sleep(1000); //how long to wait for input
} catch (InterruptedException e)
{
}

//display life points
player_stats.setText("" + Player_LP);
eggman_stats.setText(""+ Eggman_LP);
}
}
//Button Class
private static class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)//Event handler method
{
inputEntered = false;
}
}






Only problem now is that it doesn't give me a chance to input my name, it doesn't wait for me to input something, if I make the thread sleep longer, just to get to my or eggman's turn takes to long, it takes to long for eggman to attack, clicking the button doesn't do anything, and it takes the input of what I typed in the textfield even though I didn't click a button to tell it to do so.

[Edited by - Javacell on October 30, 2004 1:04:59 AM]

Share this post


Link to post
Share on other sites
Now with better results:


     
public void run()
{
String name = inputField.getText()
text.append("\n" + "You chose " + name + " as your player name."+ "\n"); //print name
text.append("Your enemy will be Eggman."+ "\n");
text.append("You and your opponent will have 100 life points."+ "\n");
text.append("The player to lose all of their life points loses the game."+ "\n");

if(choose_name) //what happens when a player is chosen
{
players[r] = 0;
text.append("\n" + "Eggman goes first." + "\n");
}
else
{
text.append("\n" + "You go first." + "\n");
}
while(!gameOver)//loops until gameover
{


if (inputEntered)
{
if(first_player) // what to do with the first player
{
players[r] = 0; //eggman's turn
//attack damage
int E_attack1 = 5;
int E_attack2 = 10;
int E_attack3 = 15;

//random attacks
int[] attacks = { E_attack1, E_attack2, E_attack3 };
int A = attacks.length;
int p = (int) (Math.random() * A);

//what happens when an attack is chosen
if(attacks[p] == E_attack1)
{
Player_LP -=E_attack1;
}
else
if(attacks[p] == E_attack2)
{
Player_LP -=E_attack2;

}
else
if(attacks[p] == E_attack3)
{
Player_LP -=E_attack3;

}
//display the attack
text.append( "\n" + "Eggman does "+ attacks[p] + " damage." + "\n");
}
else
{
int attack1 = 5;
int attack2 = 10;
int attack3 = 15;


//get input for attacks
String battacks = inputField.getText();

//display attack
text.append( "\n" + "Choose attack1 , attack2, or attack3: " + battacks);




//what happens when an attack is chosen
if(battacks.equals("attack1"))
{
Eggman_LP -=attack1;
text.append("\n" + "You attack with attack1 causing " + attack1 + " damage to Eggman."+"\n");

}
else

if (battacks.equals("attack2"))
{
Eggman_LP -=attack2;
text.append("\n" + "You attack with attack2 causing " + attack2 + " damage to Eggman."+"\n");
}
else
if(battacks.equals("attack3"))
{
Eggman_LP -=attack3;
text.append("\n" + "You attack with attack3 causing " + attack3 + " damage to Eggman."+"\n");
}
}

first_player = !first_player; //make it turn base

//how to determine gameover
if (Player_LP <=0)
{
gameover = true;
text.append("Eggman Wins");
}
else
if (Eggman_LP <=0)
{
gameover = true;
text.append("You Win");

}

inputEntered = false;
}
try
{
Thread.sleep(1000); //how long to wait for input
} catch (InterruptedException e)
{
}

//display life points
player_stats.setText("" + Player_LP);
eggman_stats.setText(""+ Eggman_LP);
}
}
//Button Class
private static class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)//Event handler method
{
inputEntered = false;
}
}










Now the only problems are it doesn't give a chance to input my name(if I put the 'input name' part of the code in the while loop or in if (inputEntered), it is repeatedly displayed over and over again) and that I have to click a button in order to get each line to display.

Ex:
You go first.
//Now I have to click a button for it to ask for my attack

Choose attack1 , attack2, or attack3: attack3
//of course I have to click a button now to submit the attack

You attack with attack3 causing 15 damage to Eggman.
//Now I have to click a button in order for eggman to do his damage

Eggman does 10 damage.
//have to click a button in order for it to ask for my attack, but yet it gets my attack input at this point also

[Edited by - Javacell on November 1, 2004 3:54:13 PM]

Share this post


Link to post
Share on other sites

This topic is 4783 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this