JavaFXを独学で学んでいる者です。
将棋のようなゲームを作ろうとしています。コマを選択し、移動先を選択した際に、処理結果が反映されない事態が生じており困っています。
GridPaneを継承したGameBoardクラスに対して、盤面の状態を示したint型の二重配列を引数にして渡すことで、描画する方法を採用しているのですが、前回の盤面の状態が残ったまま、次のターンの処理結果が表示されてしまいます。
試したこと1
調べた結果、remove()ないしremoveAll() というメソッドがあることを知りましたが、期待通りの結果にはなりませんでした。
下記のコードには、試したremove()も書いてあります。
試したこと2
GameBoardクラスのインスタンスを新たに生成するのではなく、rendering()というメソッドを用いることで、同じインスタンスを使いまわすような設定にしてみました。
GameBoardクラスのインスタンスを新たに生成した場合、移動の結果が全く反映されなかったので、
Mainクラスで選択した描画の対象から外れたのだと考えています。
わかりにくいところなどは指摘していただければ、なるべく早く追記します。
宜しくお願い致します。
追記(18/03/21 - 00:20)
・PieceTypeというのは、個人的に定義しているenumクラスです。コマなし、コマA~コマC、の計4つを持ちます。
・盤面の描画の際、本当はint[][] ではなくPieceType[][] を用いていたので、実際のコードに沿った形に修正しました。
・先ほどまではGameBoardクラスと表記していましたが、コードではBoardLatticeクラスという名前で使用していたので、実際のコードに沿って名前を修正しました。
・MVCのModel部分であるLogManagerクラスの挙動は、標準出力を用いて1つずつ確認したので、このクラスにエラーは無いと判断しています。
見直しをしたので、syntaxErrorは無いと思いますが、ミスがあれば即時対応します。
宜しくお願い致します。
追記2 問題箇所の予想(対処中) (18/03/21 - 08:10)
MVCにおけるViewを担当している、マス目の処理を担うSquareクラス(extends StackPane)の処理に関して、
前のターンにBoardLatticeインスタンスに追加したSquareインスタンスを更新するのではなく、
その上に新たなSquareインスタンスを追加していることが原因だと考えています。
そのため、BoardLatticeクラスの描画仕様を変更するつもりでいます。
描画の方法に関して助言頂ければ幸いです。
宜しくお願い致します。
java
1public class Main extends Application { 2@Override 3public void start(Stage stage) throws Exception { 4 Controller controller = new Controller();// MVCモデルのコントローラ 5 VBox root = new VBox(); 6 root.getChildren().add(controller.gameBoard); 7 (以下はStageやSceneに追加しているだけなので省略) 8}
java
1//MVCのView部分1 - ゲーム盤 2public class BoardLattice extends GridPane { 3 private Boolean turnPlayer1 = true; 4 public IntegerProperty propertyRow = new SimpleIntegerProperty(-1); 5 public IntegerProperty propertyCol = new SimpleIntegerProperty(-1); 6 Square[][] squares; 7 8 public BoardLattice(PieceType[][] boardStatus, Boolean argsTurnPlayer1){ 9 rendering(boardStatus, argsTurnPlayer1); 10 } 11 12 public void rendering(PieceType[][] boardStatus, Boolean argsTurnPlayer1){ 13 turnPlayer1 = argsTurnPlayer1; 14 //描画の処理 15 squares = new Square[5][5]; 16 for(int i=0; i<5; i++){ 17 for(int j=0; j<5; j++){ 18 // 前回のターンの結果を消去した 19 super.getChildren().remove(squares[i][j]); 20 // ImageViewクラスを継承したPieceクラスのインスタンスを生成 21 Piece piece = new Piece(boardStatus[i][j]); 22 squares[i][j].getChildren().add(piece); 23 super.add(squares[i][j], i, j); 24 25 int row = i; 26 int col = j; 27 squares[i][j].setOnMouseClicked(event -> { 28 propertyRow.setValue(row); 29 propertyCol.setValue(col); 30 }; 31 // 手番ではないPlayerの駒が載ったsquares[i][j]をクリックしてもEventが発生しないように設定 32 switch(boardStatus[i][j]){ 33 // 条件分岐のみ省略 34 squares[i][j].setDisable(true); 35 } 36 } 37 } 38 } 39}
java
1//MVCのView部分2 - 移動ボタンのコントローラクラス 2public class DirectionButtonController implements initializable { 3 // 移動ボタンが押されたとき、このコントローラクラスのStringPropertyの値に格納される 4 public static StringProperty direction = new SimpleStringProperty("have not choosen!"); 5 // FXML内に定義したボタン(Polygonクラス) 6 @FXML Polygon upButton; 7 // 移動ボタンにEventを実装 8 EventHandler<MouseEvent> upMethod = (event) -> { 9 direction.setValue("up"); 10 }; 11 @Override 12 public void initialize(URL url, ResourceBandle rb){ 13 upButton.setOnMouseClicked(upMethod); 14 } 15}
java
1//MVCのModel部分 2public class LogManager { 3 public Boolean turnPlayer1; 4 // 選択した駒の行、列の番号 5 public NumberBinding bindRow; 6 public NumberBinding bindCol; 7 // 駒の移動方向を指すStringProperty 8 public StringProperty direction = new SimpleStringProperty(""); 9 10 public int turn; 11 public PieceType[][][] mainLog = new PieceType[256][5][5]; // 256手番もあればゲームが終わる想定 12 public PieceType[][] tmpLog = new PieceType[5][5]; 13 14 public LogManager(){ 15 turn = 1; 16 turnPlayer1 = true; 17 initializeMainLog(); 18 } 19 public int[][] getLog(){ 20 return tmpLog; 21 } 22 // 以下の移動の処理に関しては期待通りの結果が出ているため、各メソッドの詳細は省略しています。 23 public void moveMethod(){ 24 // tmpLogを更新。 25 setTmpLog(); 26 //NumberBinding, StringPropertyの値を用いて移動処理を実行する 27 whichDirection(direction.getValue()); 28 // 実際の移動処理 29 movePiece(bindRow.intValue(), bindCol.intValue()); 30 // 処理結果を格納したtmpLogの値をMainLogに書き込み 31 updateMainLog(); 32 } 33 private void setTmpLog(){ 34 // mainLog[turn]をtmpLogにコピー(省略) 35 } 36 private void whichDirection(String str){ 37 // 移動処理に用いるint型の変数を設定(省略) 38 } 39 private void updateMainLog(){ 40 // ターン数+1 41 turn += 1; 42 // 処理結果を格納したtmpLogの値をMainLogに書き込み(省略) 43 // 手番の入れ替え 44 turnPlayer1 = !turnPlayer1; 45 } 46 47 private void initializeMainLog(){ 48 // MainLog[0], MainLog[1]の2つにおいて、初期状態のコマ配置を指定 49 } 50 51}
java
1public class Controller { 2 //MVCモデルにおける、View: BoardLattice、Model: LogManager 3 public BoardLattice boardLattice; 4 public LogManager logManager; 5 public GridPane directionButton; 6 7 public Controller() throws IOException { 8 logManager = new LogManager(); 9 boardLattice = new BoardLattice(logMangager.getLog()); 10 directionButton = FXMLLoader.load(getClass().getResource("DirectionButton.fxml")); 11 // Binding設定1 - 選択した駒を示す情報のBinding 12 logManager.bindRow = Bindings.add(boardLattice.propertyRow, 0); 13 logManager.bindCol = Bindings.add(boardLattice.propertyCol, 0); 14 // 移動ボタンのコントローラクラス、DirectionButtonControllerのStringPropertyと、logManagerのStringPropertyをBind 15 logManager.direction.bind(DirectionButtonController.direction); 16 // LogManagerのStringPropertyが更新されたとき、移動処理を実行(ChangeListenerをラムダ式で定義) 17 logManager.direction.addListener( (ObservableValue<? extends String> observable, String oldValue, String newValue) -> { 18 // logManager内の移動処理メソッドを実行 19 logManager.moveMethod(); 20 // boardLatticeの再描画 21 boardLattice.rendering(logManager.getLog(), logManager.turnPlayer1); 22 } 23 } 24}
java
1public class Square extends StackPane { 2 public Square(){ 3 super.setPrefSize(70,70); 4 // MouseOver,MouseExitのEventに従って背景を変化(省略) 5 } 6}
回答1件
あなたの回答
tips
プレビュー