diff --git a/reticule.py b/reticule.py
new file mode 100644
index 0000000..fa8c424
--- /dev/null
+++ b/reticule.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright © 2024 Simon Forman
+#
+# This file is part of game
+#
+# game is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# game is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with game. If not see .
+#
+
+
+class Reticule:
+
+ def __init__(self, canvas, radius_x=35, radius_y=20, color='green'):
+ self.canvas = canvas
+ self.radius_x = radius_x
+ self.radius_y = radius_y
+ self.color = color
+ self.item_ids = []
+ self.init_reticule()
+
+ def get_reticule_coords(self, x, y):
+ '''
+ Given the width and height of a rectangle and x-y coords in that
+ rectangle yield coords for four lines and an oval suitable for
+ passing to canvas.coords() method.
+ '''
+ width, height = int(self.canvas['width']), int(self.canvas['height'])
+ top = y - self.radius_y
+ left = x - self.radius_x
+ bottom = y + self.radius_y
+ right = x + self.radius_x
+ yield 0, y, left, y
+ yield right, y, width - 1, y
+ yield x, 0, x, top
+ yield x, bottom, x, height - 1
+ yield left, top, right, bottom
+
+ def init_reticule(self):
+ append = self.item_ids.append
+ w, h = int(self.canvas['width']), int(self.canvas['height'])
+ coords = self.get_reticule_coords(w >> 1, h >> 1) # Center.
+ append(canvas.create_line(*next(coords), fill=self.color))
+ append(canvas.create_line(*next(coords), fill=self.color))
+ append(canvas.create_line(*next(coords), fill=self.color))
+ append(canvas.create_line(*next(coords), fill=self.color))
+ append(canvas.create_oval(*next(coords), outline=self.color))
+
+ def set_reticule(self, x, y):
+ coords = self.get_reticule_coords(x, y)
+ for item_id, item_coords in zip(self.item_ids, coords):
+ self.canvas.coords(item_id, *item_coords)
+
+ def handle_set_event(self, event):
+ self.set_reticule(event.x, event.y)
+
+
+if __name__ == '__main__':
+ from tkinter import *
+
+ def handle_canvas_resize(event):
+ # I don't know why the Tk system doesn't update these values.
+ canvas['width'] = event.width
+ canvas['height'] = event.height
+ # update reticule here/now?
+ # If the canvas window has enlarged then some of the lines will have
+ # to be extended.
+
+
+ canvas = Canvas(bg='black')
+
+ canvas.bind('', handle_canvas_resize)
+ canvas.pack(expand=True, fill=BOTH)
+ canvas.update()
+
+ # Let the configure event propagate and trigger the
+ # handle_canvas_resize() callback to set the width
+ # and height values of the canvas correctly so that
+ # the reticule lines get drawn correctly.
+
+ reticule = Reticule(canvas)
+ canvas.bind('', reticule.handle_set_event)
+ canvas.bind('', reticule.handle_set_event)
+
+ #canvas.mainloop()