ぱぴブログ

さんたろのブログ

ゲーム開発が好きな人のひとりごと

Java奮闘記 メモ

はじめに

環境などは以下の記事をご覧いただきたい。
なおこの記事は良さげな記事やつまづいた点などを列挙している。
papyrustaro.hatenablog.jp

練習用に作っているRPGシステム

コードです。随時更新。
github.com

Scanner利用時のNoSuchElementException

詳しくは以下の記事を参考
qiita.com
ts0818.hatenablog.com

律儀にclose()をしているときに起こった例外

キーボード入力(BufferedReader or Scanner)

キーボード入力をどちらでおこなうか
上記のcloseの問題もあるので、BufferedReaderのみ使っていこうと思う。

実際に使っているコード例

public static int menu(Ally ally) {
    int input_menu = 0;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    System.out.println(ally.name + "はどうする?");
    while(input_menu <= 0 || 4 <= input_menu){
        System.out.println("1.通常攻撃  2.ヒール 3.調べる");
        try {
            input_menu = Integer.parseInt(br.readLine());
        }catch(Exception e) {
            System.out.println("数字を入力してください");
        }
    }
    return input_menu;
}

以下参考記事。
reasonable-code.com

良記事

キーボード入力の他様々な事が書かれている。
お世話になりそうだ。
qiita.com

条件分岐とreturn

Javaに限った話ではないが条件分岐先でreturnしようとするとき、
その分岐が網羅されているかどうか判断はしてくれない。
よって以下のコードは「〇〇を返す必要があります」みたいなエラーが出る(出た)。

public static Enemy selectEnemy() {
        Random random = new Random();
        int random_num = random.nextInt(2) + 1;
        switch(random_num) {
        case 1:
            return (Enemy)(new Slaim());
        case 2:
            return (Enemy)(new Goblin());
        }
}

そのため上のコードでは明示的にdefaultかswitch文外でreturnする必要がある。

public static Enemy selectEnemy() {
    Random random = new Random();
    int random_num = random.nextInt(2) + 1;
    switch(random_num) {
    case 1:
        return (Enemy)(new Slaim());
    case 2:
        return (Enemy)(new Goblin());
    }
        
    return (Enemy)(new Slaim());
}

protected

カプセル化のためフィールドはすべてprivateが望ましい、
みたいな事が言われているが、
サブクラスからスーパークラスのフィールドを使おうとするとかなり面倒。

なのでprotectedにすると、
同パッケージならどこからでもアクセスできてしまう。
protectedは名前からしてガードが堅いイメージを持っていたが、そうでもない。

なぜサブクラスからはアクセスできて同一パッケージからはアクセスできない修飾子はないのだろうか。
パッケージを分けるのが定石なのかもしれない。

文字化け

いつものようにプログラムを実行していたら、あるとき文字化けが発生した。

f:id:papyrustaro:20190310153856p:plain
文字化け

画像を見てわかる通り、すべて文字化けしているわけではない。
しかし、変更していないメソッドの部分の文字列も文字化けしているので、これはなんだ、と。
最初BufferedReaderやStirng型配列を変に使っているせいなのか、とも考えたが、
Eclipse文字コードの設定を片っ端からUTF-8にしたら直った

はっきりとした原因はわからなかったが、化け文字が発生したときはまず文字コードを疑うべきかもしれない。
以下参考記事↓
qiita.com

親クラスのフィールドを子クラスで初期化したい

親クラスでフィールドの宣言をして、子クラスでそれぞれ別々に初期化したいとき。
親クラスで宣言→子クラスのコンストラクタで初期化

こうすることで親クラスからフィールドを参照でき、
かつ子クラス毎に別々の値を持つことができる。

以下のようなコードは目にしたことがあるだろう

class Character{
    String name;
    int hp;
    Character(String name, int hp){
        this.name = name; this.hp = hp;
    }
}

class Ally extends Character{
    int mp;
    Ally(String name, int hp, int mp){
        super(name, hp);
        this.mp = mp;
    }
}

配列の初期化はこうした。
パフォーマンスなどは怪しい。

class Character{
    String name;
    String[] skill_name;
    Character(String name){
        this.name = name;
    }
}

class Ally extends Character{
    Ally(String name){
        super(name);
        this.skill_name = new String[]{"連続切り", "ヒール"};
    }
}