java - 如何让 Person 在此代码中保留对 Player 的引用?

标签 java object game-engine modeling

问题:当骨架进入一个地方时,我希望在我的 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,我希望在调用方法 goTo 时将 Person 写入文本区域,但我无法使 Person 对象具有正确的引用具有文本区域的播放器:

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 (世界)

最佳答案

如果我很好地理解你的问题,你想要有 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;
    }
}

现在,Foo 具有 Boo 的引用,而 Boo 具有 Foo 的引用:)

关于java - 如何让 Person 在此代码中保留对 Player 的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11341193/

相关文章:

c++ - 如何计算 32 位 float epsilon?

c++ - PixelToaster 库上的鼠标处理

javascript - 在 JS 中给字典键加上引号

javascript - 如何重新格式化对象中的数据。 (我如何使行成为键,其他列成为值)

javascript - AABB 碰撞解决滑边

java - spring mvc dao 和服务 bean 映射

javascript - 使用变量 "name"不适用于 JS 对象

java - maven 中的 -Denvironment 选项是什么?

java - BigDecimal 行为的差异

java - 协方差在这里安全吗?