2012-07-05 65 views
0

問題:當一個骨架進入的地方,我希望所有的玩家屏幕上使用此方法更新我World對象:如何讓一個人在此代碼中保留對玩家的引用?

/** 
* Say `text' in the Place `place'. The text will become visible at the 
* bottom of the text window of any Players currently watching `place'. 
* 
* @param place 
*   The place where the string will be displayed. 
* @param text 
*   The string to be diplayed. 
*/ 
public void sayAtPlace(Place place, String text) { 
    synchronized (players) { 
     Iterator<Player> ls = players.iterator(); 
     while (ls.hasNext()) { 
      Player p = ls.next(); 
      if (p.currentPlace() == place) { 
       p.say(text); 
      } 
     } 
    } 
} 

我有兩個班,人員和球員,我想一個人寫到textarea的方法時goTo的調用,但我不能讓Person對象有一個正確的引用到具有textarea的一個球員:

package adventure; 

import java.awt.*; 
import java.util.*; 

/** 
* ADT for persons which is completed which subclasses to creating actors with 
* specific properties 
*/ 
public class Person { 
    public Player player = null; 

    /** 
    * Name of the Person. 
    */ 
    public String name; 

    /** 
    * The World which this Person is associated with. 
    */ 
    public World world; 

    /** 
    * Tells where this Person is at the moment. 
    */ 
    public Place where;  


    /** 
    * Create Person named `name' in world `world'. 
    * 
    * @param world 
    *   The world where the Person is created. 
    * @param name 
    *   Name of the Person. 
    * @param app 
    *   An image used to display the Person. 
    */ 
    public Person(World world, String name, Image app) { 
     this.world = world; 
     this.name = name; 
     this.appearance = app; 
     // this.player = player; 
     where = world.defaultPlace(); 
     where.enter(this); 

     inventory = Collections.synchronizedCollection(new LinkedList<Thing>()); 
    } 

    /** 
    * Go directly, and quietly, to 'place'. That is to say, without posting a 
    * message that you're doing so. 
    * 
    * @param place 
    *   A string referring to the Place to go to. 
    * @see #goTo(Place) 
    * @see #go 
    */ 
    public void goTo(String place) { 
     goTo(world.getPlace(place), null); 
    } 

    /** 
    * Go directly, and quietly, to `whereTo'. That is to say, without posting a 
    * message that you're doing so. 
    * 
    * @param whereTo 
    *   The Place to go to. Can be null in which case nothing happens. 
    * @see #goTo(String) 
    * @see #go 
    */ 
    public void goTo(Place whereTo, Player player) { 
     if (whereTo != null) { 
      where.exit(this); 
      whereTo.enter(this); 
      // Update any Player's which are viewing place `where'. 
      world.update(where); 
      // Record our new position. 
      where = whereTo; 
      // Also update Player's here. 
      world.update(where); 
     } 

     System.out.println("player:"+player); 
     if(player != null){ 
      player.say("A terrifying skeleton warrior appears!"); 
     } 
     // send a msg which doors are available 
     Object[] doorNames = whereTo.exits.keySet().toArray(); 
     String s = ""; 
     int i = 1; 
     for (Object obj : doorNames) { 
      if (i < doorNames.length) { 
       s = s + obj.toString().toLowerCase(); 

       if(i<doorNames.length){ 

        s = s+ ","; 
       } 

      } if (i == doorNames.length && i > 1) { 
       s = s + " and " + obj.toString().toLowerCase(); 
      } 
      if (i == doorNames.length && i == 1) { 
       s = obj.toString().toLowerCase(); 
      } 
      ++i; 
     } 
     if (player != null) { 
      player.say("There are doors " + s); 
     } 
    } 



package adventure; 

import java.awt.*; 

/** 
* A Player object enables commands to control a certain person: »you». This 
* object is displayed graphically as a control panel where the user both can 
* control and follow the course of events 
*/ 
public class Player extends Panel { 
    private Person me; 
    private PlaceView placeview; 
    private Commands commands; 
    private TextArea textarea; 
    private static final long serialVersionUID = 100L; 

    /** 
    * Creates a new instance of Player, in World w, reflecting Person p. 
    * 
    * @param w 
    *   The world in which the Player will play in. 
    * @param p 
    *   The Person associated by Player. 
    */ 
    Player(World w, Person p) { 
     setLayout(new BorderLayout()); 
     setSize(650, 540); 

     me = p; 
     p.player = this; 
     placeview = new PlaceView(me); 
     commands = new Commands(me); 
     textarea = new TextArea("", 10, 60, TextArea.SCROLLBARS_VERTICAL_ONLY); 
     textarea.append("You are in a dungeon. The horrible shrieks of the undead chill your bones.\n"); 
     textarea.setEditable(false); 
     add("West", placeview); 
     add("East", commands); 
     add("South", textarea); 
     w.addPlayer(this); 
    } 


    /** 
    * Display a string in the players graphical interface. 
    * 
    * @param text 
    *   A string to display. 
    */ 
    void say(String text) { 
     textarea.append(text + '\n'); 
     textarea.repaint(); 
    } 

    /** 
    * Returns the Place of the Person associated with the Player. 
    * 
    * @return The Place of the Person associated with the Player. 
    */ 
    public Place currentPlace() { 
     return me.where; 
    } 
} 

你明白我想要做什麼?我想要工作的代碼是

System.out.println("player:"+player); 
    if(player != null && this.name.equals("Skeleton")){ 
     player.say("A terrifying skeleton warrior appears!"); 
    } 

但是,玩家引用的人是一個殭屍並不是實例化的。唯一擁有一個Player對象的Person是一個也是Person的Player。

你能幫我嗎?我還張貼的人的完整版本,玩家在這裏世界類

http://pastebin.com/RJCcr2ph(人) http://pastebin.com/eYSh8L9Q(播放器) http://pastebin.com/DKvRvEY8(世界)

+1

this.player代碼永遠不會在你的人物構造函數中使用,這正常嗎? – 2012-07-05 09:13:57

+5

您能否縮短程​​序以容納足以顯示問題的程序? – Keppil 2012-07-05 09:14:31

+0

@Adel Boutros你說得對,這是問題所在。如果我可以在Person構造器中實例化Player,那麼問題就會解決。但是當我成爲一個人時,我沒有球員。我需要以某種方式耦合對象。 – 2012-07-05 09:23:35

回答

2

如果我理解你的問題很好,你想有2班其中每個班級都有對另一個班級的參考。你需要的是創建其中的一個(讓它爲Foo),創建另一個類(讓它爲Boo)並通過構造函數將Foo的引用傳遞給它,然後通過setter在Foo類中設置Boo的引用方法。

例如:

public static void main(String[] args) 
{ 
    Foo f = new Foo(); 
    Boo b = new Boo(f); 
    f.setBoo(b); 
} 

class Foo 
{ 
    private Boo b; 

    public Foo() 
    { 
     // ... 
    } 

    public void setBoo(Boo b) 
    { 
     this.b = b; 
    } 
} 

class Boo 
{ 
    private Foo f; 

    public Boo(Foo f) 
    { 
     this.f = f; 
    } 
} 

現在,FooBoo參考,並Boo已在構造函數中的Foo參考:)

+0

如果你閱讀了關於這個問題的評論,他說類Foo的實例在創建Boo類的實例時是不知道的。因此,他不能通過構造函數 – 2012-07-05 09:59:47

+0

@AdelBoutros中的引用,然後他可以做相反的事情。其中一個應該在創造另一個之前存在。 – 2012-07-05 10:01:30

1

首先,你應該實例化人的成員「球員」 。

this.player = new Player(world, this); 

然後,更改從

public void goTo(String place) { 
    goTo(world.getPlace(place), null); 
} 

public void goTo(String place) { 
    goTo(world.getPlace(place), this.player); 
} 
相關問題