DJGL-画像の描画

画像の描画


 今回は画像の描画です。ゲームでとても重要な部分です。今回から外部のファイルを読み込む手順が存在するので、ファイル名やディレクトリ名の誤字に十分気をつけましょう。いろいろややこしいことが増えるので文章量が長いです。

画像の用意


 画像はこちらで用意しました。上で表示されてる画像を右クリックから保存してください(名前はplayer01.png)。某ゲームに出てくる某々の色違いみたいなやつですが、筆者が描いた絵なので著作権フリーです。改変なり再配布なり自由にどうぞ。
 自分で画像を用意してもいいです。画像を読み込める形式はgif,jpeg,png,bmpなどがあります。透明化も扱えてきれいなpngが一番いいと思います。自分の画像の名前をこちらで用意した画像と同じ(player01.png)にしておいたほうが余計な混乱をせずにすみます。

tips:動画gifを読み込んだ場合画像を表示させるだけでアニメーションします。ただちらつくことがあるのであまりおすすめしません。

画像の名前について


 画像のファイル名(というかプログラムから読み込むテキストとか音声ファイルとかのファイル名)について注意点があります。ファイル名のアルファベットはすべて小文字にしてください。
 理由は、Eclipseで実行した場合には指定したファイル名の大文字小文字が違っていてもファイルを読み込んでくれるのですが、後で解説する実行可能jar(ゲーム配布用の形式)にした場合、大文字小文字が違うと読み込んでくれません。なので、「Eclipseでは実行できるのに実行可能jarでは実行できない(泣)」みたいなことになります。すべて小文字にしておけばこういう事態が回避できます。
 大文字小文字の問題はOS間でも結構もんだいになるので気をつけましょう。ちなみに、ファイル名に日本語(全角文字)を使うのは、多分問題になりませんが……もしかしたらLINUXとかで問題になるかも……?あんまり推奨では無いので普通にアルファベット+数字+半角記号が無難です。

 別の話ですが、画像の名前の付け方はEclipseでは標準でアルファベット順でファイルを並び替えるってことを念頭に置いてつけると良いかもしれません(プレイヤー用の画像なら先頭にpが、敵用ならeが来るみたいな。でもあまり多くなるならディレクトリ作って分けたほうが良いです)。
 今回使う画像についてる01という数字は辞書順に並び替えたときにちゃんと数字どおり並ぶようにするためのものです(こうしないと1,10,11...19,2,20みたいになる)。今回使う画像は1つなので意味はありませんが、追加することも考えて初めからナンバリングつけとくと後が楽です。

画像の設置場所


 画像はプロジェクトのsrcディレクトリ内ならどこでも読み込めます。直下においてもいいですが、画像ファイルなどはresourcesディレクトリなどにまとめて置くのが普通です。今回はresourcesディレクトリを作ってその中に入れましょう。
  1. プロジェクト・エクスプローラーで「src」ディレクトリを右クリック
  2. 「新規」→「その他」をクリック
  3. 「一般」の中の「フォルダー」を選択して「次へ」
  4. 「src」が選択されているはず(されていなければ選択)なので、「フォルダー名」に「resources」と入力して「完了」
これでsrcディレクトリ内にresourcesディレクトリが作られたはずです。(一応今再ですがディレクトリとフォルダーは同じ意味)あとはダウンロードした画像をFinderやファイルエクスプローラーで右クリックで「コピー」して、resourcesディレクトリで右クリから「貼り付け」するだけです。(ちゃんとやりたい人はresourcesディレクトリを右クリックしてインポート選択してやる手順ありますけど、結果は同じことなので手順は述べません。ググれば出てきます。)
コピー&ペーストで画像がresourcesディレクトリに入っているのを確認したら次は画像の読み込みです。
もし、貼り付けをミスって別のディレクトリに入っても右クリックから「削除」で消せます。

 ここまでできていれば画像を表示させることができます。以下のソースを打ち込んでみましょう。
インポート文とフィールドとコンストラクタとdrawメソッドが変更点です。



  1. //------------
  2. //変更点開始
  3. /////////////////
  4. import java.awt.Image;
  5. import densan.s.game.image.ImageLoader;
  6. /////////////////
  7. //変更点終了
  8. //------------
  9. import java.awt.Color;
  10. import densan.s.game.drawing.Drawer;
  11. import densan.s.game.manager.GameManager;
  12. import densan.s.game.manager.Updatable;
  13.  
  14.  
  15. public class TestGame implements Updatable {
  16. //------------
  17. //変更点開始
  18. /////////////////
  19. private Image playerImage;
  20. /////////////////
  21. //変更点終了
  22. //------------
  23. //初期化
  24. public TestGame() {
  25. //------------
  26. //変更点開始
  27. /////////////////
  28. playerImage = ImageLoader.load("resources/player01.png");
  29. /////////////////
  30. //変更点終了
  31. //------------
  32. }
  33. //描画
  34. @Override
  35. public void draw(Drawer d) {
  36. //------------
  37. //変更点開始
  38. /////////////////
  39. //もともとのdrawメソッドの中身は全て消しました。
  40. //画像を描画
  41. d.drawImage(playerImage, 200, 100);
  42. /////////////////
  43. //変更点終了
  44. //------------
  45.  
  46. }
  47. //更新
  48. @Override
  49. public void update() {
  50. // まだ使わない
  51.  
  52. }
  53. //初期化
  54. public static void main(String[] args) {
  55. //ゲームを管理するクラスを取得
  56. GameManager gm = GameManager.getInstance();
  57. //このメソッドでウインドウを表示する
  58. //引数はそれぞれ(幅, 高さ, タイトルバーに表示する文字)
  59. gm.createFrame(800, 600, "テストゲーム");
  60. //更新と描画を担うオブジェクトを設定
  61. gm.setUpdatable(new TestGame());
  62. }
  63.  
  64. }
  65.  
  66.  
  67.  
  68.  
このコードは画像の読み込み部分と表示部分に分かれています。このコードを実行すると以下の画像のようになります。それでは解説していきます。


※Windowsで実行したので今までのスクショとちょっと見た目が違います。左上に画像が出てれば問題ありません。

画像の読み込み


19行目で追加したImage型の変数に28行目で読み込んだ画像を代入しています。
  • 19行目のImageクラスは標準ライブラリの画像を表すクラスです。
    • このImage型変数に読み込んだ画像を入れたり引数で渡したりして画像を受け渡します。
    • 画像の幅と高さを取得することもできます。
      • Image変数.getWidth(null)で幅を取得。
      • Image変数.getHeight(null)で高さを取得。
      • 引数の中身はnullでOK。
    • Imageについて詳しくはhttps://docs.oracle.com/javase/jp/8/docs/api/java/awt/Image.html
  • 28行目ImageLoaderクラスはDJGLの画像読み込みに使うクラスです。
    • 画像読み込みに使うのはloadメソッドです。staticメソッドなのでクラス名.メソッドで使えます。
      • 引数は画像のsrcからのパスの文字列型です。
        • src直下においていればファイル名そのままです。
        • src内のディレクトリならば、「/」で区切ってパスを指定してください。
      • 今回はresourcesディレクトリ内のplayer01.pngなので「resources/player01.png」としています。
      • 階層が深くなるごとに「resources/pic/player/player01.png」みたいになっていきます。
    • ImageLoaderでは読み込んだ画像をキャッシュに保存しているので、別々の場所で同じ画像をロードしても同じインスタンスが帰ってきます。
      • なので読み込みの容量を考えてImageクラスを使いまわしたりする必要はありません。
      • ただし、ImageLoaderで取得したImageを何らかの手段で変更した場合、同じ画像をロードしてる別のImageも同じように変化するので気をつけてください。
        • DJGLの機能だけでいろいろする分には気にしなくていいです。
      • 将来的に可変にしたりするかも。
      • 今読み込んでいるキャッシュを削除したい場合はclearCache()メソッド(static)を呼んで下さい。
    • ImageLoaderについて詳しくはhttp://kiki33.bitbucket.org/densan/s/game/image/ImageLoader.html
  • 画像のロードはコンストラクタ(24~32行目)で行っています。
    • 画像のロードは1回だけでいいので、newされたときに1回だけ呼ばれるコンストラクタで行っています。

画像の描画


 41行目で画像を描画しています。以前あったdrawメソッドの中身はみやすさのためにすべて消してますが、本当はいらなくなったコードでもコメントアウト(//~とか/*~*/とか)したほうがいいです。実は必要とか後で参考になるとかあるので。あまり量が増えるならば毛した方がいいですが、コードはできるだけ消さずにコメントアウトして残しておきましょう。
  • 画像を描画するメソッドはDrawerのdrawImageメソッドです。
    • 引数は(Imageクラス、X座標、Y座標)です。
    • ImageクラスにはImageLoaderで読み込んだ画像をそのまま入れましょう。
    • X座標、Y座標で指定するのは画像の左上の頂点の座標です。(drawRectと同じ)
      • 指定座標を中心に描画したければ画像の幅と高さを取得して半分だけずらす必要があります。
        • そのあたり自動化したメソッド作るかも……。
    • 背景が白なのでわかりにくいですが、画像に透明の部分があった場合そのまま透明に描画されます。半透明も半透明になります。(半透明はちょっと重いかも)
  • 画像を描画するメソッドにはこの他にも描画される範囲を指定するものや画像を反転・回転して描画するものもあります。それは別のページで解説します。
  • Drawerについて詳しくはhttp://kiki33.bitbucket.org/densan/s/game/drawing/Drawer.html

まとめ


 今回は画像の描画について解説しました。画像は一番ゲームの見た目を左右する部分です。ゲームの内容がアレでも画像が良ければそれなりに見えます。プログラマにとってはゲーム作る上での画像の用意が一番難題だったりします。フリー素材なども使っていきましょう。ただし素材の利用規約などはよく確認しましょう。

名前:
コメント:

すべてのコメントを見る