2017-12-22 7 views
-3

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

同じ方法で他のコードが画面に印刷されませんが。なぜ???

+2

ここではあまりにも多くのコードがあるので、私はこの質問をd​​ownvotedしました。あなたの問題がどこにあるのかを明確にするためには、問題を直接引き起こしていないコードを削除してください。もしそれを10行以下に減らすことができれば、私はdownvoteを引っ込めることを検討します。参照:[最小限で完全で検証可能な例の作成方法](http://stackoverflow.com/help/mcve)と[小規模プログラムのデバッグ方法](https://ericlippert.com/2014/03/05)/how-to-debug-small-programs /) –

+1

デバッガを試してみてください –

+1

デバッグを試しましたか? sayAtPlace()が呼び出されていないか、メソッドが正しく機能していないために表示されないかどうか。期待どおりにコードが実行を停止する場所を切り分けてください。正常に動作していないものについては良い考えがあります。 – Zachary

答えて

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??? 
       } 
      } 
     } 
    } 
+1

助けてくれてありがとう。私はバグを修正することができました。場所を再描画するPlaceクラスの場所の人物を更新することが問題でした。それは今働くようですが、私はまだそれをもっとテストするべきです。 –

関連する問題