#javafx #canvas
Вопрос:
Я очень новичок в JavaFX и в настоящее время работаю над игрой, подобной rouge, в 2D, которая использует графический интерфейс, созданный с помощью JavaFX. Движущийся персонаж нарисован на холсте с помощью GraphicContext2D. Есть только один холст, и я хотел бы решить свою проблему без наложения, если это возможно. Холст добавляется в область границ в качестве центра, Сцена, созданная с помощью этой области границ, для сцены, на которой была установлена эта сцена. Холст перерисовывается после перемещения с персонажем на KeyEvent. Я уже изменил размер сцены. Все работает хорошо, за исключением того, что я просто не могу удерживать своего движущегося персонажа в центре окна, а когда холст больше окна, он может выйти из этого окна. Как я могу удержать моего дорогого подвижного персонажа посередине?
Хорошо, вот очень, очень упрощенная версия, но с той же проблемой, персонаж не остается посередине, он может убежать из окна, а затем вернуться, когда холст установлен больше, чем окно.
public class Main extends Application {
String[][] map = new String[40][20];
int[] playerCoords = {3,10};
//colored.png downloaded from https://kenney.nl/assets/bit-pack
Image tileset = new Image("/colored.png", 815 * 2, 373 * 2, true, false);
Canvas canvas = new Canvas(
20 * 32,
40 * 32);
GraphicsContext context = canvas.getGraphicsContext2D();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage){
BorderPane borderPane = new BorderPane();
borderPane.setCenter(canvas);
map[3][10] = "p";
refresh();
Scene scene = new Scene(borderPane);
scene.setOnKeyPressed(keyEvent -> {switch (keyEvent.getCode()) {
case UP:
this.movePlayer(true);
refresh();
break;
case DOWN:
this.movePlayer(false);
refresh();
break;}});
stage.setScene(scene);
stage.show();
}
void movePlayer(boolean up){
int direction = up ? -1 : 1;
int newPosRow = playerCoords[0] direction;
if ( newPosRow >= 0 amp;amp; newPosRow < map.length) {
map[playerCoords[0]][playerCoords[1]] = null;
playerCoords[0] = newPosRow;
map[playerCoords[0]][playerCoords[1]] = "p";
}
}
void refresh(){
context.setFill(Color.BLACK);
context.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
for (int i = 0; i < map.length; i ){
for (int j = 0; j < map[0].length; j ){
if (map[i][j] != null amp;amp; map[i][j].equals("p")){
//player Tile 28, 0
context.drawImage(tileset, 952,0, 32,32,j * 32,i * 32, 32,32);
} else{
context.drawImage(tileset, 0,0, 32,32,j * 32,i * 32, 32,32);
}
}
}
}
}
Комментарии:
1. Этот метод context.drawImage немного сложен, это случилось и со мной, когда многие номера входных параметров были неверными. Также я использую отдельное приложение класса для запуска приложения, но оно действительно короткое, оно просто вызывает Main.main(args).
2. Его можно загрузить с kenney.nl/assets/bit-pack
3. Я заметил, что я не использую точно такой же png, но я проверил его с помощью этого текущего, который я загрузил несколько минут назад, он работает с ним, просто не очень хорошо, потому что для этого эти цифры в context.drawImage должны быть скорректированы.
4. Хорошо, не в contect.drawImage, а вверху, где я прочитал png для создания объекта изображения, набор листов. Размер файла составляет 815 x 373.
5. Исправлен размер файла в приведенном здесь примере кода.
Ответ №1:
Хорошо, так что, похоже, в настоящее время не существует простого решения JavaFX. Но если кто-то знает одного, спасибо, что поделился. 🙂 Тем временем я подумал об алгоритмическом решении путем преобразования координат в соответствии с абсолютными и относительными (игрок, помещенный посередине) координатами игрока. Он очень далек от совершенства, он изменяет только строки карты, так как в этом примере игрок может перемещаться только по вертикали, и он работает с холстом, не намного превышающим размер окна. Мне нужно было изменить только метод обновления. Есть кое-что, чего я на данный момент не понимаю, это работает с вычитанием centerCol из строки игрока.
int centerRow = map.length/2;
int centerCol = map[0].length/2;
int mapRowDiff = playerCoords[0] - centerCol;
не с вычитанием центральной строки из строки игрока
int centerRow = map.length/2;
int centerCol = map[0].length/2;
int mapRowDiff = playerCoords[0] - centerRow;
Но, по крайней мере, это начало работать.
И вот мое обновление() с преобразованием, оно стало немного сложным.
void refresh(){
context.setFill(Color.BLACK);
context.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
int centerRow = map.length/2;
int centerCol = map[0].length/2;
int mapRowDiff = playerCoords[0] - centerCol;
for (int i = 0; i < map.length; i ){
for (int j = 0; j < map[0].length; j ){
if (mapRowDiff >= 0
amp;amp; mapRowDiff < map.length) {
if (map[mapRowDiff][j] != null amp;amp; map[mapRowDiff][j].equals("p")) {
//player Tile 28, 0
context.drawImage(tileset, 952, 0, 32, 32, j * 32, i * 32, 32, 32);
} else {
context.drawImage(tileset, 0, 0, 32, 32, j * 32, i * 32, 32, 32);
}
} else {
context.drawImage(tileset, 0, 34, 32, 32, j * 32, i * 32, 32, 32);
}
}
mapRowDiff ;
}
}