質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

3383閲覧

ゲームパッドが反映されない

kt3302y

総合スコア27

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/06/27 06:06

編集2016/07/03 08:52

jinputを使用してゲームパッドをコントローラ代わりにしてクライアントサーバ通信でロボットを操作するということを行おうとしています.ゲームパッドを使用するのはクライアント側でjavafx8を使用してアプリケーションを作成しました.問題点はアプリを起動してスティックを動かすとアプリが応答停止になってしまいます.

応答停止になる原因にはどのようなものがあるのでしょうか?
下記にソースコードを載せますのでどこが悪いのか教えてはくれないでしょうか?

operate_with_GamepadController.java(クライアントGUI)

1package ieexp3; 2 3import java.util.function.Consumer; 4 5import javafx.event.ActionEvent; 6import javafx.fxml.FXML; 7import javafx.scene.control.Button; 8import javafx.scene.control.TextField; 9 10 11 12public class operateRobot_with_GamepadController { 13 14 //オブジェクト 15 @FXML private Button buttonConnect; 16 @FXML private Button buttonDisconnect; 17 @FXML private Button buttonRun; 18 @FXML private TextField inputIPaddress; 19 @FXML private TextField inputPort; 20 @FXML private static TextField viewLog; 21 22 //通信クラス 23 static CommunicationTask task; 24 25 static robotController task2; 26 27 28 29 30 31 //イベントハンドラの処理 32 @FXML protected void handleButtonConnect(ActionEvent e){ 33 //接続処理(タスク起動) 34 String server = inputIPaddress.getText(); 35 int port = Integer.parseInt(inputPort.getText()); 36 task = new CommunicationTask(server,port); 37 38 viewLog.textProperty().bind(task.messageProperty()); 39 Thread thread = new Thread(task); 40 thread.setDaemon(true); 41 thread.start(); 42 } 43 @FXML protected void handleButtonDisconnect(ActionEvent e){ 44 //タスク終了処理 45 task.makeMessage("disconnect"); 46 task.cancel(); 47 viewLog.textProperty().unbind(); 48 } 49 @FXML protected void handleButtonRun(ActionEvent e){ 50 task2 = new robotController(); 51 Thread thread = new Thread(task2); 52 thread.setDaemon(true); 53 task.makeMessage("run"); 54 if(ControllerInput.State.x == 1){ 55 task.makeMessage("right"); 56 }else if(ControllerInput.State.x == -1){ 57 task.makeMessage("left"); 58 }else if(ControllerInput.State.y == 1){ 59 task.makeMessage("forward"); 60 }else if(ControllerInput.State.y == -1){ 61 task.makeMessage("back"); 62 }else if(ControllerInput.State.catchButtonPushed){ 63 task.makeMessage("catch"); 64 }else if(ControllerInput.State.downButtonPushed){ 65 task.makeMessage("down"); 66 }else if(ControllerInput.State.upButtonPushed){ 67 task.makeMessage("up"); 68 } 69 } 70 71 72} 73

ControllerInput.java

1package ieexp3; 2 3import java.util.Optional; 4 5 6import net.java.games.input.Controller; 7import net.java.games.input.ControllerEnvironment; 8 9public interface ControllerInput { 10 11 //コントローラーの入力状態を取得する抽象メソッド 12 Optional<ControllerInput.State> getState(); 13 14 15 boolean available(); 16 17 //コントロールオブジェクトを取得する抽象メソッド 18 static Controller detectController(Controller.Type type){ 19 Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers(); 20 for(Controller controller : controllers){ 21 if(controller != null && controller.getType() == type){ 22 return controller; 23 } 24 } 25 return NullController.Instance; 26 } 27 28 //コントローラーの入力状態 29 static final class State { 30 static int x; 31 static int y; 32 static boolean upButtonPushed; 33 static boolean downButtonPushed; 34 static boolean catchButtonPushed; 35 36 37 State(int x,int y,boolean upButtonPushed,boolean downButtonPushed,boolean catchButtonPushed){ 38 this.x = x; 39 this.y = y; 40 this.upButtonPushed = upButtonPushed; 41 this.downButtonPushed = downButtonPushed; 42 this.catchButtonPushed = catchButtonPushed; 43 } 44 } 45} 46

GamepadControllerInput.java

1```package ieexp3; 2 3import java.util.Optional; 4 5import net.java.games.input.Component.Identifier; 6import net.java.games.input.Controller; 7 8 9public final class GamepadControllerInput implements ControllerInput { 10 11 private Controller controller; 12 13 14 private boolean button2Released; 15 private boolean button3Released; 16 private boolean button6Released; 17 18 //ゲームコントローラーコンストラクタ生成 19 GamepadControllerInput(){ 20 this.controller = ControllerInput.detectController(Controller.Type.GAMEPAD); 21 this.button2Released = true; 22 this.button3Released = true; 23 this.button6Released = true; 24 } 25 public Controller getController(){ 26 return this.controller; 27 } 28 @Override 29 public boolean available(){ 30 return controller != NullController.Instance; 31 } 32 33 @Override 34 public Optional<ControllerInput.State> getState(){ 35 //コントローラの入力が受け付けられた場合 36 if(controller.poll()){ 37 //スティックの状態を取得 38 float x0 = controller.getComponent(Identifier.Axis.X).getPollData(); 39 float y0 = controller.getComponent(Identifier.Axis.Y).getPollData(); 40 int x = 0; 41 int y = 0; 42 43 //x軸 44 if(x0 > 0.0f){ 45 x = 1; 46 }else if(x0 < 0.0f){ 47 x = -1; 48 }else{ 49 x = 0; 50 } 51 //y軸 52 if(y0 > 0.0f){ 53 x = 1; 54 }else if(y0 < 0.0f){ 55 x = -1; 56 }else{ 57 x = 0; 58 } 59 //ボタン判定 60 boolean button2Pushed = controller.getComponent(Identifier.Button._1).getPollData()>0.0f; 61 boolean upButtonPushed = button2Released && button2Pushed; 62 button2Released = !button2Pushed; 63 64 boolean button3Pushed = controller.getComponent(Identifier.Button._2).getPollData()>0.0f; 65 boolean downButtonPushed = button3Released && button3Pushed; 66 button3Released = !button3Pushed; 67 68 boolean button6Pushed = controller.getComponent(Identifier.Button._5).getPollData()>0.0f; 69 boolean catchButtonPushed = button6Pushed && button6Released; 70 button6Released = !button6Pushed; 71 72 if(x != 0 || y != 0 || upButtonPushed || downButtonPushed || catchButtonPushed){ 73 return Optional.of(new ControllerInput.State(x, y, upButtonPushed, downButtonPushed, catchButtonPushed)); 74 } 75 76 } 77 return Optional.empty(); 78 } 79 80}

NullController.java

1package ieexp3; 2 3import net.java.games.input.*; 4import net.java.games.input.Component.Identifier; 5 6public final class NullController implements Controller { 7 static final Controller Instance = new NullController(); 8 9 @Override 10 public Controller[] getControllers(){ 11 return new Controller[0]; 12 } 13 @Override 14 public Type getType() { 15 return Controller.Type.UNKNOWN; 16 } 17 18 @Override 19 public Component[] getComponents() { 20 return new Component[0]; 21 } 22 23 @Override 24 public Component getComponent(Identifier id) { 25 return null; 26 } 27 28 @Override 29 public Rumbler[] getRumblers() { 30 return new Rumbler[0]; 31 } 32 33 @Override 34 public boolean poll() { 35 return false; 36 } 37 38 @Override 39 public void setEventQueueSize(int size) { 40 } 41 42 @Override 43 public EventQueue getEventQueue() { 44 return null; 45 } 46 47 @Override 48 public PortType getPortType() { 49 return Controller.PortType.UNKNOWN; 50 } 51 52 @Override 53 public int getPortNumber() { 54 return -1; 55 } 56 57 @Override 58 public String getName() { 59 return "NullController"; 60 } 61}

robotController.java

1package ieexp3; 2 3public class robotController implements Runnable{ 4 5 private ControllerInput gamepadController; 6 7 robotController(){ 8 this.gamepadController = new GamepadControllerInput(); 9 } 10 public void run(){ 11 //ゲームパッド入力 12 if(gamepadController.available()){ 13 while(true){ 14 gamepadController.getState(); 15 sleep(15L); 16 } 17 } 18 } 19 //コントローラ入力の状態を反映 20 public void sleep(long millis){ 21 try{ 22 Thread.sleep(millis); 23 }catch(InterruptedException e){ 24 throw new RuntimeException(e); 25 } 26 } 27}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

おそらく参考にされているページは同じものを見ていると思いますので、そのページを見ながらもう一度以下の点を確認してみてください。

  • ネイティブライブラリーにパスを通す
  • ゲームパッドをONにしてからJavaプログラムを起動する
  • エラー(スタックトレース)が出ていたらそれをチェックする

それと、「ゲームパッドの信号が反映されない問題」について、もう少し調査をお願いします。
デバッグprintなどを活用して、どの時点で処理が動いていないのかを確認してみて下さい。

投稿2016/06/27 06:43

argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kt3302y

2016/06/28 11:10

信号が反映されていないというのほRunボタンのイベントハンドラが設定されていなかったからでした それを直したら6 28, 2016 8:08:19 午後 net.java.games.input.DefaultControllerEnvironment getControllers 警告: Found unknown Windows version: Windows 10 6 28, 2016 8:08:19 午後 net.java.games.input.DefaultControllerEnvironment getControllers 警告: Attempting to use default windows plug-in. このエラーが出たのですがどうすればよいのでしょうか
argius

2016/06/28 11:27

> 信号が反映されていないというのほRunボタンのイベントハンドラが設定されていなかったからでした なるほど。 で、結局のところ動作はしたのでしょうか? > このエラーが出たのですがどうすればよいのでしょうか 最新のjinput2.0.6が2年前なので、Windows10に対応していないのでしょう。 既知のバージョンであればそれ専用の対応を行うが、バージョンが既知でないため、 とりあえずWindowsとして動作する、というメッセージを警告として出しているんだと思います。 ログにおける警告というのは、エラーではないが問題があるかも知れないような場合に出力されます。 その警告を抑制する方法は分かりません。 jinputの新しいバージョンが(出ることは期待できませんが)出るまで待つしか無いかもです。
kt3302y

2016/06/28 11:57

ゲームパッドを接続しているのにコンストラクタでNullControllerを返していましたので動作しませんでした
argius

2016/06/28 12:33

Windows10で(参考サイトの方のコードを)動作確認をしてみたところ、 同じ警告メッセージが出ましたが動作しました。 よって、Windows10だから動作しないというわけではなさそうです。 念のため確認ですが、 最初の回答に書いたことは全てクリアーしているということで良いんですよね? (これを書いていただかないと、どこまでが上手く行っているのか回答者側で判断できません。) それと、jinput以外ではそのゲームパッドは正しく動作しているのですよね?
kt3302y

2016/06/28 13:23

クリアしてると思います. 一つ質問なのですがネイティブライブラリーのパスを通していないとビルドエラーが発生するはずですよね? ゲームパッドはオンラインゲームで使用していたのを使用しているため動作するはずです.
argius

2016/06/28 13:44

> クリアしてると思います. > ゲームパッドはオンラインゲームで使用していたのを使用しているため動作するはずです. 了解です。ありがとうございます。 > ネイティブライブラリーのパスを通していないとビルドエラーが発生するはずですよね? いえ、ネイティブライブラリーはランタイムなので、実行時にパスが通っている場所に存在すれば大丈夫です。 ビルド時と実行時に必要なのは、jinput.jarだけです。 jutils.jarも実行時(のクラスパス)だけでOKです。 ちなみに、ネイティブライブラリーにパスが通っていない場合は、 java.lang.UnsatisfiedLinkError: no jinput-dx8_64 in java.library.path などのエラーが出ます。 GamePadが検出できないのは、jinput内部とWindows側やDirectX側の連携まで 追いかけないといけないので、 せめて現物がないと調査が難しいです。 あっても難航しそうですが... あとはダメ元で、JavaFXを使わずに、 参考にされたサイトのコードをそのまま動かしてみて(Windows10 64ビット版では確認済み)、 それでも動かなければ、 ちょっとお手上げかも知れません。
kt3302y

2016/06/28 22:46

jUtilsというのも追加してクラスパスを通さなければ実行できないのですか?
argius

2016/06/28 23:12

Jutilsは、GradleでJinputを設定したときにGradleが追加してくれています。 プロジェクトの「参照ライブラリー」というところを見ると、 jutils-1.0.0.jarが入っているはずです。 前回の質問の回答はこれのことを言っています。
kt3302y

2016/07/03 08:50

ゲームパッドを取得する際の定数をGamepadからStickに変更したら接続することができました. 次に発生したのがプログラムが応答停止する問題なのですが応答停止になる原因には何が考えられるのですか?
argius

2016/07/03 09:14

ゲームパッドではなく、ジョイスティックタイプだったのでしょうか? 応答停止というのは具体的にどのような状態でしょうか。
argius

2016/07/03 09:33

いま不自由な環境なので小出しになってしまいすみません。 Stateクラスのフィールドはstaticにしてはダメです。 入力状態はgamepadController.getState()の値を使って判定してください。
kt3302y

2016/07/05 11:11

アプリケーションがフリーズしたという表現でいいのですかね statinフィールドにしてはいけない理由はなんでなのでしょうか?
argius

2016/07/06 03:06

ご質問については後半で返答します。 先にコードの改善すべき箇所の説明から書きます。 まず、ControllerInputの入力状態のチェックですが、 これはループの中で行う必要があります。 なので、operateRobot_with_GamepadControllerのhandleButtonRunメソッドに 書いているif文を、robotControllerクラスのrunメソッドのwhile文の中に 書くようにした方がよいです。 あと、handleButtonRunメソッドのthreadはstartされていないので、 処理が開始しないと思います。 フリーズの件は、 Windowsなら「応答なし」状態になるのがフリーズです。 そうでなければ、単に処理が空振りしているだけの可能性があります。 デバッグを行って、どこが動いていないのかを確認してみて下さい。 staticフィールドの件は、 ControllerInput.Stateというのは入力をチェックした その「時点」の「状態」を表すオブジェクトなので、 staticにしてしまうと状態が次のチェックと混ざってしまう恐れがあります。 ただ問題が発生する頻度がとても低いので、 正しく動作しているように見えてしまうと思います。 とにかく、クラスの使い方としては正しくないです。
kt3302y

2016/07/13 13:06

修正したら正常に動作させることができました。 いろいろとお答えしてくれてありがとうございました。 最後にひとつだけお尋ねしたいのですが、 ifPresent(this::changestate) これのthis::changestateはthis.changestateと同じ意味なのでしょうか?
argius

2016/07/13 13:40

this::changestateというのは「メソッド参照」を表します。 this.changestateだとその場でメソッドを実行してしまいますが、 メソッド参照は条件を満たした場合のみメソッドを後から実行するような場合に使用します。 具体的には、 gamepadInput.getState().ifPresent(this::changeState); はgetState()がOptionalを返しますが、値がemptyでない場合にだけ changeState()を実行するようにしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問