在java游戏中转向问题

时间:2015-12-01 16:34:04

标签: java swing event-driven-design

我创造了一个玩家与电脑对战的简单游戏。 我在转弯时间方面遇到了问题,通过点击LeftChoiceRightChoice按钮,计算机应该是第一个采取行动的人,而不是真正的玩家应该采取行动。

这是我在代码中遇到的问题:

public class GameForm extends javax.swing.JFrame {

/**
 * Creates new form GameForm
 */
final int SIZE = 10;
int CurrentSize = 10;
int PC_SUM=0;
int HUMAN_SUM=0;
boolean PC_TURN = true;
int[] RandArr = new int[SIZE];
public GameForm() {
    initComponents();
}
public void init(){
    for(int i = 0 ; i<SIZE;i++){
        RandArr[i] = (int)(Math.random()*100)+1;
    }
    jTextField3.setText("");
    jTextField4.setText(Integer.toString(PC_SUM));
    jTextField5.setText(Integer.toString(HUMAN_SUM));
}
public void HUMAN_updateLeft(){
    HUMAN_SUM+=RandArr[0];
    jTextField5.setText(Integer.toString(HUMAN_SUM));
    jTextField1.setText(Arrays.toString(RandArr));
    CurrentSize--;
    int [] NewRand = new int[CurrentSize];
     for(int i = 1 ; i<=CurrentSize;i++){
        NewRand[i-1] = RandArr[i];
    }
     RandArr = NewRand;
     jTextField2.setText(Arrays.toString(RandArr));
     PC_TURN = true;
}
public void HUMAN_updateRight(){
    HUMAN_SUM+=RandArr[CurrentSize-1];
    jTextField5.setText(Integer.toString(HUMAN_SUM));
    jTextField1.setText(Arrays.toString(RandArr));
    CurrentSize--;
    int [] NewRand = new int[CurrentSize];
     for(int i = CurrentSize-1 ; i>=0;i--){
        NewRand[i] = RandArr[i];
    }
     RandArr = NewRand;
     jTextField2.setText(Arrays.toString(RandArr));
     PC_TURN = true;
}
public static boolean WhoIsBigger(int[] arr){
int even=0,odd=0;

for(int i=0;i<arr.length;i+=2){
    if(i%2==0){
    even+=arr[i];
    odd+=arr[i+1];
    }
    else{
        odd+=arr[i];
        even+=arr[i+1];
    }
  }
return even>odd;
}
public void PC_updateLeft(){
    PC_SUM+=RandArr[0];
    jTextField4.setText(Integer.toString(PC_SUM));
    jTextField1.setText(Arrays.toString(RandArr));
    CurrentSize--;
    int [] NewRand = new int[CurrentSize];
     for(int i = 1 ; i<=CurrentSize;i++){
        NewRand[i-1] = RandArr[i];
    }
     RandArr = NewRand;
     jTextField2.setText(Arrays.toString(RandArr));
}
public void PC_updateRight(){
    PC_SUM+=RandArr[CurrentSize-1];
    jTextField4.setText(Integer.toString(PC_SUM));
    jTextField1.setText(Arrays.toString(RandArr));
    CurrentSize--;
    int [] NewRand = new int[CurrentSize];
     for(int i = CurrentSize-1 ; i>=0;i--){
        NewRand[i] = RandArr[i];
    }
     RandArr = NewRand;
     jTextField2.setText(Arrays.toString(RandArr));
}
public void PC_TURN(){
    if(WhoIsBigger(RandArr))
        PC_updateLeft();
    PC_updateRight();
}
public void FullGame(){
    while(RandArr.length>0){
        if(PC_TURN){
            PC_TURN();
            PC_TURN = false;
        }
    }
}
  //start button listener
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    init();
    jTextField2.setText(Arrays.toString(RandArr));
    jTextField1.setText("-");
    jButton1.setEnabled(false);
    FullGame();
}                                        
   //left button listener
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
HUMAN_updateLeft();
}                                        
//right button listener
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
HUMAN_updateRight();
}                

我怎么知道真正的玩家已经移动所以它会将PC_TURN更改为True并且游戏会继续进行?

here's a picture of how my GUI looks like:

3 个答案:

答案 0 :(得分:4)

首先,在命名变量时应遵循Java命名约定。就目前而言,PC_TURN看起来好像是一个常数,虽然它不是常数,因为你正在改变它的价值。所以更合适的名称是pcTurn

您似乎还有一个名为PC_TURN()的方法,我假设它是导致计算机轮流做某事的方法。因此,如果将其命名为takePCTurn()之类的描述,那会更好。注意整个使用camelCase。名称开头的大写字母应保留用于类和接口,而不是变量或方法。

您的方法名称

也是如此
public void FullGame()

应该写成

public void fullGame()

遵守这样的编码惯例,让其他人更容易阅读和理解您的代码,并保持一切干净整洁。这是一个很好的习惯。 :)

我不知道您的左右按钮在哪里被声明或者您为它们命名了什么,但是您需要为每个按钮添加一个事件监听器,这会导致点击它们时发生某些事情。我也不确定RandArr.length > 0的目的。你真的不需要循环,因为这是一个带有GUI的应用程序,除非你明确告诉它(例如通过点击关闭按钮),它永远不会关闭。所以我会给你一个通用的解决方案。

你基本上希望玩家转过来触发计算机,直到某些游戏超过条件为止。

示例:

//Assuming this is called when the Start button is clicked
public void fullGame() {
    takePCTurn();
}

public void takePCTurn() {
    //Do PC's turn logic
    //You might want to check if the Computer Won the game here        
}


class PlayerTurnListener implements ActionListener() {
    public void actionPerformed(ActionEvent e) {
        //Do Player's turn logic            
        //You might want to check if the Player Won the game here
        takePCTurn();
    }
}

//We can create an instance of our listener and add it to both buttons
PlayerTurnListener playerTurnListener = new PlayerTurnListener();

leftButton.addActionListener(playerTurnListener);
rightButton.addActionListener(playerTurnListener);

首先发生的事情是fullGame()由您的“开始”按钮调用,然后调用takePCTurn();,导致计算机轮流使用它。现在,只有玩家点击左或右按钮才会发生任何事情。当他们执行此操作时,会调用PlayerTurnListener actionPerformed()方法,您可以在其中执行某些逻辑,然后再次调用takePCTurn();

冲洗并重复直到游戏结束。

希望有所帮助:)

答案 1 :(得分:2)

您应该在左右按钮上附加clickListener。然后,当用户单击该事件将被触发时。您应该将PC_TURN更改为true,并在需要时重新运行循环。

示例:

JButton yourButton = new JButton("Your Button");
yourButton.addActionListener(new ActionListener()
{
  public void actionPerformed(ActionEvent e)
  {
    PC_TURN = true;
    // extra code
  }
});

答案 2 :(得分:1)

如果这是一个Swing或其他GUI,那么你将需要摆脱while循环。

请记住,GUI程序是非线性的并且是事件驱动的,因此,而不是限制while循环可能会完全损害您的GUI,您可以根据轮到它来改变程序的状态 - 有一个变量指示轮到它了 - 然后根据状态改变程序的行为。

如果您需要更具体的帮助,那么您将需要提出更完整的问题,包括一个包含足够代码和解释的问题,以便我们更好地理解您的问题(但不要太多代码)。

关于您发布的代码:

  • 是的,肯定会在循环时摆脱它。
  • 您的代码很难理解,主要是因为您的变量命名很差。与使用jTextField1之类的变量名称不同,使用具有逻辑意义的名称,使您的代码“自我调试”,例如humanScoreFieldcomputerScoreField等。
  • 还要学习并遵循标准的Java命名实践,包括让所有变量以小写字母开头,使用大写字母的类,使用camelCase,除了常量都是大写的。
  • 详细说明这段代码应该做什么,按钮和JTextfields代表什么,你想要什么行为等......