ゲームプログラミング前回の記事の続きです。Javaを使った2Dゲームの、スクロールに挑戦しました。はじめにスクロールを表現するにあたって、題材は「迷路ゲーム」にしました。※フレームと色を少なくしているので粗いです。迷路なのかというと、まず、ごく小規模で完結したゲームを作ろうと思ったからです。昔の2Dゲームの方式で作ろうとしていて、スクロールを取り入れたものにしたかったんですね。3Dゲームは、作る根気が無いのでいまのところは作る予定はありません。迷路の外見は、RPGのダンジョンを意識しています。対象読者?私はゲーム制作の素人ですので、もし本気でゲーム制作をしたい方は、まずは他のゲーム制作専門サイトさまを当たっていただいた方が無難です。それと、このサンプルはゲームの原理を理解するためのものなので、本格的なゲームを作るとなると、DirectXやゲーム専用ライブラリーなどを使うのは避けて通れないでしょう。DirectXや専用ライブラリーは少しハードルが高い1ので、入門にはJavaの標準機能を使ってみるのも良いんじゃないかと思います。いうことで、ゲーム作ってみたいけどあれもこれも難しくて捗らない...Javaならなんとか行けそう、という人向けです。2.0.6Java8の新機能を使っているので、Java8必須です。GUIはAWT+Swingで、JavaFXは使っていません。制作作業はWindows上で行っています。v10.12.4)でも行いました。Linux(Ubuntu14)でも確認してみたのですが、エラーになってしまいました。下記のissueが関係しているようですが、詳細は不明です。JIRAJInputについての説明と、キーボードとゲームパッドからの入力方法については、以前の記事「Javaでゲームパッドの入力をJInputを使って実現する」を参照してください。JInputのネイティブライブラリーをパスに通すところを忘れると動かないので注意して下さい。JInput以外の部分も一部流用していますので、そちらを先に読んでいただいたほうが理解しやすいと思います。ControllerInput,NullController,GamepadControllerInput,KeyboardControllerInputクラスorインターフェイスのコードは、上記の記事のものをそのまま使うので説明は省略します。ソースコードは、Gistに含まれています。Gistへのリンクは最後に載せてあります。昔のゲームは、少ないリソースで作らないといけないこともあって、同じサイズの小さな画像をいくつか用意して、それを組み合わせて画面を作る方式が一般的でした。Wikipediaタイルを組み合わせて絵を作っているから、Tile-basedなんですね。比較的、作る手間がかからないからか、同人作品などではいまでもこの方式を採用することが多いみたいです。「ツクール」なんかはこれですね。今回は、この方式を採用しています。設計を簡単に説明この迷路ゲームの設計と、実装方針について簡単に触れます。ゲームのルール迷路には、壁などの障害物があり、それを進んで行って、上り階段にたどり着けばゴールです。要はただの迷路ですね。今回は、1フロアだけを実現しています。応用すれば、ダンジョンを上っていくようなものも作れるでしょう。メインループ前回は、入力に対してイベントドリブン方式で処理をさせていましたが、今回は、メインループ内で処理させるようにしました。こちらの方がよく知られた方式だと思います。入力をチェックし、入力があれば2へ進む。なければ一定時間待機して再度1を行う。入力された方向の地形が通過可能であれば、3へ進む。ウェイトをかけながら少しずつスクロールし、1マス分移動する。現在位置を移動先に変更する。移動先がゴールなら、ゴール処理をして終了。マップチップマップを作るのに用意する画像は、ひとつひとつ別ファイルにすると作業効率が悪いので、1つの画像として用意します。これを、マップチップ(方式?)と呼びます。英語では、tilesetというそうです。マッピングと地図のマップが紛らわしいので、ここではマップチップを「タイルセット」、マップを「地図」と呼びます。著作権などのややこしいことは避けたいので、今回は雑ではありますが、自作しました。拡大版(分かりやすくするために番号をつけています)なお、今回はキャラクターもここに含めていて、いちばん右下(E)をプレイヤーキャラクター(棒人間)としています。この画像と、地図データを組み合わせて、迷路の画像を作ります。地図データのフォーマット地図データは、テキストファイルで作成します。今回は、単純にするために、ASCII文字1字で1マスを表現することにします。地形を表すコードなので、地形コードと呼ぶことにします。画像を16種類用意しているので、地形コードはピリオドと0~9、A~E(.0123456789ABCDE)を使用します。ピリオドを入れているのは、テキストファイルでの視認性のためです。地図データはスプレッドシートで作成すると楽2なので、その場合はスペースだと視認しにくいので避けました。下記のデータは、冒頭に貼ってある画像のものとは異なっています。map.txt)AAAAAAAAAAAAAAAAAAAAAAAAAAA8C......................AA.C.CCCCCCCBBBBBC.CCCCCC.AA.C.C...C.......C.C....C.AA.C.CCCCC.CCCCCCC.C....C.AA.C.5656C.C.....C.C....C.AA.C.6565C.C.....C.C....C.AA.C.5656C.C.....C.C....C.AA9C.6565C.C.CCCCC.C....C.AACC.....C.C.D.....C....C.AA.C.....C3C.D.CCC.CCCCCC.AA.C.....C3C.D...C.7....C.AA.C.....C3C.D..CC.C....C.AA.C.....C.C.C..C..C...9C.AA.C.....C.C....C.CCBBBCC.AA.C.....C.CBBBCCCCC....C.AA.C.CBBBC.......8..9...C.AA.C.......CAAAAAAAAAAAAC.AA.C.CBBBC.CA0123456789AC.AA.C.CBBBC.CA..ABCDE...AC.AA.C.....C.CAAAAAAAAAAAAC.AA.CCCCCCC.C.CCCC.CBBCCCC.AA..............C.........AAAAAAAAAAAAAAAAAAAAAAAAAAAこのファイルを読み込んで、char型の2次元配列に格納します。地図情報ファイルを読み込む際は、スプレッドシートから直接コピペしても良いように、タブ文字は除外します。地形コードは、通れるかどうかを判定するのにも使用します。今回はパターンが少ないので、第6ビットが1のA~Eを通れない地形、それ以外の第6ビットが0のものを通れる地形にします。ビット操作については以下の記事などを参考にして下さい。実装ここに書かれているもの以外は、Gistの完成形をご参照ください。地図データ読み込み地図情報(map.txt)を読み取ってchar[][]に変換します。chars;}タイルセットを使って地図画像を生成プログラム上では、マップチップから指定した番号の画像を取り出せるようにすると便利です。今回は、地形コード(char値)を渡すと、対応する地形をBufferedImageで返すクラスTilesetを定義します。importしている)です。タイルサイズは32x32なので、TSIZEは32です。}}このTilesetクラスと地図情報を使って、地図画像を生成します。地図画像のサイズは、余白を空けるために大きめにしています。bi;}これで1フロア分の地図画像が完成しました。あとは、BufferedImage#getSubimageメソッドを使って、区画を切り取って画面に表示します。前回からの改良点として、以下があります。完成形GistにJavaソースコード(App.java,ControllerInput.java)をアップしてあります。GistGradleプロジェクト、もしくはMavenプロジェクトに、下記のようにファイルを配置します。tileset.png後は、ビルドして、game.App.main()を実行するだけです。ビルドが面倒という方のために、Dropboxにビルド済みファイル一式を用意しました。※ご利用の際は自己責任でお願いいたします。(Dropbox)今回はほとんど頭の中にある情報だけで構築できました。次はもうちょっとゲームらしいものを作ってみたいと思っています。(おわり)ほとんど使ったことないので想像です。↩さらに本格的なゲームにするには、専用のマップエディターを作ることを検討したほうが良いでしょう。スクロールの表現Tweet広告を非表示にする関連記事2016-02-26Javaでゲームパッドの入力をJInputを使って実現する突然、ゲームを作ってみたくなりました。#java8Java8未満を切り捨てて色々と作ってみるシリーズ。(2)プロフィールid:argiusはてなブログをはじめよう!argiusさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。