Background:
I'm working on a visualizer for real-time planning algorithms. The 'world' is provided in a text file, where '_' is a free cell, and '#' is a blocked cell. The following is an example:
41 21 ___________________@_____________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _#######################################_ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ ___________________*_____________________
It is very important that the window has the exact same number of cells in every row and the exact same number of cells in every column.
I have to visualize in Kotlin, which is 100% interoperable with Java. I decided to try javafx, version 8.0.60. After doing some research on javafx layouts, I decided TilePane was my best bet.
What I have so far:
This is what I have so far. If you look closely, you can see a very small amount of padding within each node of the TilePane. As the robot goes from tile to tile, this small amount of padding introduces a slight error, because the robot moves using the width and height of the tile, not accounting for the padding. This causes the robot to not be in the center of the tile as it traverses the maze.
Additionally, my solution is very dependent on the size of the window. If I adjust it slightly, the world is displayed incorrectly because each row and column do not have the same number of fixed cells.
Questions:
These questions are in order of importance.
- Is there a layout or setting that will provide me with a fixed number of cells per row and per column? Displaying the world depends on that.
- How do I get rid of the padding between each node in the layout?
- If possible, I would like to resize the layout, while maintaining the first two invariants. Does anyone know of a way to do this?
Relevant parts of my code:
Note: robot.fill is the same as calling robot.setFill, and Kotlin omits types and the keyword new when instantiating objects.
val root = TilePane(0.0, 0.0)
/* The robot */
val robotWidth = TILE_WIDTH / 4.0
val robot = Rectangle(robotWidth, robotWidth)
robot.fill = Color.ORANGE
/* The robots starting location, needs to be drawn later */
var startX: Double? = null
var startY: Double? = null
for (y in 0..rowCount - 1) {
val line = inputScanner.nextLine()
for (x in 0..columnCount - 1) {
when (line[x]) {
'#' -> {
val blocked = Rectangle(TILE_WIDTH, TILE_HEIGHT)
blocked.fill = Color.BLACK
//blocked.stroke = Color.BLACK
root.children.add(blocked)
}
'_' -> {
val free = Rectangle(TILE_WIDTH, TILE_HEIGHT)
free.fill = Color.LIGHTSLATEGRAY
free.opacity = .5
root.children.add(free)
}
'*' -> {
val radius = TILE_WIDTH / 10.0
val dirtyCell = Circle(radius)
//dirtyCell.stroke = Color.BLUE
dirtyCell.fill = Color.BLUE
root.children.add(dirtyCell)
}
'@' -> {
startX = x * 1.0
startY = y * 1.0
root.children.add(robot)
}
}
}
}