トップページ > Java3D入門 > Javaのキーボード入力(4)

物体を動かすテストプログラム

キー入力テストプログラム

前ページで解説したクラスを実際に作ります。メインとなるクラスを記述する “Key_test3.java”というファイルと、 キーボード入力専用のクラスを記述する“key_input2.java”というファイルの 2つを新しく作ることになります。 “key_input2”は、押されたキーを判別するのところで 作ったクラス“key_input”を元にしています。

プログラムの動作内容は、カーソルキーの入力に従って立方体が動くだけです。 [↑]と[↓]で図形が奥に行ったり手前に戻ったりします。[←]と[→]で、左右に 動きます。対応するキーが 思いつかなかったので、上下方向(y軸方向)には動かしていません・・・(汗)

メイン関数で行っていることは、これまでと全く同じです。 フレームを作って、Canvas3Dをのせて、SimpleUniverseを登録して、Boxオブジェクトを 作って…と、おなじみの流れになっています。今回新しい要素が含まれているのは “key_input2”クラスのほうなので、以後の解説は主にkey_input2クラス中心に なります。

おまけの要素としてフレーム上に現在座標を表示するラベルを つけました。このラベルはキーボード入力クラスのフィールドとして管理されています。 新しく付け加えられた部分は、細部までコメントをふっているので行っている処理を 追ってみてください。なお、メインクラスにおいてキーボード入力クラスと組み合わせたことで 変更点が生じた、または、新しくつけたされた処理の部分には[新] と書いています。

ソースコード : key_input2.java

//******************************************************************************
//キーボード入力のためのクラス“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クラスここまで
//******************************************************************************

ソースコード : Key_test3.java

//******************************************************************************
//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);

 }
}
//ソースコードここまで。
//******************************************************************************

若干、問題があります

座標が原点付近であれば、問題なく描画されるのですが…

少し動かすと、すぐに見えなくなってしまいます。 これは、ライトの設定によるものです。 次ページでこれを改善する方法を考えます。




前へ   次へ