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の2つのクラスがあり、メソッドgoToが呼び出されたときにPersonが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!");
    }

ただし、ゾンビである人物のプレーヤー参照はインスタンス化されません。Playerオブジェクトがインスタンス化されている唯一のPersonは、PersonでもあるPlayerです。

手伝って頂けますか?また、Person、Player、Worldクラスのフルバージョンもここに投稿しました

http://pastebin.com/RJCcr2ph(個人) http://pastebin.com/eYSh8L9Q(プレーヤー) http://pastebin.com/DKvRvEY8(世界)

4

2 に答える 2

2

私があなたの質問をよく理解しているなら、あなたは各クラスが他のクラスへの参照を持っている2つのクラスを持ちたいと思うでしょう。必要なのは、それらの1つを作成し(それをFoo)、もう1つのクラスを作成し(それを) 、コンストラクターを介してそのクラスへBooの参照を渡し、次にsetterメソッドを介して内部クラスの参照を設定することです。FooBooFoo

例えば:

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 に答える