JavaFX 3D Game GT Negative 6 創ってみた。

お正月休みに久しぶりにグランツーリスモやってみたら、もの凄く難しくてストレスたまった。

頭にきたので自分で人生2作目のゲームを創ることにした。

もちろん、JavaFX でね!

ついでに 3D ゲームにしちゃえ!(なんちゃってだけどね。

目標はシンプルで誰でもそれなりに楽しめるゲーム。しかもお手軽に創れる範囲でとしました。

そう、古の白黒ゲームのようにシンプルで優しいゲーム。

出来上がったのはこちら(動画)になります。(ちょっとファイルサイズが大きいです。ごめんね!)

自動車のモデルも作ろうかと思ったのですが面倒なのとお正月休みといえど、いろいろお仕事があるので・・・

メタセコ素材!様のモデルデータ(車とタイヤ)を使わせていただきました。

素敵なモデルデータをありがとうございました。(^_^)

この動画をご覧になって気付かれた方もいらっしゃると思うのですが、

タイヤバリア、と車のナンバープレートがちらついてます。

これ何でこうなるのか解らない! (>_<。)

えっ、ゲーム下手くそだって・・・

それは禁句です。

もの凄く傷つきますのでそってしておいてあげてください。

それとず~~~っと気になってるこのメソッドって何に使うんだろう?

setDepthTest(DepthTest.ENABLE);

これ使うといったい何が幸せになれるんだろう?

まだまだ解らないことだらけだ。

とりあえず今回のゲーム作成においての収穫はフロントタイヤをスピードに合わせて回転させながら、ステアリング操作によって舵角も付けることができたことかな。

ちょっとしたミスでなんでできないのだろうと悩んだことは秘密にしておきます。(ヲヒ

この不完全でシンプルなプログラムで遊んでみたいという人のために Dropbox に置いておきます。

Java 8 build 121 で創りましたので実行環境あるかたはどうぞ!

Dropbox 障害発生からまだ復活してないようなので Google ドライブにおいときます。

https://drive.google.com/folderview?id=0B2xIvGdIzGbAX1lvcTJSTXhPcU0&usp=sharing

MyApp ディレクトリ内にある GT Negative 6 ディレクトリをダウンロード後、

その中にある 3D_Race.jar ファイルをダブルクリックでゲーム開始します。

PC の性能が低いとゆっくりとしたゲームになるかもしれませんがお楽しみいただけると幸いです。

なんでもありのルール無用のゲームです!!!(基本的なルールの実装が面倒くさかったわけではありません。絶対に・・・)

最後にこのシンプルで不完全なゲームを創ってみて、高いお金払ってゲーム買って上手く操作できずにストレスためるより

自分で創った欠陥だらけのゲームのほうが楽しめた。

今年はいい年になるな。きっと!

JavaFX 最高!

Hatena タグ:

Stream API の復習

来年の3月18日に Java 8 がリリースされるとあってこのところ日本語での情報もたくさんネット上に出回ってきました。

以前、「JDK8 Lambda その他いろいろ なんでもいいから動かしてみる」シリーズ、「もっと Lambda」シリーズのエントリーで適当に遊んでました。

少し API の変更などあって動かなくなってしまったサンプルもあります。

そこで Java Advent Calendar 2013 のエントリーで復習にぴったりの記事を見つけたので写経させていただくことにしました。

メッセージに「ラムダについて、○ん○出して考えてみた!」とあってビックリしました。

最初「ラムダについて、うんこ出して考えてみた!」と連想してしまい、なんだ!この人はと驚きました。

少ししてから「ラムダについて、ほんき出して考えてみた!」だよなって別解がでました。

まぁ、わざわざ伏せているところをみると作者の罠にまんまとはまったと思う。

ちなみに、○ん○出して考えてみた!というサイトは下記です。

ラムダ禁止について本気出して考えてみた – 9つのパターンで見るStream API

とてもいいですね。

ただ禁止度があるのですがこれはこのサイトの著者が独断で考慮して決められているようです。

プロフェッショナルプログラマの判断なのでおそらくこれに準ずるような企業が多くなるのでしょうかね。

私個人としては、女性と API は新しい方が良い!と言う人間なので

「8. stream中に元のオブジェクトを操作」 以外は使ってもいいんじゃない?

というよりは使いこなせるようになりたい!

Java Advent Calendar 2013 では時期が時期だけに Java 8 に関するエントリーがちらほらとみられます。

どのエントリーも非常に興味深いものばかりです。

それでは自分用のφ(..)メモメモ

おっと、まんま写経しても面白くないので解りやすく変更を加えてコーディングしました。

プログラムの解説はないので興味のあるかたはご自分でお調べくださいませ。

なお、プログラム中に出てくる人物やデータは実際の人物の正確なデータではありませんのであしからず。(なんのこっちゃ

package jp.yucchi.mystreamexample;

import java.time.LocalDate;
import java.time.Period;

public class MyFriends {

    public enum Sex {

        MALE, FEMALE, OKAMA
    }

    String name;
    LocalDate birthday;
    Sex gender;
    int Breast;
    int waist;
    int hips;

    public MyFriends(String name, LocalDate birthday, Sex gender, int Breast, int waist, int hips) {
        this.name = name;
        this.birthday = birthday;
        this.gender = gender;
        this.Breast = Breast;
        this.waist = waist;
        this.hips = hips;
    }

    public int getAge() {
        return Period.between(birthday, LocalDate.now()).getYears();
    }

    public String getName() {
        return name;
    }

    public LocalDate getBirthday() {
        return birthday;
    }

    public Sex getGender() {
        return gender;
    }

    public int getBreast() {
        return Breast;
    }

    public int getWaist() {
        return waist;
    }

    public int getHips() {
        return hips;
    }

    void printMyFriends() {
        System.out.println(name + ", " + this.getAge() + "歳" + ", Gender: "
                + this.getGender() + ", Breast Size: " + this.getBreast()
                + ", Waist Size: " + this.getWaist() + ", Hips Size: " + getHips());
    }
}

package jp.yucchi.mystreamexample;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import jp.yucchi.mystreamexample.MyFriends.Sex;

public class MyStreamExample {

    public static void main(String[] args) {
        List friend = new ArrayList<>();

        friend.add(new MyFriends("柴田 恭平", LocalDate.of(1951, 8, 18), MyFriends.Sex.MALE, 90, 75, 80));
        friend.add(new MyFriends("小栗 旬", LocalDate.of(1982, 12, 26), MyFriends.Sex.MALE, 85, 68, 77));
        friend.add(new MyFriends("市原 隼人", LocalDate.of(1987, 2, 6), MyFriends.Sex.MALE, 88, 65, 76));
        friend.add(new MyFriends("壇 蜜", LocalDate.of(1980, 12, 3), MyFriends.Sex.FEMALE, 85, 60, 89));
        friend.add(new MyFriends("北川 景子", LocalDate.of(1986, 8, 22), MyFriends.Sex.FEMALE, 75, 54, 81));
        friend.add(new MyFriends("綾瀬 はるか", LocalDate.of(1985, 3, 24), MyFriends.Sex.FEMALE, 88, 61, 91));
        friend.add(new MyFriends("佐々木 希", LocalDate.of(1988, 2, 8), MyFriends.Sex.FEMALE, 80, 58, 82));
        friend.add(new MyFriends("剛力 彩芽", LocalDate.of(1992, 8, 27), MyFriends.Sex.FEMALE, 77, 58, 84));
        friend.add(new MyFriends("堀北 真希", LocalDate.of(1988, 10, 6), MyFriends.Sex.FEMALE, 78, 58, 83));
        friend.add(new MyFriends("武井 咲", LocalDate.of(1993, 12, 25), MyFriends.Sex.FEMALE, 76, 58, 82));
        friend.add(new MyFriends("深田 恭子", LocalDate.of(1982, 11, 2), MyFriends.Sex.FEMALE, 86, 62, 88));
        friend.add(new MyFriends("はるな 愛", LocalDate.of(1976, 7, 21), MyFriends.Sex.OKAMA, 90, 60, 89));
        friend.add(new MyFriends("マツコ・デラックス", LocalDate.of(1972, 10, 26), MyFriends.Sex.OKAMA, 150, 150, 150));

        // MyFriends 全員表示
        System.out.println("<-- MyFriends 全員表示 -->");
        friend.stream().forEach((e) -> {
            e.printMyFriends();
        });

        // 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる。
        System.out.println("\n<-- 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる -->");
        Map resultBreastSize = resultBreastSize = groupBySexAndBreast(friend);
        System.out.println(resultBreastSize);

        // 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる。(別パターン)
        System.out.println("\n<-- 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる。(別パターン) -->");
        Map resultBreastSize2 = resultBreastSize2 = groupBySexAndBreast2(friend);
        System.out.println(resultBreastSize2);

        // 性別が女性のバストの個数(個々では友達の人数)、合計、最小値、平均値、最大値を取得。
        System.out.println("\n<-- 性別が女性のバストの個数(ここでは友達の人数)、合計、最小値、平均値、最大値を取得。 -->");
        IntSummaryStatistics breastStatistics = breastAverageAndSum(friend);
        System.out.println("count: " + breastStatistics.getCount() + "\n"
                + "sum: " + breastStatistics.getSum() + "\n"
                + "min: " + breastStatistics.getMin() + "\n"
                + "avarage: " + breastStatistics.getAverage() + "\n"
                + "max: " + breastStatistics.getMax());

        // 女性だけをフィルタリングしてバストのサイズによって降順ソート。
        System.out.println("\n<-- 女性だけをフィルタリングしてバストのサイズによって降順ソート。 -->");
        List f = breastSort(friend);
        f.forEach(e -> {
            System.out.println(e.getName() + ": Breast: " + e.getBreast());
        });

        // 女性でバストが 80 より大きい友達だけをフィルタリングしてバストの値に 1000 を足して合計する。
        // reduce を使う! sum() のほうが便利だけどね。
        System.out.println("\n<-- 女性でバストが 80 より大きい友達だけをフィルタリングしてバストの値に 1000 を足して合計する。 -->");
        int breastSum = addBigBreast(friend);
        System.out.println(breastSum);

        // 性別によってグルーピングして年齢の若い順に表示させる。
        System.out.println("\n<-- 性別によってグルーピングして年齢の若い順に表示させる。 -->");
        Map> resultGender = groupByGender(friend);
        for (Map.Entry> keyValue : resultGender.entrySet()) {
            System.out.println(keyValue.getKey().toString());
            for (int i = 0; i < keyValue.getValue().size(); i++) {
                System.out.println(keyValue.getValue().get(i).getName() + " : " + keyValue.getValue().get(i).getAge());
            }
        }

        // 女性のバストの大きさでグルーピングして年齢の若い順に表示させる。
        System.out.println("\n<-- 女性のバストの大きさでグルーピングして年齢の若い順に表示させる。 -->");
        Map> resultBreastRank = groupByBreastRank(friend);
        for (Map.Entry> keyValue : resultBreastRank.entrySet()) {
            System.out.println(keyValue.getKey().toString());
            for (int i = 0; i < keyValue.getValue().size(); i++) {
                System.out.println(keyValue.getValue().get(i).getName() + " : " + keyValue.getValue().get(i).getAge() + " Breast: " + keyValue.getValue().get(i).getBreast());
            }
        }

        // 性別による平均年齢を計算。
        System.out.println("\n<-- 性別による平均年齢を計算。 -->");
        Map averageAge = groupingBySexAndAve(friend);
        for (Map.Entry keyValue : averageAge.entrySet()) {
            System.out.println(keyValue.getKey().toString() + " : " + keyValue.getValue().toString());
        }

        // 性別によるグルーピングをして人数の少ない順にソートする。
        System.out.println("\n<-- 性別によるグルーピングをして人数の少ない順にソートする。 -->");
        List sortSex = sortSexCount(friend);
        sortSex.forEach(System.out::println);

        // 性別によるグルーピングをして人数の少ない順にソートする。人数も表示させる。
        System.out.println("\n<-- 性別によるグルーピングをして人数の少ない順にソートする。人数も表示させる。 -->");
        List> sortSex2 = sortSexCount2(friend);
        sortSex2.forEach(f2 -> {
            System.out.println(f2.getKey() + " : " + f2.getValue());
        });

    }

    private static Map groupBySexAndBreast(List friend) {
        return friend.stream().collect(Collectors.groupingBy(MyFriends::getGender,
                Collectors.collectingAndThen(Collectors.toList(), f -> f.stream()
                        .filter(fs -> fs.getBreast() > 85)
                        .count())));
    }

    private static Map groupBySexAndBreast2(List friend) {
        return friend.stream()
                .collect(Collectors.groupingBy(MyFriends::getGender))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(entry -> entry.getKey(),
                                entry -> entry.getValue()
                                .stream()
                                .filter(f -> f.getBreast() > 85)
                                .count()));

    }

    private static IntSummaryStatistics breastAverageAndSum(List friend) {
        return friend.stream()
                .filter(f -> f.getGender() == Sex.FEMALE)
                .mapToInt(MyFriends::getBreast)
                .summaryStatistics();

    }

    private static List breastSort(List friend) {
        return friend.stream()
                .filter(f -> f.getGender() == Sex.FEMALE)
                .sorted((f1, f2) -> f2.getBreast() - f1.getBreast())
                .collect(Collectors.toList());
    }

    private static int addBigBreast(List friend) {
        return friend.stream()
                .filter(f -> f.getGender() == Sex.FEMALE && f.getBreast() > 80)
                .mapToInt(f -> f.getBreast() + 1000)
                .reduce(0, (x, y) -> x + y);
    }

    private static Map> groupByGender(List friend) {
        return friend.stream()
                .sorted((f1, f2) -> f1.getAge() - f2.getAge())
                .collect(Collectors.groupingBy(f -> f.getGender()));
    }

    private static Map> groupByBreastRank(List friend) {
        return friend.stream()
                .filter(f -> f.getGender() == Sex.FEMALE)
                .sorted((f1, f2) -> f1.getAge() - f2.getAge())
                .collect(Collectors.groupingBy(f -> {
                    if (f.getBreast() > 85) {
                        return "< 巨乳>";
                    }
                    if (f.getBreast() > 75) {
                        return "< 乳 >";
                    }
                    if (f.getBreast() > 65) {
                        return "< 貧乳 >";
                    }
                    return "・・・";
                }));
    }

    private static Map groupingBySexAndAve(List friend) {
        return friend.stream()
                .collect(Collectors.groupingBy(MyFriends::getGender, Collectors.averagingInt(MyFriends::getAge)));
    }

    private static List sortSexCount(List friend) {
        return friend.stream()
                .collect(Collectors.groupingBy(MyFriends::getGender, Collectors.counting()))
                .entrySet()
                .stream()
                .sorted(Comparator.comparingLong(Entry::getValue))
                .map(Entry::getKey)
                .collect(Collectors.toList());
    }

    private static List> sortSexCount2(List friend) {
        return friend.stream()
                .collect(Collectors.groupingBy(MyFriends::getGender, Collectors.counting()))
                .entrySet()
                .stream()
                .sorted(Comparator.comparingLong(Entry::getValue))
                .collect(Collectors.toList());
    }

}

実行結果は次のようになります。

<– MyFriends 全員表示 –>
柴田 恭平, 62歳, Gender: MALE, Breast Size: 90, Waist Size: 75, Hips Size: 80
小栗 旬, 30歳, Gender: MALE, Breast Size: 85, Waist Size: 68, Hips Size: 77
市原 隼人, 26歳, Gender: MALE, Breast Size: 88, Waist Size: 65, Hips Size: 76
壇 蜜, 33歳, Gender: FEMALE, Breast Size: 85, Waist Size: 60, Hips Size: 89
北川 景子, 27歳, Gender: FEMALE, Breast Size: 75, Waist Size: 54, Hips Size: 81
綾瀬 はるか, 28歳, Gender: FEMALE, Breast Size: 88, Waist Size: 61, Hips Size: 91
佐々木 希, 25歳, Gender: FEMALE, Breast Size: 80, Waist Size: 58, Hips Size: 82
剛力 彩芽, 21歳, Gender: FEMALE, Breast Size: 77, Waist Size: 58, Hips Size: 84
堀北 真希, 25歳, Gender: FEMALE, Breast Size: 78, Waist Size: 58, Hips Size: 83
武井 咲, 19歳, Gender: FEMALE, Breast Size: 76, Waist Size: 58, Hips Size: 82
深田 恭子, 31歳, Gender: FEMALE, Breast Size: 86, Waist Size: 62, Hips Size: 88
はるな 愛, 37歳, Gender: OKAMA, Breast Size: 90, Waist Size: 60, Hips Size: 89
マツコ・デラックス, 41歳, Gender: OKAMA, Breast Size: 150, Waist Size: 150, Hips Size: 150

<– 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる –>
{FEMALE=2, MALE=2, OKAMA=2}

<– 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる。(別パターン) –>
{MALE=2, FEMALE=2, OKAMA=2}

<– 性別が女性のバストの個数(ここでは友達の人数)、合計、最小値、平均値、最大値を取得。 –>
count: 8
sum: 645
min: 75
avarage: 80.625
max: 88

<– 女性だけをフィルタリングしてバストのサイズによって降順ソート。 –>
綾瀬 はるか: Breast: 88
深田 恭子: Breast: 86
壇 蜜: Breast: 85
佐々木 希: Breast: 80
堀北 真希: Breast: 78
剛力 彩芽: Breast: 77
武井 咲: Breast: 76
北川 景子: Breast: 75

<– 女性でバストが 80 より大きい友達だけをフィルタリングしてバストの値に 1000 を足して合計する。 –>
3259

<– 性別によってグルーピングして年齢の若い順に表示させる。 –>
MALE
市原 隼人 : 26
小栗 旬 : 30
柴田 恭平 : 62
FEMALE
武井 咲 : 19
剛力 彩芽 : 21
佐々木 希 : 25
堀北 真希 : 25
北川 景子 : 27
綾瀬 はるか : 28
深田 恭子 : 31
壇 蜜 : 33
OKAMA
はるな 愛 : 37
マツコ・デラックス : 41

<– 女性のバストの大きさでグルーピングして年齢の若い順に表示させる。 –>
< 貧乳 >
北川 景子 : 27 Breast: 75
< 巨乳>
綾瀬 はるか : 28 Breast: 88
深田 恭子 : 31 Breast: 86
< 乳 >
武井 咲 : 19 Breast: 76
剛力 彩芽 : 21 Breast: 77
佐々木 希 : 25 Breast: 80
堀北 真希 : 25 Breast: 78
壇 蜜 : 33 Breast: 85

<– 性別による平均年齢を計算。 –>
FEMALE : 26.125
MALE : 39.333333333333336
OKAMA : 39.0

<– 性別によるグルーピングをして人数の少ない順にソートする。 –>
OKAMA
MALE
FEMALE

<– 性別によるグルーピングをして人数の少ない順にソートする。人数も表示させる。 –>
OKAMA : 2
MALE : 3
FEMALE : 8

Hatena タグ: