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

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

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

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

Q&A

解決済

1回答

806閲覧

Java キーボードのイベント処理と再描画

pinchan

総合スコア2

Java

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

1グッド

0クリップ

投稿2022/12/31 12:55

前提

学校の課題でタイルベースゲームのようなものを作っています。

実現したいこと

プレイヤーにマップ上を移動させたい

発生している問題・エラーメッセージ

キーボードのイベント処理で、プレイヤーの位置情報が変更されるようにしました(メソッドplayerMove)
しかし、その後に再描画をする方法が分からず困っています。
多分JavaFXのImageクラス,ImageViewクラスの使い方が多分よくわかってないです。

該当のソースコード

Java

1import javafx.application.Application; 2import javafx.scene.Group; 3import javafx.scene.Scene; 4import javafx.scene.image.Image; 5import javafx.scene.image.ImageView; 6import javafx.scene.paint.Color; 7import javafx.stage.Stage; 8 9import javafx.scene.input.KeyEvent; 10 11 12 13public class TileGame extends Application{ 14 char[][] map; 15 int MX = 6, MY = 6; 16 int boy_x, boy_y; //主人公の位置 17 18 @Override public void start(Stage stage){ 19 Group root = new Group(); 20 Scene scene = new Scene(root); 21 scene.setFill(Color.BLACK); 22 23 stage.setTitle("Tile Game"); 24 stage.setWidth(600); 25 stage.setHeight(600); 26 stage.setScene(scene); 27 stage.sizeToScene(); 28 stage.show(); 29 30 MapMaker(); 31 32 drawInitialMapAndChars(root); 33 scene.setOnKeyPressed(this::keyPressed); 34 } 35 36 public static void main(String[] args) { 37 launch(args); 38 } 39 40 41 public void MapMaker(){ 42 // ひとまわり大きな配列を作る 43 map = new char[MY+2][MX+2]; 44 45 // マップの周囲を見えない壁で囲む 46 for (int x = 0; x <= MX+1; x++) { 47 map[0][x] = 'B'; 48 map[MY+1][x] = 'B'; 49 } 50 51 for (int y = 0; y <= MY+1; y++) { 52 map[y][0] = 'B'; 53 map[y][MX+1] = 'B'; 54 } 55 56 String[] map_str = { //初期マップ 57 " G", 58 "BLB BB", 59 " L ", 60 "BLBLB ", 61 " LML ", 62 "BBBBBB" }; 63 64 // マップデータの読み込み 65 for (int y = 1; y <= MY; y++) { 66 for (int x = 1; x <= MX; x++) { 67 map[y][x] = map_str[y-1].charAt(x-1); 68 if ( map[y][x] == 'M' ) { 69 boy_x = x; 70 boy_y = y; 71 } 72 } 73 } 74 } 75 76 public void drawInitialMapAndChars(Group root) { 77 78 for (int y = 1; y <= MY; y++) { 79 for (int x = 1; x <= MX; x++) { 80 switch ( map[y][x] ) { 81 82 case 'B': // ブロックの描画 83 Image Bimage = new Image("ground.png"); 84 ImageView blockView = new ImageView(Bimage); 85 blockView.setFitWidth(100); 86 blockView.setFitHeight(100); 87 blockView.setX(100*(x-1)); 88 blockView.setY(100*(y-1)); 89 root.getChildren().add(blockView); 90 break; 91 92 case 'G': // 敵の描画 93 94 break; 95 96 case 'M': // プレイヤーの描画 97 Image Pimage = new Image("player.png"); 98 ImageView playerView = new ImageView(Pimage); 99 playerView.setFitWidth(100); 100 playerView.setFitHeight(100); 101 playerView.setX(100*(x-1)); 102 playerView.setY(100*(y-1)); 103 root.getChildren().add(playerView); 104 break; 105 } 106 } 107 } 108 } 109 110 public void keyPressed(KeyEvent e) { 111 112 switch ( e.getCode() ) { 113 case LEFT: 114 playerMove(2); 115 break; // left 116 case RIGHT: 117 playerMove(0); 118 break; // right 119 case UP: 120 playerMove(1); 121 break; // up 122 case DOWN: 123 playerMove(3); 124 break; // down 125 } 126 } 127 128 public void playerMove(int dir) { 129 int dx = 0, dy = 0; 130 switch ( dir ) { 131 case 0: dx = 1; break; // right 132 case 1: dy = -1; break; // up 133 case 2: dx = -1; break; // left 134 case 3: dy = 1; break; // down 135 } 136 if ( dx == 0 && dy == 0 ) return; 137 if ( map[boy_y+dy][boy_x+dx] == 'B' ) return; // block 138 boy_x += dx; boy_y += dy; 139 if ( map[boy_y][boy_x] == ' ' && map[boy_y+1][boy_x] == ' ' ) playerMove(3); // drop 140 else{ 141 map[boy_y][boy_x] = 'M'; 142 //この後再描画 143 } 144 } 145 146}

試したこと

再描画のところでメソッドdrawInitialMapAndCharsをもう一度呼び出してみたら、プレイヤーが移動した分増殖していきました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

TN8001👍を押しています

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

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

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

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

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

jimbe

2022/12/31 13:46

>再描画のところでメソッドdrawInitialMapAndCharsをもう一度呼び出してみたら、プレイヤーが移動した分増殖していきました。 移動するときに移動元を消してませんが。
pinchan

2022/12/31 14:09

コメントありがとうございます。 移動元の消し方?が分からないです。。。 とりあえずマップごと全部描画し直せばいいのかな、というイメージで最初の描画メソッドを呼び出してみたのですが、その前に今描画されているものを消す処理が必要ということでしょうか?
TN8001

2022/12/31 14:41

>> 移動するときに移動元を消してませんが。 > 移動元の消し方?が分からないです。。。 `L`があったりするので単純には消せませんね... どうせ boy_x, boy_y で管理してるので、わざわざ`M`も動かす意味もないような。 `L`の役割と、// drop の意図がちょっとわかりません(`G`にたどり着けなくないですか?)
guest

回答1

0

ベストアンサー

drawInitialMapAndCharsを単純に呼ぶと、ImageViewがどんどん増えていきます。
root.getChildren().clear()として、いったん全部消してからやり直せば増え続けはしなくなります。
しかし現状移動するたびにmapMが増えていくので、やり直してもやっぱりプレイヤーが増えます。

ひとつ動かすために全部作り直すのも無駄ですので、playerViewをフィールドに取り直接動かせばいいでしょう。

Java

1//この後再描画 2playerView.setX(100 * (boy_x - 1)); 3playerView.setY(100 * (boy_y - 1));

ImageViewの元のImageは使いまわせるので、Image Bimage = new Image("ground.png");はループの外に出したほうが省メモリかと思います。

投稿2022/12/31 14:18

編集2022/12/31 15:36
TN8001

総合スコア9321

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

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

pinchan

2022/12/31 15:31

確かに’M’を動かす必要は全くありませんでしたね。。。 ImageViewとImageについて理解が深まりました。 回答していただきありがとうございました。 ちなみに、’L’ははしごで、//dropは下に落下する処理でした。 マップや描画処理など未完成で混乱させていたら申し訳ありませんでした。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問