未显示游戏消息

时间:2017-12-22 00:52:30

标签: java android adventure

我正在为Android编写一款小型冒险游戏。代码和演示可从我的repository获得。我有程序尝试实现一个游戏消息,显示的信息是角色进入房间。但该消息仅显示"有时"这令人困惑。

该消息应该是"一个可怕的骷髅战士进入。"在代码中,这部分属于班级Person.java。这个游戏信息并不总是显示出来,我想知道为什么?

package dev.game.adventure;

import java.util.*;

/**
 * ADT for persons which is completed which subclasses to creating actors with
 * specific properties
 */
public class Person {

    /**
     * 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 place;

    /**
     * The inventory, contains Things.
     */
    public Collection<Thing> things;
    FullscreenActivity target;
    /**
     * Shows how the Person looks like
     */
    public int image;

    public String getHelloWorldString() {
        return "HELLO WORLD";
    }

    /**
     * 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, int app, FullscreenActivity target) {
        this.world = world;
        this.name = name;
        this.image = app;
        this.target = target;
        place = world.defaultPlace();
        if (this.getName().equals("Skeleton")) {
            world.sayAtPlace(place,
                    "A terrifying skeleton warrior appears!", target);
        }
        place.enter(this, target);
        things = 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, FullscreenActivity)
     * @see #go
     */
    public void goTo(String place, FullscreenActivity target) {
        goTo(world.getPlace(place), target);
    }

    /**
     * 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(Place, FullscreenActivity
     * @see #go
     */
    public void goTo(Place whereTo, FullscreenActivity target) {
        if (whereTo != null) {
            place.exit(this, target);
            whereTo.enter(this, target);

            if (this.getName().equals("Skeleton")) {
                world.sayAtPlace(whereTo,
                        "A terrifying skeleton warrior appears!", target);
            }

            world.update(place, target);
            // Record our new position.
            place = whereTo;
            // Also update Player's here.
            world.update(place, target);
        }
    }

    /**
     * Go through the door `door', verbosly. That is to say, post a message that
     * you re doing so. Don't complain if the door doesn't exist.
     *
     * @param door Name of the door to exit through.
     * @see #goTo(String)
     * @see #goTo(Place, FullscreenActivity
     */
    public void go(String door, FullscreenActivity target) {
        Place whereTo = place.getExit(door);
        if (whereTo != null) {
            if (!name.equals("You")) {
                world.sayAtPlace(place, name + " goes " + door, target);
            } else {
                world.sayAtPlace(place, name + " are going " + door, target);
            }
            goTo(whereTo, target);
        }
    }

    /**
     * Print `text' in the bottom of the text window. Prepend it with a cue
     * indicating who is speaking. The text will only show up for Players at the
     * same Place as the one who is speaking.
     *
     * @param text String to be displayed.
     */
    public void say(String text, FullscreenActivity target) {
        world.sayAtPlace(place, name + " says: " + text, target);
    }

    /**
     * Grab a Thing from this Place and place it in the inventory.
     *
     * @param thingName Name referring to a Thing to be grabbed.
     * @see #drop
     */
    public synchronized void grab(String thingName, FullscreenActivity target) {
        Thing item = place.removeThing(thingName);
        if (item != null) {
            things.add(item);
            world.sayAtPlace(place, name + " is taking " + thingName, target);
            world.update(place, target);
        }
    }

    /**
     * Drop a Thing the ground by deleting it from the inventory.
     *
     * @param thingName Name referring to a Thing to be dropped.
     * @see #grab
     */
    public synchronized void drop(String thingName, FullscreenActivity target) {
        Thing item = findThing(thingName);

        if (item != null) {
            things.remove(item);
            place.addThing(item);
            world.sayAtPlace(place, name + " is dropping " + thingName, target);
            world.update(place, target);
        }
    }

    /**
     * Find a Thing in our inventory.
     *
     * @param thingName The name of a thing to find.
     */
    public Thing findThing(String thingName) {
        synchronized (things) {
            Iterator<Thing> iterate = things.iterator();
            while (iterate.hasNext()) {
                Thing t = (Thing) iterate.next();
                if (t.name.equals(thingName))
                    return t;
            }
        }
        return null;
    }

    /**
     * Respond to a query from another person.
     *
     * @param questioner The Person querying.
     */
    public void query(Person questioner) {
        // Default case - don't say anything
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public World getWorld() {
        return world;
    }

    public void setWorld(World world) {
        this.world = world;
    }

    public Collection<Thing> getThings() {
        return things;
    }

    public void setThings(Collection<Thing> things) {
        this.things = things;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }
}

世界级

package dev.game.adventure;

import java.util.*;

/**
 * The data structure that describes the world.
 */
public abstract class World { // "implements" Playable
    public Adventure owner;

    public AdventureGame ag;

    public AdventureGame getAg() {
        return ag;
    }

    /**
     * Players watching this World
     */
    public Collection<Player> players;

    public void setAg(AdventureGame ag) {
        this.ag = ag;
    }

    /**
     * Places in this World
     */
    public Map<String, Place> places;

    public Map<String, Place> getPlaces() {
        return places;
    }

    public void setPlaces(Map<String, Place> places) {
        this.places = places;
    }

    public Collection<Player> getPlayers() {
        return players;
    }

    public void setPlayers(Collection<Player> players) {
        this.players = players;
    }

    /**
     * Create a World. `a' is a reference to the Adventure itself. This reference is
     * used when loading images and sounds.
     *
     * @param a An instance of adventure.
     */
    public World(Adventure a) {
        places = new HashMap<String, Place>();
        players = new LinkedList<Player>();
        owner = a;
    }

    // Every World must implement this method which returns at what
    // Place in the World new Persons are created.
    abstract Place defaultPlace();

    /**
     * Create a Place with name `name' and picture file name "`name'.gif" and
     * add it to this World.
     *
     * @param name A name for the new place and the filename for the gif-image.
     */
    public void createPlace(String name, FullscreenActivity target, int pic) {
        createPlace(name, pic, target);
    }

    /**
     * Create a Place with name `name' and picture file name `picture' and add
     * it to this World.
     *
     * @param name    A name for the new place.
     * @param picture The filename of the image associated with the place.
     */
    public void createPlace(String name, int picture, FullscreenActivity target) {
        places.put(name, new Place(name, owner.loadPicture(picture, target)));
    }

    /**
     * Returns the Place in this world which has the name `name'.
     *
     * @param name Name of the place to be returned.
     * @return The place in name.
     * @throws NoSuchElementException if matching place does not exist.
     */
    public Place getPlace(String name) {
        Place p = (Place) places.get(name);
        if (p == null)
            throw new NoSuchElementException(name);
        return p;
    }

    /**
     * State that the Player `p' is watching this world.
     *
     * @param p The player to add to the list of players watching this world.
     */
    public void addPlayer(Player p) {
        players.add(p);
    }

    /**
     * Update the control window of any Players who are currently watching
     * `place'.
     *
     * @param place to update.
     */
    public void update(Place place, FullscreenActivity target) {
        synchronized (players) {
            Iterator<Player> ls = players.iterator();
            while (ls.hasNext()) {
                Player p = ls.next();
                if (p.currentPlace() == place)
                    p.update();
            }
        }
        place.draw(target, ag);
    }

    /**
     * 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 displayed.
     */
    public void sayAtPlace(Place place, String text, FullscreenActivity target) {
        synchronized (players) {
            Iterator<Player> ls = players.iterator();
            while (ls.hasNext()) {
                Player p = ls.next();
                if (p.currentPlace() == place) {
                    p.say(text, target); //FIXME does this always work???
                }
            }
        }
    }

    /**
     * Play `sound' in the Place `place'. The sound will be played by any
     * Players currently watching `place'. Sound can for example be:
     * "songs/what_a_wonderful_world" -- suitable when your key is accepted
     * "effects/gong" -- suitable when Troll kills
     *
     * @param place Place at which the sound will be played.
     * @param sound Filename of the sound.
     */
    public void playAtPlace(Place place, String sound) {
        synchronized (players) {
            Iterator<Player> ls = players.iterator();
            while (ls.hasNext()) {
                Player p = ls.next();
                if (p.currentPlace() == place) {
                    //owner.playSound(sound);
                }
            }
        }
    }
}

其余的代码,请检查回购。

调试显示的奇怪之处是到达以下代码并将文本打印到游戏中:

if (person.getName().equals("You")) {

    String[] msgs = {
            "The horrible shrieks of the undead chill your bones.",
            "The maddening horrors of this place make your skin crawl.",
            "Death fills the very air of everywhere you turn.",
            "Frightening voices in the air whisper to you, imploring you to join their ranks.",
            "The pungent stength of lurking horrors fills your nostrils.",
            "Morbid visions glimpse before eyes.",
            "Howling screams of a distant Leviathan far below shiver your sanity and prophesize your doom.",
            "Ancient abominations and unspeakable horrors stir in their sleep as you sneak them by."};

    String rand = msgs[(int) (Math.random() * msgs.length)];
    person.getWorld().sayAtPlace(person.place, rand, target);
    // don't write out exit info if there is none
    if (!this.name.equals("Heaven")) {
        person.getWorld().sayAtPlace(person.place,
                "There are doors " + s, target);
    }
}

虽然同一方法中的其他代码不会打印到屏幕上。为什么???

1 个答案:

答案 0 :(得分:1)

在确定事情不起作用的原因时,调试可能是一个非常有用的工具。只需打印到控制台,即可隔离程序/代码停止运行的位置。

使用您的代码,您会发现您并未按预期打印游戏消息。首先要检查的是你是否按预期输入if语句。您提到在调试过程中您将其隔离。因此问题必须在sayAtPlace()方法中。

if (this.getName().equals("Skeleton")) {
    world.sayAtPlace(place,
        "A terrifying skeleton warrior appears!", target);
}

如图所示,sayAtPlace方法期望在提供的地方有一名玩家。如果没有找到玩家,那么就没有输出。在调试时你说没有播放器,因此你会期望没有输出显示。如果没有玩家,您将无法找到与Player集合匹配的内容,这需要调用say方法来显示消息。

    public void sayAtPlace(Place place, String text, FullscreenActivity target) {
        synchronized (players) {
            Iterator<Player> ls = players.iterator();
            while (ls.hasNext()) {
                Player p = ls.next();
                if (p.currentPlace() == place) {
                    p.say(text, target); //FIXME does this always work???
                }
            }
        }
    }
相关问题