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);
            }
        }
    }
}

我有两个类,Person 和 Player,我希望 Person 在goTo调用该方法时写入 textarea,但我无法使 Person 对象正确引用具有 textarea 的 Player:

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!");
    }

但是没有实例化作为僵尸的 Person 的玩家引用。唯一实例化了 Player 对象的 Person 是也是 Person 的 Player。

你能帮助我吗?我还在此处发布了 Person、Player 和 World 类的完整版本

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

4

2 回答 2

2

如果我很好地理解了您的问题,那么您希望拥有 2 个类,其中每个类都有另一个类的引用。您需要创建其中一个(让它成为Foo),创建另一个类(让它成为Boo)并通过Foo构造函数传递对它的引用,然后通过 setter 方法设置Boo内部类的引用。Foo

例如:

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;
    }
}

现在,Foo有一个参考Boo,并且Boo有一个参考Foo:)

于 2012-07-05T09:40:10.303 回答
1

首先,您应该在构造函数中实例化 Person 的成员 'player'。

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);
}
于 2012-07-05T09:40:56.823 回答