Mini-map Spike (2)
Hello, loves!
Another cut at the mini-map. Tout le monde déteste l’IA. … and yet …
My firm intention is never to use the AI plugins and intention files and LLM code generation tools. I can, of course, imagine changing my mind about that, but from what I’ve seen about how one uses them and how they work, I’m not at all sure what would change my mind.
However, a somewhat guilty confession: I still use Google as my search engine, having tried others and found them wanting. And Google often produces an “AI Overview” response, and I am likely to read it, and then likely to go on to one of the links it also produces. When the question is about how to do something in Python, or even in Arcade, the “AI Overview” is quite good. It is often right on target. I have seen it produce completely wrong answers, but only rarely. I have also seen completely wrong answers on stack overflow or reddit.
I have found the “AI Overview” to be useful. I have seen it provide Python/Arcade code, unsolicited, as an example, as part of an answer to a query. I have even given it follow-up questions, and its answers have been even more useful. I have used some of those answers as pointers into Arcade’s or Python’s documentation, and applied what I learned.
I don’t know for sure how I feel about this. I am a Jesuit-trained atheist, and I can rationally discuss most anything … and rationalize a lot of things that probably don’t deserve to be rationalized.
What I will not do, I promise you, is show you code here that I didn’t write, without being clear about how it came to be. I think I’ve done that so far, and I’ll continue.
If you have thoughts about this, feel free to @ me on mastodon, or to drop me an email.
Let’s get to work.
The Mini-map
The task before us is to double the width of the screen, making the left half a mini-map that will appear as you explore, and the right half the same larger map that we have been using right along.
Yesterday I tried a lot of fiddling with the camera without much useful effect. I rolled that back, without as much success as I’d like to have had, and today we’ll try again. The starting plan is:
- Resize the layout array, reducing it a bit so that the screen, doubled, will fit on my monitor.
- Try to bash things so that the dungeon builds, in the zoomed-out size, on the left pane.
- See what’s next based on whatever is learned.
I plan to do some commits along the way, but we can always reset way back if we need to.
In main, we have this:
def main():
layout = DungeonLayout(64, 56)
dungeon = Dungeon(layout)
stepper = make_build_table(layout, dungeon)
screen_width = 16*dungeon.max_x
screen_height = 16*dungeon.max_y
arcade.Window(screen_width, screen_height, 'Caveat Emptor')
view = DungeonView(dungeon)
view.run(stepper)
We’ll change to this:
layout = DungeonLayout(56, 56)
dungeon = Dungeon(layout)
stepper = make_build_table(layout, dungeon)
screen_width = 2*16*dungeon.max_x
screen_height = 16*dungeon.max_y
arcade.Window(screen_width, screen_height, 'Caveat Emptor')
That shows the drawing, as intended, on the left …

However, if I take one more step, the one that places Dot in the dungeon, the whole picture centers. However, and this is probably a useful clue, the scroller message comes out on the left, not centered.
OK. What do we do when we place Dot?
In main:
def populate(layout, dungeon):
dungeon.populate()
# target = random.choice(options)
# DungeonViewMaker(dungeon).view.run()
target = Cell(32, 28)
dungeon.just_set_player_position(target)
And
def just_set_player_position(self, cell):
self.player_cell = cell
OK, that wouldn’t change anything. So it has to be happening in on_draw:
class DungeonView:
def on_draw(self):
self.clear()
player_cell = self.dungeon.player_cell
if player_cell:
self.cameras.scroll_dungeon_cam(self.dungeon.player_cell)
with self.cameras.dungeon_cam.activate():
self.keyed_sprites.draw()
self.draw_adventurer()
self.draw_flood()
with self.cameras.scroller_cam.activate():
self.cameras.scroller.draw()
Gotcha! scroll_dungeon_cam!
class Cameras:
def scroll_dungeon_cam(self, cell):
cx, cy = cell.xy
self.dungeon_cam.position = (cx * cell_size, cy * cell_size)
self.dungeon_cam.position = (
arcade.camera.grips.constrain_xy(
self.dungeon_cam.view_data, self.dungeon_camera_bounds
))
I stole that code from an Arcade example, as described here. I didn’t understand it then, and I don’t understand it now.
Quiet Period
I am bashing at the constraints to try to get the view to stay on the left. I could just not set it, but I’d like to get it right using the grips thing.
I found something to bash that keeps the picture on the left.
class Cameras:
def __init__(self, view, max_x, max_y, zoom):
self.scroller_cam = arcade.Camera2D()
self.scroller = Scroller(lines=4, base=(512,800))
self.dungeon_cam = arcade.Camera2D()
self.dungeon_cam.zoom = zoom
width_margin = self.compute_margin(max_x, zoom)
height_margin = self.compute_margin(max_y, zoom)
self.once = True
self.dungeon_camera_bounds = (
self.margin_rectangle(view.width, view.height, width_margin, height_margin))
def compute_margin(self, cell_count, zoom):
cells_visible = cell_count // zoom
desired_margin = cells_visible // 2
pixel_margin = desired_margin * cell_size
return pixel_margin
def margin_rectangle(self, view_width, view_height, width_margin, height_margin):
rect = arcade.LRBT(width_margin, view_width - width_margin, height_margin, view_height - height_margin)
rect = arcade.LRBT(view_width/2, view_width, 0, view_height)
return rect
The only change is the override of rect there at the end. And the zoomed-out view stays on the left.
Can I push it to the right all the way?
A bit more bashing and this pushes the picture to the right:
def margin_rectangle(self, view_width, view_height, width_margin, height_margin):
rect = arcade.LRBT(width_margin, view_width - width_margin, height_margin, view_height - height_margin)
rect = arcade.LRBT(view_width/2, view_width, 0, view_height)
v = 0
rect = arcade.LRBT(v, v, 0, view_height)
return rect
I don’t know why that works. That’s OK with me for now. With that in place, I want to see what happens at zoomed in scale. Nothing good. I see only a fraction of the build on the left and when it moves to the right, it doesn’t show Dot.
If I go back to the original scheme, I get the big wide display with Dot in the center, not off to the right like I’d like.
Reluctant Conclusion
I think I have to go back to basics, and I believe that I’ll look for a different approach entirely. Arcade as a thing called Section, which is a, well, rectangular section of the entire view, and you can constrain drawing to a section.
More study is needed. I’ve learned a bit, but not enough to see my way to what I want. Break time.
See you anon!