ブログトップ 記事一覧 ログイン 無料ブログ開設

人工知能に関する断創録 このページをアンテナに追加 RSSフィード

2004-09-18

Duke

Javaでゲーム作りますが何か?

| 20:42 |  Javaでゲーム作りますが何か?を含むブックマーク  Javaでゲーム作りますが何か?のブックマークコメント

Javaを使ったゲームプログラミングについて書いてます。プログラムはJAR形式で公開しているのでダブルクリックで実行してください。ソースファイルはJARファイルの中に入っているので解凍してご覧下さい。基本的に全部ソースファイル入ってます。著作権を主張することはないので自由に使ってください。

リンク切れやリンク先がおかしいなどありましたらコメントもらえると助かります。もうかなり長い間Javaは使っていないため内容に関する質問に私からはお答えできないと思います。もっと人が多いサイトで聞いた方がよいかもしれません。

(注1)ファイルをダウンロードするときは、ファイル名の後のf:id:aidiary:20090901213430g:imageマークをクリックしてください。はてなの仕様のようでファイル名をクリックしてダウンロードしようとするとファイル名が変になります。

(注2)ブログはその他雑多な記事も多いため記事は連続しておらず記事上方にあるナビゲーションはほとんど役に立ちません。このページを起点としてリンク先へ、読んだら戻るといった使い方が楽だと思います。

(注3)リンク先がない項目は面倒くさくなって解説を書いておらず、ソースファイルの提供のみとなっています。ご了承ください。

基礎

部品

  • ファイアボール - クリックとドラッグでマウスの位置にファイアボールを発射(2006/1/29)
  • テレポート - Tキーでマウスの位置にテレポート(2006/2/4)teleport.jar 直
  • ブレゼンハムアルゴリズム - 直線を描画する方法、直線経路探索でも使う(2005/4/2)
  • メタボール - 何か気持ちいいメタボールJavaでピクセル操作は少し重いかな(2006/4/30)metaball.jar 直
  • 大砲発射 - マウスクリックで弾を発射します。弾は放物線を描いて飛んできます。CTRLを押しながらだと正確にマウスポインタの位置を撃ち抜きます(2006/6/3)cannon.jar 直
  • 矢 - マウスクリックで矢を発射。CTRLを押しながらだとマウスポインタを正確に射抜きます。矢の長さが一定になるように少し工夫してます(2006/6/11)arrow.jar 直
  • スポットライト効果 - ドラクエ1の洞窟とか(2006/12/29)
  • 円運動 - くるくる回転(2007/2/4)
  • サンダー - マウスボタンの長押しでパワーをためて話すと稲妻が落ちます。もっとかっこいい稲妻にしたいですね(2006/2/4)thunder.jar 直
  • 稲妻 - リアルサンダー(2006/8/18)
  • 爆発エフェクト - TimerTaskを使った爆発エフェクト。クリックとドラッグで爆発(2006/1/29)explosion.jar 直
  • くだけちるエフェクト - スライムはくだけちった。アニメーションの速度を遅くすると楽しいかも(2005/12/3)megante.jar 直
  • フェードアウト効果 - だんだん見えなくなる画面効果(2007/5/4)

ブロック崩し

インベーダー

テトリス

マリオ風アクション

RPG

マップエディタ

  • ひながた - ドラッグでチップを塗りつぶす(2005/12/17)map_editor01.jar 直
  • パレットの追加 - マップチップパレットの追加(2005/12/17)map_editor02.jar 直
  • マップチップの選択と描画 - パレットからマップチップを選択して描画(2005/12/17)map_editor03.jar 直
  • マップの新規作成 - 新規作成メニューを追加。スクロールバーも装備(2005/12/23)map_editor04.jar 直
  • マップを保存 - マップを1マス1バイトのバイナリ形式で保存(2005/12/25)map_editor05.jar 直
  • マップを開く - 保存したマップを開く(2005/12/25)map_editor06.jar 直

オセロ

ミニゲーム

  • Nibble - 制限時間内に蛙を食べまくれ(2004/12/15)nibble.jar 直

人工知能

  • ライフゲーム - 人生ゲームじゃないです(2004/12/25)
  • 単純な追跡アルゴリズム - 単純に近づくだけ(2005/3/27)
  • LOS追跡 - ブレゼンハムアルゴリズムをもとに最短経路で追跡(2005/4/9)
  • パターン移動 - 移動経路を設定する(2005/4/10)pattern_movement.jar 直
  • ブレッドクラム経路探索 - パンくずをたどって追跡する(2005/4/16)bread_crumb.jar 直
  • ウォールトレーシング - 左手法を使ってダンジョンを巡回する(2005/4/16)wall_tracing.jar 直
  • A* (A-star) 経路探索 - 障害物があっても大丈夫(2005/4/23)a_star.jar 直
  • A* (A-star) 経路探索(地形コストつき) - バリアはコストが高いので迂回する(2005/4/23)a_star2.jar 直
  • A* (A-star) 経路探索(迷路) - 最短経路で迷路をぬける(2005/4/23)a_star3.jar 直
  • 有限状態機械(蟻の例) - 蟻は内部状態に応じて行動を変化させる(2005/4/24)ant_fsm.jar 直
  • ニューラルネットによるパターン認識 - 3層パーセプトロン・誤差逆伝播法を使ったパターン認識(2005/5/5)
  • ニューラルネットによる逃避行動の学習 - ニューラルネットを使って逃げ方を覚える(2005/5/14)
  • 強化学習で迷路の最短経路を見つける - 強化学習で迷路は基本タスク(2005/1/21)
  • 強化学習で倒立振子を制御する - 掃除の時間にやるやつ(2005/1/21)pole_balancing.jar 直
  • 強化学習でアクロバットを制御する - 足を振り上げる鉄棒選手(2005/2/17)acrobat.jar 直
  • 強化学習で車の山登りタスクを解く - 山を登る方法を学習する(2005/5/1)mountain_car.jar 直
  • 倒立振子制御の教示学習 - 強化学習に教示を導入。教示モードでは左右キーで台車を操作できます。エージェントにお手本を見せましょう。Modeボタンを押してエージェントの自律モードに切り替えると前よりずっとうまくできるようになってます。赤ちゃんエージェントにお手本を見せよう。(2005/9/11)pole_balance_teaching.jar 直
  • 強化学習でPongを学習する - 学習を通じてPongがうまくできるようになる(2005/12/10)pong_learning.jar 直

人工無脳

ネットワーク

Java Sound

Java3D

(注)Java3Dがインストールされている必要があります。起動が遅い場合があります。

  • Java3Dの雛形 - Java3Dアプリケーションの基本形(2006/7/28)sample3d.jar 直
  • 座標軸 - X軸、Y軸、Z軸の描画(2006/7/28)axis.jar 直
  • 床 - XZ平面に広がる床(2006/7/28)floor.jar 直
  • 回転キューブ - 回転するカラーキューブ(2005/12/30)rotating_cube.jar 直
  • 点を打つ - 点を描画(2006/1/1)point.jar 直
  • 神々のトライフォース - 某ゲームのあれ(2006/1/1)triforce.jar 直
  • 水晶球 - 赤い絨毯と水晶球(2006/1/4)crystal_ball.jar 直
  • Sphere in the Box - 箱の中で跳ね回るボール(2006/1/28)sphere_in_the_box.jar 直
  • ボールの自由落下 - 自由落下してバウンドするボール(2006/2/4)falling_ball.jar 直

関連書籍

  • Developing Games in Java - Java Gamesでも推薦されているBrackeenさんの本です。Javaでゲームを作るための必須技術が解説されています。マリオ風アクションゲームの作成は必見です。Javaゲームの基礎的な内容だけではなく、マルチプレーヤー、Java3D、衝突検出、最短経路探索、人工知能など応用技術も幅広く解説されています。海外の本は充実度がものすごいです。ソースコードとフレームワークはhttp://www.brackeen.com/javagamebook/で公開されてます。
  • Javaゲームプログラミング アルゴリズムとフレームワーク - 表紙はあれですが内容は濃いです。入門編と実践編に分かれています。入門編はJavaでゲームを作るためのフレームワークが解説されています。実践編は落ちモノパズル、シューティング、戦略シミュレーション、ネット対戦ゲームが解説されています。実践編、特に戦略シミュレーションの作り方が面白かったです。
  • やさしくわかるJava3D - Java3D本の中では一番いいかも。ただこの本以外である程度Java3Dの基礎を勉強してないとつらいような気がします。3Dジャンプアクションの作り方が面白いです。

リンク集

  • Javaで RPGを作ろう! - JavaでRPGを作る方法が解説されています。スクロール処理の実装方法が参考になりました。
  • 安永ノリカズの公開ゲーム制作 - 魔法使いの街を舞台にした生活シミュレーションゲームをアプレット形式で公開しています。人工生命手法を用いた社会構造テストプログラムがとても興味深いです。またJavaの入門者を対象に愛のJava256本ノックという面白い試みもしています。
  • Javaゲームはじめました。 - Javaでさまざまなゲームを作られてます。シミュレーションゲームの作り方講座が楽しい。今度作るとき参考にさせてほしいと思います。向こうからもリンク貼っていただいたようです。ありがとうございます。

アプリケーションの構成

| 21:02 |  アプリケーションの構成を含むブックマーク  アプリケーションの構成のブックマークコメント

ここではHello Worldを表示する最も簡単なJavaアプリケーションを書いてみます。私の書くJavaアプリケーションはフレームとメインパネルの二部構成を取っています。今後書くアプリケーションはすべて同じ枠組みですのでここで詳しく解説します。

hello_world.jar 直

フレームとパネル

私の書くゲームアプリケーションはフレーム(JFrameを拡張したクラス)とパネル(JPanelを拡張したクラス)から成り立っています。フレームはアプリケーション本体です。アプリケーションの開始点であるmain()を持ちます。パネルはゲームのメイン画面です。オセロゲームだったら盤面、RPGだったらフィールドを描画する場所となります。

HelloWorld.javaです。

import java.awt.*;
import javax.swing.*;

public class HelloWorld extends JFrame {
    public HelloWorld() {
        // タイトルを設定
        setTitle("Hello Worldを表示する");

        // メインパネルを作成してフレームに追加
        MainPanel panel = new MainPanel();
        Container contentPane = getContentPane();
        contentPane.add(panel);

        // パネルサイズに合わせてフレームサイズを自動設定
        pack();
    }

    public static void main(String[] args) {
        HelloWorld frame = new HelloWorld();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

MainPanel.javaです。

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;

public class MainPanel extends JPanel {
    // パネルサイズ
    private static final int WIDTH = 240;
    private static final int HEIGHT = 240;

    public MainPanel() {
        // パネルの推奨サイズを設定、pack()するときに必要
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        // 変数などの初期化
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        // 盤面を描いたり、フィールドを描いたりする
    }
}

フレームクラス(HelloWorld)自体はたいしたことをしていません。タイトルを設定し、フレームのcontentPaneというところにパネル(MainPanelオブジェクト)をadd()で貼り付けているだけです。画面への描画などの処理はパネルがすべて担当しており、フレームはパネルを乗せる単なる土台にすぎません(下図参照)。

f:id:aidiary:20090827214622g:image

メインメソッド

アプリケーションはmain()から開始されます

    public static void main(String[] args) {
        HelloWorld frame = new HelloWorld();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

main()の1行目ではHelloWorldフレームのオブジェクトを作っています。HelloWorldクラス内のmain()で HelloWorldオブジェクトを作るのは変だと思われるかもしれませんが、main()がstaticメソッドであるため正しい書き方です。この書き方は分かりにくいという指摘もありますが、簡潔なため採用しました。

2行目はフレームの終了処理を指定しています。これを書かないとプログラムが終了できなくなります。こう書くもんだと思ってください。3行目は画面にフレームを表示します。フレームはsetVisible(true)しないと画面に表示されません。

描画処理

描画処理はパネル(MainPanel)のpaintComponent()に書きます。paintComponent()はGraphicsオブジェクトgを引数として受け取ります。このgを通して文字、図形、イメージを描画することができます。今回はdrawString()を使って画面上にHello Worldを描画しています。

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // (20,50)の位置にHello Worldを描画する
        g.drawString(str, 20, 50);
    }

図形を描く

| 21:41 |  図形を描くを含むブックマーク  図形を描くのブックマークコメント

paintComponent()の引数であるGraphicsオブジェクトgを使うと直線、図形、文字、イメージをパネルに描けます。今回は、gを使ってさまざまな図形を描いてみます。

draw_figure.jar 直

座標系

Javaの座標系は数学で使う座標系と異なり、左上が(0,0)になります。x座標は右に行くほど大きくなり、y座標は下に行くほど大きくなります(下図参照)。また、座標はピクセル単位であるため整数値しか取れません。数学が得意な人は慣れるまで大変かも・・・。

f:id:aidiary:20090827214807g:image

色の指定

色は赤(R)、緑(G)、青(B)の3つの成分の組み合わせで表されます。それぞれの成分は8ビット(0〜255の整数値)です。たとえば、赤は (255,0,0)、緑は(0,255,0)、青は(0,0,255)、白は(255,255,255)、黒は(0,0,0)、黄色は赤と緑を混ぜ合わせればよいので(255,255,0)です。

ここで、なぜ白が(255,255,255)、黒が(0,0,0)なんだと疑問に思う方いませんか?白は色がないんだから(0,0,0)で絵の具を全部混ぜると黒になるから黒は(255,255,255)じゃないかって。私も最初疑問に思ってました。だけど、この色が絵の具じゃなくてライトだと考えればすんなり納得できました。太陽の光は白ですが、プリズムを通すと虹が見えるように白い光はすべての色を含んでいます。つまり、白はすべての色を含む(255,255,255)なのです。また、光がまったくないと真っ暗闇です。だから黒は色をまったく含まない(0,0,0)なのです。

Javaで色を指定するにはColorクラスを使います。たとえば、赤を表すColorオブジェクトを作りたければ、new Color(255,0,0)で作れます。紫を表すColorオブジェクトを作りたければ、new Color(255,0,255)で作れます。こうして作ったColorオブジェクトをsetColor()に渡してあげれば図形の色を指定できます。

    // 赤に変更
    g.setColor(new Color(255,0,0));

いちいち(R,G,B)を指定するのが面倒なので標準の色は名前で指定できるようになっています。

    // 赤に変更
    g.setColor(Color.RED);

この指定方法ではnewは使いません。Javaが内部でnewしてくれているからです。プログラムでは赤(Color.RED)と青(Color.BLUE)を使っています。他にどんな色があるか知りたいですか?そんな場合は、ColorクラスのAPI(Application Programming Interface)を調べてみましょう。

図形を描く

Graphicsオブジェクトgを使うとさまざまな図形が描けます(プログラムでは線と四角形と円しか描いてませんが・・・)。drawLine ()は線を描くメソッドです。プログラムでは(10,10)から(100,10)まで線を引いています。drawRect()は四角形の枠を描くメソッドです。プログラムでは(10,20)を左上の座標とする幅40、高さ40の四角形を描いています。後ろの2つの引数は幅と高さであって、右下の座標でないので注意しましょう。fillRect ()は塗りつぶした四角形を描くメソッドです。drawOval()は円を描くメソッドです。プログラムでは(10,70)を左上の座標とする幅40、高さ40の四角形のぴったりと納まる大きさの円を描いています。fillOval()は塗りつぶした円を描くメソッドです。

線、四角形、円以外にも角丸四角形を描くdrawRoundRect()、ポリゴンを描くdrawPolygon()、弧を描くdrawArc() などのメソッドもあります。詳しくはGraphicsクラスのAPIを見てみましょう。私は線、四角形、円以外はほとんど使ったことないです。

長々と図形を描く方法を解説してきましたが、ゲームでこれらのメソッドを使うことはほとんどありません。地味ですから。実際はイメージを多用します。

aidiaryaidiary 2010/03/27 21:54 何かあればここにコメントください。

jojo 2010/05/26 00:32 すごい面白いですね。このサイト。まさかJavaであんなドラクエまるっきりそのままのものができるとは思いませんでした。

HetHet 2010/07/04 09:42 いつも参考にさせてもらっています。
今更ながら、バグ報告をしても宜しいでしょうか?
sound_engine2のMidiEngine.java内、counter変数は初期化後ずっと0のままなので、92行目をのcounterをmidiMap.size()に置き換えるべきかと思います。
sound_engineの方は最大値チェック自体が無いですね。

aidiaryaidiary 2010/07/04 10:48 ご報告ありがとうございます。おっしゃるとおりです。ずっと前のことで記憶があいまいなのですが、ちょっとずつ拡張していて実装し忘れてしまったような気がします。サウンドエンジンのページにコメントを掲載させてください。

HetHet 2010/07/04 16:53 ごめんなさい。
「92行目をのcounterを」は間違いです。正しくは「92行目のcounterを」です。
私も修正を加えてる内にミスをしてしまいました。

aidiaryaidiary 2010/07/04 17:14 どうもです。修正しておきました。でもその程度の誤字なら誰も気づかないかも(笑)また何かあったらお願いします。

zefa999zefa999 2010/07/08 13:42 はじめまして。
半年くらい前からプログラムを始めたものなのですが
こちらのページのプログラムをいつも参考にさせていただいております。
いろいろなゲームを作られており、すごく面白いです。

友人が、ソースコードジェネレータという
一つのソースコードから他の言語のソースコードを自動で
作成してくれるツールを作成しました。

(JavaScript→Flash ActionScript
DOJA → iPhone 等に変換)

恐らく、変換できるのは携帯向けの言語のソースに変換
するものがほとんどであると思われます。

もし、興味があれば、是非見に来てください。
感想のひとつでもあれば喜んでくれると思いますので
どうかお願いします。

友人のブログ
http://d.hatena.ne.jp/noji_50/20100614/

私の作成しているブログの方で、使い方の補足説明を
させていただいております。

http://d.hatena.ne.jp/zefa999/20100708

yuiyui 2011/08/28 18:38 初歩的かもしれませんが。。。
JAVAで書いたプログラミングをどうすればJARファイルにして実行できるように行えるのでしょうか?

kmkm 2011/08/31 14:17 http://d.hatena.ne.jp/aidiary/20060224/1251376545
この記事に載っています。

vava 2011/09/10 14:07 矢の長さを保つのってどうやっているんですか?
ヒントをください・・・

AKIAKI 2011/10/31 03:53 こんにちは!
どうしても、コマンドがうまくいきません。シンボルが見つからないと言われてしまいます。
何が足りないのでしょうか?
ファイルの中に、二つのjavaをいれてファイルの中でjavacをしています。
MainPanelだけやってみるとうまくいきます。
アドバイスをください!
 
HelloWorld.java:10: cannot find symbol
symbol : variable panel
location: class HelloWorld
contentPane.add(panel);
   ^
1 error

aidiaryaidiary 2011/10/31 22:33 そのエラーはCLASSPATHが設定されてないせいかもしれません。JavaはHelloWorld.javaで使われているクラスMainPanelをCLASSPATHに登録されている場所から探してくるんですが、その探してくる場所にカレントディレクトリ(javacを実行した場所)が指定されてないためかも。Macなんですよね?
javac -classpath . HelloWorld.java (コンパイル)
java -classpath . HelloWorld (実行)
でどうですか?
https://discussionsjapan.apple.com/thread/10062535?start=0&tstart=0
が参考になります。たぶん同じ問題です。-classpath .を毎回書くのが面倒な場合はCLASSPATH環境変数に登録しておくこともできます。ターミナルで
CLASSPATH=.:$CLASSPATH; export CLASSPATH
と打ち込んでみてください。次からは-classpath .がなくてもコンパイル・実行できると思います。

初心者初心者 2012/02/03 20:04 マリオのソース、ショット能力と、体力ゲージの表示、体力の設定を実装したいんですけど、難しくてわかりません^^;
ヒントあんかを教えてください。

がくせいがくせい 2012/02/20 16:13 何がどう難しくてわからないのか、どこまでができて、どこからができないのかなど
具体的に書かないとヒントの出しようがないです。