トップページ > Java3D入門 > Javaのキーボード入力(4)
前ページで解説したクラスを実際に作ります。メインとなるクラスを記述する “Key_test3.java”というファイルと、 キーボード入力専用のクラスを記述する“key_input2.java”というファイルの 2つを新しく作ることになります。 “key_input2”は、押されたキーを判別するのところで 作ったクラス“key_input”を元にしています。
プログラムの動作内容は、カーソルキーの入力に従って立方体が動くだけです。 [↑]と[↓]で図形が奥に行ったり手前に戻ったりします。[←]と[→]で、左右に 動きます。対応するキーが 思いつかなかったので、上下方向(y軸方向)には動かしていません・・・(汗)
メイン関数で行っていることは、これまでと全く同じです。 フレームを作って、Canvas3Dをのせて、SimpleUniverseを登録して、Boxオブジェクトを 作って…と、おなじみの流れになっています。今回新しい要素が含まれているのは “key_input2”クラスのほうなので、以後の解説は主にkey_input2クラス中心に なります。
おまけの要素としてフレーム上に現在座標を表示するラベルを つけました。このラベルはキーボード入力クラスのフィールドとして管理されています。 新しく付け加えられた部分は、細部までコメントをふっているので行っている処理を 追ってみてください。なお、メインクラスにおいてキーボード入力クラスと組み合わせたことで 変更点が生じた、または、新しくつけたされた処理の部分には[新] と書いています。
//****************************************************************************** //キーボード入力のためのクラス“key_input2” //フィールドとしてTransformGroupを持つ。 //外部クラスの図形オブジェクトを、このクラスのTransformGroupに登録。 //おまけとしてラベルに現在座標を表示する。(使用しなくてもよい) //****************************************************************************** //インポート import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.vecmath.*; import javax.media.j3d.*; public class key_input2 implements KeyListener { //============================================================================= //クラスのフィールド //============================================================================= //キーコード用の変数 int KeyCode; //「X座標 :」などの文字列を表示するだけのラベル。 JLabel x_label1; JLabel y_label1; JLabel z_label1; //現在座標の数値を表示するラベル。 JLabel x_label2; JLabel y_label2; JLabel z_label2; //平行移動の座標変換につかう Vector3f vector1; //座標変化用 Transform3D transform1; //ここに外部クラスの図形オブジェクトを登録する。 TransformGroup transform_group1; //============================================================================= //コンストラクタ(簡単な初期設定だけ) //============================================================================= public key_input2() { //ラベルを作成して、文字を入れる x_label1 = new JLabel("X座標 :"); y_label1 = new JLabel("Y座標 :"); z_label1 = new JLabel("Z座標 :"); //ラベル作成。内容はカラにしておく x_label2 = new JLabel(); y_label2 = new JLabel(); z_label2 = new JLabel(); //Transform3Dのインスタンス生成 transform1 = new Transform3D(); //TransformGroupのインスタンス生成 transform_group1 = new TransformGroup(); //座標変換の上書きを許可する transform_group1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); //Vector3Dのインスタンスを生成、リセットしておく vector1 = new Vector3f(0.0f,0.0f,0.0f); } //============================================================================= //キーが押されたときに呼ばれるメソッド //============================================================================= public void keyPressed(KeyEvent event) { //押されたキーのキー・コードを取得 KeyCode = event.getKeyCode(); //どのキーか判別する(今回はカーソルキーのみが対象) switch(KeyCode) { //[←]の場合 case 37: vector1.x -= 1.0f; break; //[↑]の場合 case 38: vector1.z -= 1.0f; break; //[→]の場合 case 39: vector1.x += 1.0f; break; //[↓]の場合 case 40: vector1.z += 1.0f; break; } //値が変更されたvector1に従って、平行移動の座標変換 transform1.setTranslation(vector1); //座標変換をTransformGroupへ登録 transform_group1.setTransform(transform1); //ラベルへ、現在座標の数値を代入。 //元がfloat型なので、int型へキャストしておく。 //int型にキャストしたものをtoString()で文字列に置き換える。 //最後に、ラベル内の文字列としてsetText()で登録。 x_label2.setText( Integer.toString((int)vector1.x ) ); y_label2.setText( Integer.toString((int)vector1.y ) ); z_label2.setText( Integer.toString((int)vector1.z ) ); } //============================================================================= //キーが離されたときに呼ばれるメソッド //============================================================================= public void keyReleased(KeyEvent event) { //何もしない } //============================================================================= //キーがタイプされたときに呼ばれるメソッド //============================================================================= public void keyTyped(KeyEvent event) { //何もしない } } //****************************************************************************** //key_inputクラスここまで //******************************************************************************
//****************************************************************************** //Java3D Key_test3 //キーボードで図形を動かす //****************************************************************************** //============================================================================== //インポート・ファイル import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.geometry.Box; //============================================================================== //メイン・クラス //============================================================================== public class Key_test3 { //============================================================================= //メイン・メソッド public static void main(String[] args) { //コンストラクタを呼ぶだけです。 Key_test3 test = new Key_test3(); } //============================================================================= //コンストラクタ public Key_test3() { //============================================================================ //[新]基礎フレームの設定(フレームのタテの長さをラベルの分だけ増やしています) //============================================================================ JFrame frame = new JFrame(); frame.setSize(300,320); frame.setTitle("Key_test3"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel cp = new JPanel(); cp.setLayout(null); frame.add(cp); //============================================================================ //次にJava3D関係の設定(いつもどおり) //============================================================================ GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration(); Canvas3D canvas = new Canvas3D(g_config); cp.add(canvas); canvas.setBounds(0,20,300,300); //============================================================================ //[新]キーボード入力クラスの登録 //============================================================================ //キーボード入力クラスを生成 key_input2 key = new key_input2(); //Canvas3Dにキーボード入力の受信を登録 canvas.addKeyListener(key); //============================================================================ //[新]キーボード入力クラスのラベルをフレームに登録 //============================================================================ cp.add(key.x_label1); key.x_label1.setBounds(0,0,70,20); cp.add(key.x_label2); key.x_label2.setBounds(70,0,20,20); cp.add(key.y_label1); key.y_label1.setBounds(90,0,70,20); cp.add(key.y_label2); key.y_label2.setBounds(160,0,20,20); cp.add(key.z_label1); key.z_label1.setBounds(180,0,70,20); cp.add(key.z_label2); key.z_label2.setBounds(250,0,20,20); //============================================================================ //空のSimpleUniverseを生成(いつもどおり) //============================================================================ SimpleUniverse universe = new SimpleUniverse(canvas); frame.setVisible(true); //============================================================================ //視点の設定(今回は、少し離れた位置から見下ろすような感じにします) //============================================================================ ViewingPlatform camera = universe.getViewingPlatform(); TransformGroup view_transform_group = camera.getViewPlatformTransform(); Transform3D view_trans1 = new Transform3D(); Transform3D view_trans2 = new Transform3D(); Vector3f view_vec = new Vector3f(0.0f,16.0f,24.0f); view_trans1.setTranslation(view_vec); view_trans2.rotX(-Math.PI/6); view_trans1.mul(view_trans2); view_transform_group.setTransform(view_trans1); //============================================================================ //ライトの設定(いつもと同じ平行光源を設定) //============================================================================ Color3f light_color = new Color3f(1.4f,1.4f,1.4f); Vector3f light_direction = new Vector3f(0.5f,-0.5f,-0.7f); DirectionalLight light = new DirectionalLight(light_color,light_direction); BoundingSphere bounds = new BoundingSphere(); light.setInfluencingBounds(bounds); BranchGroup group2 = new BranchGroup(); group2.addChild(light); universe.addBranchGraph(group2); //============================================================================ //Boxを作る(いつもどおり) //============================================================================ Appearance appearance = new Appearance(); Material material = new Material(); material.setDiffuseColor(0.2f,0.3f,0.9f); appearance.setMaterial(material); Box box = new Box(1.0f,1.0f,1.0f,appearance); //============================================================================ //[新]BoxをTransfomrGroupに追加。さらにTransformGroupをBranchGroupへ登録。 //============================================================================ //BranchGroupを生成 BranchGroup group1 = new BranchGroup(); //キーボード入力クラスのTransformGroupへ、Boxを登録 key.transform_group1.addChild(box); //このクラスのBranchGroupへ //キーボード入力クラスのTransformGroupを登録 group1.addChild(key.transform_group1); //最後に、SimpleUniverseへBranchGroupを追加 universe.addBranchGraph(group1); } } //ソースコードここまで。 //******************************************************************************
座標が原点付近であれば、問題なく描画されるのですが…
少し動かすと、すぐに見えなくなってしまいます。 これは、ライトの設定によるものです。 次ページでこれを改善する方法を考えます。