I started the day with the idea that I would make the tile listeners for my map designer. The map designer, which allows the user to create customized dungeon maps, needs an additional layer that makes each tile able to react to user interaction.
My first inclination seemed reasonable, and I began coding on it pretty fast. Tile-unit sized panels would be made with a mouse motion listener and mouse click listener.
After the building of the listener progressed for a while, it started to become apparent that this plan might not be as feasable as once thought. Because of all of the listening threads I'd constantly be running, the program would cause irresponsible, even if insignificant, strain on the system.
The next idea involved creating one listener, matching the size of the map it overlies, that is intelligent enough to know which tile the mouse is pointing at. After all, this was a much more rational, and managable, approach.
The first step was to extend my MapDisplay Panel. (The
MapDisplay is in charge of displaying the game map.) The next step would be to make a special version of this map, exclusively for the map designer. This specialized MapDisplay would hold the one huge listener mentioned above, and process the map it was holding.Before rip-roaring into this module, the first step was to figure out which utilities were likely to be used again. The decision was made to add conversion utilities to a standard utility class
RH_Utilities that would convert pixel-unit spaces into grid-coordinates, and vice versa.With these conversions made on the fly, the focus returned to the new specialized MapDisplay (called
RHD_MapDisplay ). After building the methods to do the math, it was a breeze having the graphics layer paint a green tile around the currently selected mouse area, with a little simple math.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (!(activatedTile == new Point(-1,-1))) {
// Draw a green sqaure around the currently selected tile
g.setColor(Color.GREEN);
g.drawRect(
activatedTile.x * rougehack.RougeHack.getGridWidth(),
activatedTile.y * rougehack.RougeHack.getGridHeight(),
rougehack.RougeHack.getGridWidth()-2,
rougehack.RougeHack.getGridHeight()-2);
}
}
With that routine finished, the next step was to add the listener to update the current grid-point in focus, and to keep that grid point as a property - in case in comes in handy in the future.
At this point, the setup was *almost* done. Because this new smart-panel was placed inside of a
JScrollPane , the *scroll pane* was the active listener, and muted the new smart panel. Luckily, this was not difficult to get around.By adding a listener onto the scroll pane, and then creating a public method in
RHD_MapDisplay which would allow outside entities to invoke RHD_MapDisplay's mouse listener, the scroll pane allowed the user to get right through to the smart panel, by calling the smart panel's mouse listener through it's own. This worked better than expected (some extra work was anticipated allowing the user to scroll and still be accurate about the mouse conversion - luckily there was no such work needed). After some tweaking of the calculations used to determine where to put that blasted green box, the end result came out nicely:
This is where my progress for this portion of Issue 13 (Upgrade User UI to accept mouse input) , which is still in progress, ceases for the moment.





Turns out that there was a little extra work done here: You see in that 1 2 3 diagram, where steps 1 and 2 are connected by the green arrow? That arrow should just point straight at the smart panel.
ReplyDeleteJava's a smart langauge, and apparently JScrollPane lets its components listen as well.