トップページ > 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);
}
}
//ソースコードここまで。
//******************************************************************************
座標が原点付近であれば、問題なく描画されるのですが…
少し動かすと、すぐに見えなくなってしまいます。 これは、ライトの設定によるものです。 次ページでこれを改善する方法を考えます。