2016-08-02 65 views
-1

我對Java中的某些中間概念相當陌生。最近我做了一個名爲DazzleQuest的文本冒險遊戲,它完全在開發者控制檯/終端中運行。它讓我的朋友們成爲角色,所以我想通過將命令行和控制檯輸出的功能轉移到一個簡單的Swing界面中,讓他們看到他們並獲得Java體驗,包括一個JTextArea以顯示遊戲輸出和一個JTextField,與ActionListener,處理來自用戶的命令。將Swing集成到一個簡單的文本冒險遊戲中

我的主要DazzleQuest類包含的方法稱爲run()handleCommand(),我想我需要用我的Frame類和它的子類TextFieldHandler [延伸ActionListener]集成。 我在想,一般來說,整合這些方法和類的最好方法是什麼。我目前的嘗試一直令人困惑,儘管我對如何讓不同的課程和方法進行溝通有基本的把握,但這是暫定的。

道歉的單調性和缺乏特異性。我會分享我的代碼,但我不確定要給出多少和確切的內容。如果你認爲你可以回答我的問題,但需要我的例子,請說出來。即使僞代碼作爲答案,將不勝感激。謝謝!瞭解這可能對我作爲程序員的教育非常有幫助。

編輯:這裏是我完全在開發人員控制檯中運行的遊戲版本的代碼簡化示例。這是我的主要DazzleQuest類:

public class DazzleQuest { 

public void run() { 
    listCommands(); 
    for (;;) { 
     StdOut.println(new StringBuilder("You are in ").append(currentRoom.getName()).append(".").toString()); 
     StdOut.println(new StringBuilder("You can go to: ").append(currentRoom.listExits()).toString()); 
     StdOut.print("> "); 
     handleCommand(StdIn.readLine()); 
     StdOut.println(); 
    } 

public void handleCommand(String line) { 
     String[] words = line.split(" "); 
     if (words[0].equals("look")) 
      look(); 
     } 
    } 

} 

這裏是我目前的JFrame設置,在Frame類:

import java.awt.FlowLayout; 

import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.JTextArea; 

import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 

public class Frame extends JFrame { 

    public static JTextField field; 
    public JTextArea area; 

    public Frame() { 
     setLayout(new FlowLayout()); 

     area = new JTextArea(20, 40); 
     area.setEditable(false); 

     field = new JTextField(20); 
     add(area); 
     add(field); 
     pack(); 
     setVisible(true); 

     TextFieldHandler handler = new TextFieldHandler(); 

      field.addActionListener(handler); 
     } 

     public class TextFieldHandler implements ActionListener{ 

      public void actionPerformed(ActionEvent event) 
      { 
       String line = field.getText(); 
       area.append(line + "\n"); 
       field.setText(""); 
      } 
     } 


    public static void main(String args[]) { 

     Frame test = new Frame(); 
     test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

我知道如何打印輸出到JTextArea,而不是到控制檯。我的問題是如何得到handleCommand()Frame類中使用actionPerformed(),或者我應該在主類中設置一個動作偵聽器或類似的東西。任何實施的例子將不勝感激。

再次感謝您的任何事情,你可以告訴我!

回答

2

首先,關於包含代碼,您應該查看https://stackoverflow.com/help/mcve以瞭解如何幫助我們爲您提供幫助。

現在,考慮到你還沒有提供任何代碼(還!)給出你應該如何構建你的程序的建議是有點棘手。但是,無論如何我會進行一次嘗試,並在您提供MWE時編輯答案。

在你的情況下,JTextArea真的只是一個看中System.out.print因爲你只會用它來顯示冒險遊戲輸出的文本(如果我正確理解你的話)。所以基本上,您可以編寫一個接受字符串的方法,該方法會將該字符串附加到您的JTextArea。然後用這個方法替換你當前的輸出行。

然後你有你的JTextField你想替換你的(我猜)Scanner(System.in)與。我假設您知道如何設置響應Entersubmit按鈕的動作偵聽器。 如何設置這些並不奇怪,很多指南都會討論如何去做。 https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html就是一個很好的例子。

現在,在一般的關於你的程序的結構。 你做要依賴於用戶如何進入文本或你如何顯示它。我的意思是,你不希望輸入或顯示邏輯干擾你的遊戲(業務)的邏輯。你的遊戲邏輯應該從任何地方接收輸入,並將其輸出到任何地方。如何以及調用函數決定如何處理這些信息並不是遊戲邏輯關心的。

因此,應用於您發佈的方法名稱。我認爲run()是你踢球的地方。當你有,你總是想顯示輸出,你可能想在interface這裏有這應該是打印文本到任何文本元素,用於顯示文本的方法方法print(string)(等)通過,無論是System.out還是JTextArearun()方法永遠不需要知道。 handleCommand()也應該只接受一個值(我假設一個字符串),並處理它應該像它應該,不管是誰或什麼叫它。

我無法給你,沒有代碼的意見。但是我的一般建議是:不要將表示邏輯與業務邏輯混合在一起。並且儘可能少地給每種方法提供信息,因爲給予他們比實際需要的更多的信息通常會導致流程和結構的靈活性降低。


現在編輯一些代碼已被添加。

我知道如何將輸出打印到JTextArea而不是控制檯。我的問題是如何獲得handleCommand()與Frame類中的actionPerformed()一起使用

使用actionPerformed()方法。我建議這樣做,因爲如果你決定在將來某個時候(多人遊戲)決定使用Thread,那麼你就不必費盡心機。 https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html給出了一些關於如何編寫監聽器的好信息。但我也會給你一些建議代碼。

... 
area.setEditable(false); 

field = new JTextField(20); 
field.addActionListener(new SendText());  
.... 

class SendText implements ActionListener{ 
    public void actionPerformed(ActionEvent ae){ 
     if(ae.getSource() == field){ 
      String str = field.getText(); 
      if(!str.equals("")){ 
       commandHandler.handle(str); 
      } 
     } 
    } 
} 

然後重寫你的run()方法

public void run(){ 
    ui.print(commandHandler.listCommands()); 

    while(true){ 
     if(commandHandler.continue()){ 
      ui.print(commandHandler.events()); 
     } 
    } 
} 

所以,現在你有沒有真正的搭配要麼邏輯或顯示一個非常小的run()方法。 ui.print(str)是一種方法,你UI類(Frame你的情況),只是什麼附加給它的繪圖區域曾經串發送給它的,是它System.outJTextArea

commandHandler是新的。這是你的遊戲邏輯應該在的地方。它有一個方法handle(string)這是你的舊handleCommand(string)。它有一個返回布爾值的方法continue()。無論何時您希望故事繼續,布爾值應該設置爲true,例如,當用戶輸入命令時。最後是events()(這是一個不好的名字),它返回自從發送上一個命令後發生的事情,併爲用戶提供關於下一步做什麼的選項。我沒有完成這個,因爲我只是想把這個概念給你。用戶界面不執行任何邏輯處理。 run()方法不期望任何東西,它只是繼續檢查是否continue()爲真。commandHandler是所有bizz的地方。

現在,你確實有一個無限循環運行。所以如果你有任何性能問題,你可以看看Thread。這個模型應該支持它。

+0

非常感謝您的回答!演示文稿和業務邏輯的分離對我來說是一個有趣的主題 - 我曾經做過一個遊戲,其中包含遊戲規則和邏輯的「Model」類與包含顯示方法,控件的主遊戲類分離以及遊戲的開始和結束。這是你的意思嗎?我將嘗試明天覆制我的實現示例,並提供更具體的建議。 – speers

+0

@speers是的。這聽起來像我的意思。 [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)模式非常標準,並有很好的理由。它使得更換用戶界面變得更加容易,而不會改變執行數據處理的邏輯。 – Chewtoy

+0

我會牢記這一點。我目前的程序非常簡單,我想我可以很容易地將模型與顯示分開,但是在我已經想出如何使其在GUI中運行後,可能會這樣做。我只是用代碼示例更新了我的帖子,所以如果你可以再看一看,那將是非常棒的! – speers