(* A Simple Game, with 2D physics *) (* Copyright (C) 2024 Florent Monnier *) (* To the extent permitted by law, you can use, modify, and redistribute this software, and the associated elements, as long as you also respect the distribution agreements of these associated elements. The 2D physics functions was provided by ChatGPT. *) let width, height = (520, 360) type point = float * float type segment = point * point type circle = { mutable cx: float; (* center (cx, cy) *) mutable cy: float; mutable r: float; (* radius *) mutable vx: float; (* inertia vector (vx, vy) *) mutable vy: float; mutable static: bool; mutable touched: bool; } (* Access to the canvas from the html document *) let canvas = Canvas.getElementById Canvas.document "my_canvas" let ctx = Canvas.getContext canvas "2d" type key_change = KeyDown | KeyUp let red = "#F00" let green = "#0F0" let blue = "#00F" let white = "#FFF" let black = "#000" let bg_color = blue let seg_color = white let circ_color = black (* Draw Circle *) let draw_circle color circle = if circle.static then begin Canvas.strokeStyle ctx green; Canvas.beginPath ctx; Canvas.lineWidth ctx 2.0; Canvas.arc ctx circle.cx circle.cy circle.r 0.0 6.28 false; Canvas.closePath ctx; Canvas.stroke ctx; end else begin Canvas.strokeStyle ctx color; Canvas.beginPath ctx; Canvas.lineWidth ctx 2.0; Canvas.arc ctx circle.cx circle.cy circle.r 0.0 6.28 false; Canvas.closePath ctx; Canvas.stroke ctx; end; () ;; (* Draw Segment *) let draw_segment color segment = let p1, p2 = segment in let p1x, p1y = p1 in let p2x, p2y = p2 in Canvas.strokeStyle ctx color; Canvas.lineWidth ctx 1.4; Canvas.beginPath ctx; Canvas.moveTo ctx p1x p1y; Canvas.lineTo ctx p2x p2y; Canvas.closePath ctx; Canvas.stroke ctx; () ;; (* Display Background *) let display_background () = (* Fill the background *) Canvas.fillStyle ctx bg_color; Canvas.fillRect ctx 0 0 width height; () ;; (* Display Level *) let display_level circles segments = (* Draw the circles *) List.iter (draw_circle circ_color) circles; (* Draw the segments *) List.iter (draw_segment seg_color) segments; () ;; (* Function to apply gravity to a circle *) let apply_gravity circle (gx, gy) dt = circle.vx <- circle.vx +. gx *. dt; circle.vy <- circle.vy +. gy *. dt; ;; (* Function to normalize a vector (x, y) *) let normalize_vector (x, y) = let magnitude = sqrt (x *. x +. y *. y) in if magnitude = 0. then (0., 0.) (* Handle the zero vector case to avoid division by zero *) else (x /. magnitude, y /. magnitude) (* Function to handle collision between a circle and a segment *) let collision_circle_segment circle ((p1x, p1y), (p2x, p2y)) restitution = let cx, cy, r = circle.cx, circle.cy, circle.r in let vx, vy = circle.vx, circle.vy in (* Calculate the minimum and maximum x and y values of the segment *) let min_x = min p1x p2x in let min_y = min p1y p2y in let max_x = max p1x p2x in let max_y = max p1y p2y in (* Quick check if the circle can be in collision *) if (cx +. r >= min_x) && (cx -. r <= max_x) && (cy +. r >= min_y) && (cy -. r <= max_y) then (* Calculate the direction vector of the segment *) let dx = p2x -. p1x in let dy = p2y -. p1y in (* Calculate the vector from the start of the segment to the center of the circle *) let fx = cx -. p1x in let fy = cy -. p1y in (* Calculate the parameter t for the projection of the circle's center on the segment *) let t = (fx *. dx +. fy *. dy) /. (dx *. dx +. dy *. dy) in (* Calculate the point of projection on the segment *) let projection_x, projection_y = if t < 0. then (p1x, p1y) else if t > 1. then (p2x, p2y) else (p1x +. t *. dx, p1y +. t *. dy) in (* Calculate the distance between the center of the circle and the projection point *) let distance = sqrt ((cx -. projection_x) ** 2. +. (cy -. projection_y) ** 2.) in (* Check for collision *) if distance <= r then (* Collision detected, calculate the new velocity vector *) let normal_x = (cx -. projection_x) /. distance in let normal_y = (cy -. projection_y) /. distance in let dot_product = vx *. normal_x +. vy *. normal_y in (* Update the velocity vector by inverting the normal component and applying restitution *) if not circle.static then begin circle.vx <- vx -. (1. +. restitution) *. dot_product *. normal_x; circle.vy <- vy -. (1. +. restitution) *. dot_product *. normal_y; end; (* Separate the circle from the segment to avoid consecutive collisions *) let penetration_depth = r -. distance in if not circle.static then begin circle.cx <- cx +. normal_x *. penetration_depth; circle.cy <- cy +. normal_y *. penetration_depth; end; ;; (* Function to handle collision between two circles *) let collision_circle_circle circle1 circle2 restitution = let dx = circle2.cx -. circle1.cx in let dy = circle2.cy -. circle1.cy in let distance = sqrt (dx *. dx +. dy *. dy) in let overlap = circle1.r +. circle2.r -. distance in if overlap > 0.0 then let normal_x, normal_y = normalize_vector (dx, dy) in let relative_velocity_x = circle1.vx -. circle2.vx in let relative_velocity_y = circle1.vy -. circle2.vy in let dot_product = relative_velocity_x *. normal_x +. relative_velocity_y *. normal_y in if dot_product > 0.0 then (* Resolve the collision by adjusting the velocities *) let impulse = (1. +. restitution) *. dot_product /. (circle1.r +. circle2.r) in if not circle1.static then begin circle1.vx <- circle1.vx -. impulse *. normal_x; circle1.vy <- circle1.vy -. impulse *. normal_y; end; if not circle2.static then begin circle2.vx <- circle2.vx +. impulse *. normal_x; circle2.vy <- circle2.vy +. impulse *. normal_y; end; if circle1.static then circle1.touched <- true; if circle2.static then circle2.touched <- true; (* Separate the circles to avoid consecutive collisions *) let separation = overlap /. 2.0 in if not circle1.static then begin circle1.cx <- circle1.cx -. normal_x *. separation; circle1.cy <- circle1.cy -. normal_y *. separation; end; if not circle2.static then begin circle2.cx <- circle2.cx +. normal_x *. separation; circle2.cy <- circle2.cy +. normal_y *. separation; end; ;; (* Function to update the position of multiple circles and handle collisions *) let update_circles circles segments gravity dt restitution = List.iter (fun circle -> if not circle.static then begin (* Apply gravity to the circle's velocity *) apply_gravity circle gravity dt; (* Update the circle's position based on its velocity *) circle.cx <- circle.cx +. circle.vx *. dt; circle.cy <- circle.cy +. circle.vy *. dt; (* Check for collisions with each segment *) List.iter (fun segment -> collision_circle_segment circle segment restitution ) segments end; ) circles; (* Check for collisions between circles *) let rec check_circle_collisions circles = match circles with | [] -> () | circle1 :: rest -> List.iter (fun circle2 -> collision_circle_circle circle1 circle2 restitution ) rest; check_circle_collisions rest in check_circle_collisions circles; ;; (* Events *) type keys = { mutable left : bool; mutable right : bool; mutable up : bool; mutable down : bool; mutable s : bool; (* scale out *) mutable n : bool; (* next level *) } let keys = { left = false; right = false; up = false; down = false; s = false; n = false; } (* Key Change *) let ev_keychange key_change ev = match key_change, ev.Canvas.keyCode, ev.Canvas.key with | KeyDown, 37, _ -> (keys.left <- true) (* Left *) | KeyDown, 39, _ -> (keys.right <- true) (* Right *) | KeyDown, 38, _ -> (keys.up <- true) (* Up *) | KeyDown, 40, _ -> (keys.down <- true) (* Down *) | KeyUp, 37, _ -> (keys.left <- false) (* Left *) | KeyUp, 39, _ -> (keys.right <- false) (* Right *) | KeyUp, 38, _ -> (keys.up <- false) (* Up *) | KeyUp, 40, _ -> (keys.down <- false) (* Down *) | KeyDown, _, "s" -> (keys.s <- true) | KeyUp, _, "s" -> (keys.s <- false) | KeyDown, _, "n" -> (keys.n <- true) | KeyUp, _, "n" -> (keys.n <- false) | KeyDown, _, " " -> () | _ -> () ;; (* Levels *) let targets_2 = Array.to_list [| (-324.5, 94.4); (459.0, 474.2); (432.0, -199.0); (1350.5, 175.4); (1139.5, 220.9); (1268.0, 56.9); (-152.5, 784.4); (-73.0, 932.4); (133.5, 687.4); (744.5, -888.6); (417.5, -1028.1); (1204.1, -955.1); (1535.0, -738.6); |] let level_2 = Array.to_list [| (240.0, 342.4), (200.0, 342.4); (200.0, 342.4), (160.0, 372.4); (160.0, 372.4), (-30.0, 372.4); (-30.0, 372.4), (-30.0, 412.4); (-30.0, 412.4), (30.0, 412.4); (30.0, 412.4), (30.0, 532.4); (30.0, 532.4), (0.0, 532.4); (0.0, 532.4), (-30.0, 492.4); (-30.0, 492.4), (-90.0, 492.4); (-90.0, 492.4), (-90.0, 532.4); (-90.0, 532.4), (-120.0, 532.4); (-120.0, 532.4), (-120.0, 652.4); (-120.0, 652.4), (-150.0, 692.4); (-150.0, 692.4), (-210.0, 692.4); (-210.0, 692.4), (-240.0, 733.4); (-240.0, 733.4), (-270.0, 772.4); (-270.0, 772.4), (-270.0, 862.4); (-270.0, 862.4), (-180.0, 862.4); (-180.0, 862.4), (-180.0, 912.4); (-180.0, 912.4), (-210.0, 952.4); (-210.0, 952.4), (-210.0, 1012.4); (-210.0, 1012.4), (60.0, 1012.4); (60.0, 1012.4), (140.0, 952.4); (140.0, 952.4), (250.0, 952.4); (250.0, 952.4), (290.0, 922.4); (290.0, 922.4), (290.0, 822.4); (290.0, 822.4), (260.0, 782.4); (260.0, 782.4), (260.0, 702.4); (260.0, 702.4), (230.0, 662.4); (230.0, 662.4), (230.0, 502.4); (230.0, 502.4), (150.0, 502.4); (150.0, 502.4), (110.0, 532.4); (110.0, 532.4), (70.0, 532.4); (70.0, 532.4), (70.0, 412.4); (70.0, 412.4), (160.0, 412.4); (160.0, 412.4), (160.0, 442.4); (160.0, 442.4), (200.0, 442.4); (200.0, 442.4), (240.0, 412.4); (240.0, 412.4), (240.1, 382.4); (240.1, 382.4), (320.1, 382.4); (320.1, 382.4), (440.1, 292.4); (440.1, 292.4), (440.1, 232.4); (440.1, 232.4), (520.1, 172.4); (520.1, 172.4), (580.1, 172.4); (580.1, 172.4), (580.1, 232.4); (580.1, 232.4), (540.1, 262.4); (540.1, 262.4), (520.1, 262.4); (520.1, 262.4), (480.1, 292.4); (480.1, 292.4), (480.1, 372.4); (480.1, 372.4), (400.1, 432.4); (400.1, 432.4), (400.1, 492.4); (400.1, 492.4), (500.1, 492.4); (500.1, 492.4), (620.1, 402.4); (620.1, 402.4), (650.1, 402.4); (650.1, 402.4), (680.1, 442.4); (680.1, 442.4), (730.1, 442.4); (730.1, 442.4), (730.1, 342.4); (730.1, 342.4), (700.1, 302.4); (700.1, 302.4), (670.1, 302.4); (670.1, 302.4), (640.1, 262.4); (640.1, 262.4), (640.1, 172.4); (640.1, 172.4), (930.0, 172.4); (930.0, 172.4), (990.0, 252.4); (990.0, 252.4), (1050.0, 252.4); (1050.0, 252.4), (1050.0, 332.4); (1050.0, 332.4), (1220.0, 332.4); (1220.0, 332.4), (1300.0, 272.4); (1300.0, 272.4), (1460.0, 272.4); (1460.0, 272.4), (1460.0, 162.4); (1460.0, 162.4), (1430.0, 122.4); (1430.0, 122.4), (1430.0, 52.4); (1430.0, 52.4), (1400.0, 12.4); (1400.0, 12.4), (1330.0, 12.4); (1330.0, 12.4), (1330.0, -47.6); (1330.0, -47.6), (1250.0, -47.6); (1250.0, -47.6), (1170.0, 12.4); (1170.0, 12.4), (1090.0, 12.4); (1090.0, 12.4), (930.0, 132.4); (930.0, 132.4), (860.0, 132.4); (860.0, 132.4), (860.0, 52.4); (860.0, 52.4), (980.0, -37.6); (980.0, -37.6), (980.0, -157.6); (980.0, -157.6), (1100.0, -247.6); (1100.0, -247.6), (1100.0, -367.6); (1100.0, -367.6), (1260.0, -367.6); (1260.0, -367.6), (1340.0, -427.6); (1340.0, -427.6), (1500.0, -427.6); (1500.0, -427.6), (1500.0, -487.6); (1500.0, -487.6), (1660.0, -487.6); (1660.0, -487.6), (1820.0, -607.6); (1820.0, -607.6), (1821.0, -727.6); (1821.0, -727.6), (1780.0, -727.6); (1780.0, -727.6), (1660.0, -887.6); (1660.0, -887.6), (1500.0, -887.6); (1500.0, -887.6), (1440.0, -967.6); (1440.0, -967.6), (1360.0, -967.6); (1360.0, -967.6), (1360.0, -1027.6); (1360.0, -1027.6), (1440.0, -1087.6); (1440.0, -1087.6), (1440.0, -1227.6); (1440.0, -1227.6), (1300.0, -1227.6); (1300.0, -1227.6), (1220.0, -1167.6); (1220.0, -1167.6), (980.0, -1167.6); (980.0, -1167.6), (900.0, -1107.6); (900.0, -1107.6), (660.0, -1107.6); (660.0, -1107.6), (580.0, -1047.6); (580.0, -1047.6), (360.0, -1047.6); (360.0, -1047.6), (200.0, -927.6); (200.0, -927.6), (200.0, -787.6); (200.0, -787.6), (360.0, -787.6); (360.0, -787.6), (360.0, -667.6); (360.0, -667.6), (420.0, -587.6); (420.0, -587.6), (520.0, -587.6); (520.0, -587.6), (550.0, -547.6); (550.0, -547.6), (690.0, -547.6); (690.0, -547.6), (780.0, -427.6); (780.0, -427.6), (900.0, -427.6); (900.0, -427.6), (900.0, -387.6); (900.0, -387.6), (1030.0, -387.6); (1030.0, -387.6), (1030.0, -267.6); (1030.0, -267.6), (910.0, -177.6); (910.0, -177.6), (910.0, -57.6); (910.0, -57.6), (790.0, 32.4); (790.0, 32.4), (790.0, 132.4); (790.0, 132.4), (640.0, 132.4); (640.0, 132.4), (640.0, 12.4); (640.0, 12.4), (720.0, 12.4); (720.0, 12.4), (800.0, -47.6); (800.0, -47.6), (800.0, -137.6); (800.0, -137.6), (650.0, -137.6); (650.0, -137.6), (620.0, -177.6); (620.0, -177.6), (520.0, -177.6); (520.0, -177.6), (490.0, -217.6); (490.0, -217.6), (400.0, -217.6); (400.0, -217.6), (400.0, -147.6); (400.0, -147.6), (460.0, -67.6); (460.0, -67.6), (520.0, -67.6); (520.0, -67.6), (580.0, 12.4); (580.0, 12.4), (580.0, 132.4); (580.0, 132.4), (500.1, 132.4); (500.1, 132.4), (470.1, 92.4); (470.1, 92.4), (260.1, 92.4); (260.1, 92.4), (220.1, 122.4); (220.1, 122.4), (160.1, 122.4); (160.1, 122.4), (80.1, 182.4); (80.1, 182.4), (80.1, 242.4); (80.1, 242.4), (10.1, 242.4); (10.1, 242.4), (-19.9, 202.4); (-19.9, 202.4), (-139.9, 202.4); (-139.9, 202.4), (-140.0, 172.4); (-140.0, 172.4), (-60.0, 112.4); (-60.0, 112.4), (-60.0, -7.6); (-60.0, -7.6), (-300.0, -7.6); (-300.0, -7.6), (-420.0, 82.4); (-420.0, 82.4), (-420.0, 182.4); (-420.0, 182.4), (-215.0, 182.4); (-215.0, 182.4), (-139.9, 282.4); (-139.9, 282.4), (-19.9, 282.4); (-19.9, 282.4), (-19.9, 322.4); (-19.9, 322.4), (60.1, 322.4); (60.1, 322.4), (100.1, 292.4); (100.1, 292.4), (240.1, 292.4); (240.0, 342.4), (240.1, 292.4); (1170.0, 72.4), (1170.0, 102.4); (1170.0, 102.4), (1090.0, 162.4); (1090.0, 162.4), (1050.0, 162.4); (1050.0, 162.4), (1050.0, 102.4); (1050.0, 102.4), (1090.0, 72.4); (1170.0, 72.4), (1090.0, 72.4); (180.0, 832.4), (140.0, 862.4); (140.0, 862.4), (10.0, 862.4); (10.0, 862.4), (10.0, 822.4); (10.0, 822.4), (-20.0, 782.4); (-20.0, 782.4), (-20.0, 742.4); (-20.0, 742.4), (40.0, 742.4); (40.0, 742.4), (70.0, 782.4); (70.0, 782.4), (180.0, 782.4); (180.0, 832.4), (180.0, 782.4); (879.6, -867.1), (820.0, -867.6); (820.0, -867.6), (820.0, -907.6); (820.0, -907.6), (600.0, -907.6); (600.0, -907.6), (600.0, -967.6); (600.0, -967.6), (680.0, -1027.6); (680.0, -1027.6), (900.0, -1027.6); (900.0, -1027.6), (1020.0, -867.6); (1020.0, -867.6), (1020.0, -787.6); (1020.0, -787.6), (940.0, -787.6); (879.6, -867.1), (940.0, -787.6); (1340.0, -527.6), (1260.0, -467.6); (1260.0, -467.6), (1220.0, -467.6); (1220.0, -467.6), (1220.6, -547.1); (1220.6, -547.1), (1160.0, -627.6); (1160.0, -627.6), (960.0, -627.6); (960.0, -627.6), (960.6, -548.1); (960.6, -548.1), (840.0, -547.6); (840.0, -547.6), (779.6, -628.1); (779.6, -628.1), (680.0, -627.6); (680.0, -627.6), (680.0, -667.6); (680.0, -667.6), (860.0, -667.6); (860.0, -667.6), (940.0, -727.6); (940.0, -727.6), (1280.0, -727.6); (1280.0, -727.6), (1340.0, -647.6); (1340.0, -647.6), (1340.0, -567.6); (1340.0, -567.6), (1420.0, -567.6); (1420.0, -567.6), (1420.0, -527.6); (1340.0, -527.6), (1420.0, -527.6); (1461.0, -707.6), (1460.0, -667.6); (1460.0, -667.6), (1381.0, -667.6); (1381.0, -667.6), (1320.0, -747.6); (1320.0, -747.6), (1320.0, -767.6); (1320.0, -767.6), (1420.0, -767.6); (1420.0, -767.6), (1500.0, -827.6); (1500.0, -827.6), (1620.0, -827.6); (1620.0, -827.6), (1620.0, -767.6); (1620.0, -767.6), (1540.0, -767.6); (1461.0, -707.6), (1540.0, -767.6); (1180.0, -847.6), (1180.0, -787.6); (1180.0, -787.6), (1080.0, -787.6); (1080.0, -787.6), (1080.0, -867.6); (1080.0, -867.6), (1160.0, -927.6); (1160.0, -927.6), (1200.0, -927.6); (1200.0, -927.6), (1280.0, -987.6); (1280.0, -987.6), (1301.0, -987.6); (1301.0, -987.6), (1300.6, -907.1); (1300.6, -907.1), (1260.0, -907.6); (1180.0, -847.6), (1260.0, -907.6); (620.0, -727.6), (620.0, -647.6); (620.0, -647.6), (580.0, -647.6); (580.0, -647.6), (520.0, -727.6); (520.0, -727.6), (440.0, -727.6); (440.0, -727.6), (440.0, -787.6); (440.0, -787.6), (520.0, -847.6); (520.0, -847.6), (600.0, -847.6); (600.0, -847.6), (660.0, -767.6); (660.0, -767.6), (700.0, -767.6); (700.0, -767.6), (700.0, -727.6); (620.0, -727.6), (700.0, -727.6); |] let targets_3 = Array.to_list [| (1340.5, 603.9); (-2281.5, 1627.1); |] let level_3 = Array.to_list [| (-1347.2, 808.1), (-1347.5, 873.9); (-1347.5, 873.9), (-1262.9, 874.8); (-1262.9, 874.8), (-1262.6, 824.8); (-1262.6, 824.8), (-1099.2, 824.8); (-1099.2, 824.8), (-1099.4, 761.6); (-1099.4, 761.6), (-913.1, 761.6); (-913.1, 761.6), (-913.3, 703.6); (-913.3, 703.6), (-1000.2, 703.8); (-1000.2, 703.8), (-999.2, 646.0); (-999.2, 646.0), (-1172.6, 645.2); (-1172.6, 645.2), (-1171.9, 571.3); (-1171.9, 571.3), (-1023.5, 571.4); (-1023.5, 571.4), (-1024.4, 442.4); (-1024.4, 442.4), (-1140.0, 442.4); (-1140.0, 442.4), (-1140.0, 312.4); (-1140.0, 312.4), (-1235.0, 312.4); (-1235.0, 312.4), (-1235.0, 142.4); (-1235.0, 142.4), (-1114.6, 143.4); (-1114.6, 143.4), (-1115.0, 232.9); (-1115.0, 232.9), (-1065.0, 232.4); (-1065.0, 232.4), (-1065.0, 298.4); (-1065.0, 298.4), (-970.0, 298.4); (-970.0, 298.4), (-970.0, 387.4); (-970.0, 387.4), (-910.1, 387.4); (-910.1, 387.4), (-910.2, 527.2); (-910.2, 527.2), (-870.0, 527.0); (-870.0, 527.0), (-870.0, 572.8); (-870.0, 572.8), (-804.9, 572.4); (-804.9, 572.4), (-805.0, 707.4); (-805.0, 707.4), (-710.3, 707.2); (-710.3, 707.2), (-710.0, 742.3); (-710.0, 742.3), (-649.8, 742.1); (-649.8, 742.1), (-650.2, 807.4); (-650.2, 807.4), (-589.9, 807.2); (-589.9, 807.2), (-590.3, 912.7); (-590.3, 912.7), (-545.0, 912.6); (-545.0, 912.6), (-544.1, 967.6); (-544.1, 967.6), (-435.0, 967.7); (-435.0, 967.7), (-434.6, 1012.4); (-434.6, 1012.4), (-274.3, 1012.7); (-274.3, 1012.7), (-275.1, 707.7); (-275.1, 707.7), (-229.7, 752.8); (-229.7, 752.8), (-229.3, 862.7); (-229.3, 862.7), (-94.7, 862.6); (-94.7, 862.6), (-95.0, 682.4); (-95.0, 682.4), (-55.0, 642.4); (-55.0, 642.4), (105.0, 802.4); (105.0, 802.4), (205.0, 702.4); (205.0, 702.4), (260.0, 757.4); (260.0, 757.4), (356.0, 663.4); (356.0, 663.4), (255.0, 562.4); (255.0, 562.4), (315.0, 502.4); (315.0, 502.4), (335.0, 522.4); (335.0, 522.4), (370.0, 487.4); (370.0, 487.4), (460.0, 578.4); (460.0, 578.4), (555.0, 482.4); (555.0, 482.4), (555.0, 372.4); (555.0, 372.4), (440.0, 372.4); (440.0, 372.4), (440.0, 307.4); (440.0, 307.4), (360.0, 307.4); (360.0, 307.4), (360.0, 252.4); (360.0, 252.4), (570.0, 252.4); (570.0, 252.4), (570.0, 172.4); (570.0, 172.4), (415.0, 172.4); (415.0, 172.4), (415.0, 122.4); (415.0, 122.4), (295.0, 122.4); (295.0, 122.4), (295.0, -27.6); (295.0, -27.6), (110.0, -27.6); (110.0, -27.6), (110.0, 17.4); (110.0, 17.4), (20.0, 17.4); (20.0, 17.4), (20.0, -2.6); (20.0, -2.6), (-85.0, -2.6); (-85.0, -2.6), (-85.0, 32.4); (-85.0, 32.4), (-105.0, 32.4); (-105.0, 32.4), (-105.0, -137.6); (-105.0, -137.6), (60.0, -137.6); (60.0, -137.6), (60.0, -82.6); (60.0, -82.6), (165.0, -82.6); (165.0, -82.6), (165.0, -127.6); (165.0, -127.6), (335.0, -127.6); (335.0, -127.6), (335.0, -157.6); (335.0, -157.6), (400.0, -157.6); (400.0, -157.6), (400.0, -102.6); (400.0, -102.6), (355.0, -102.6); (355.0, -102.6), (355.0, -12.6); (355.0, -12.6), (560.0, -12.6); (560.0, -12.6), (560.0, 22.4); (560.0, 22.4), (650.0, 22.4); (650.0, 22.4), (650.0, 57.4); (650.0, 57.4), (805.0, 57.4); (805.0, 57.4), (805.0, -92.6); (805.0, -92.6), (835.0, -92.6); (835.0, -92.6), (835.0, 122.4); (835.0, 122.4), (675.1, 120.4); (675.1, 120.4), (675.0, 272.4); (675.0, 272.4), (635.0, 272.4); (635.0, 272.4), (635.0, 532.4); (635.0, 532.4), (720.0, 532.4); (720.0, 532.4), (720.0, 722.4); (720.0, 722.4), (920.0, 722.4); (920.0, 722.4), (920.0, 822.4); (920.0, 822.4), (1185.0, 822.4); (1185.0, 822.4), (1185.0, 712.4); (1185.0, 712.4), (1395.0, 712.4); (1395.0, 712.4), (1395.0, 477.4); (1395.0, 477.4), (1280.0, 477.4); (1280.0, 477.4), (1280.0, 307.4); (1280.0, 307.4), (970.0, 307.4); (970.0, 307.4), (970.0, 392.4); (970.0, 392.4), (800.0, 392.4); (800.0, 392.4), (800.0, 192.4); (800.0, 192.4), (835.0, 192.4); (835.0, 192.4), (835.0, 222.4); (835.0, 222.4), (885.0, 222.4); (885.0, 222.4), (885.0, -92.6); (885.0, -92.6), (915.0, -92.6); (915.0, -92.6), (915.0, 137.4); (915.0, 137.4), (1145.0, 137.4); (1145.0, 137.4), (1145.0, -97.6); (1145.0, -97.6), (1090.0, -97.6); (1090.0, -97.6), (1090.0, -167.6); (1090.0, -167.6), (980.0, -167.6); (980.0, -167.6), (980.0, -357.6); (980.0, -357.6), (690.0, -357.6); (690.0, -357.6), (690.0, -212.6); (690.0, -212.6), (560.0, -212.6); (560.0, -212.6), (560.0, -137.6); (560.0, -137.6), (450.0, -137.6); (450.0, -137.6), (450.0, -237.6); (450.0, -237.6), (520.0, -237.6); (520.0, -237.6), (520.0, -322.6); (520.0, -322.6), (350.0, -322.6); (350.0, -322.6), (350.0, -217.6); (350.0, -217.6), (320.0, -217.6); (320.0, -217.6), (320.0, -287.6); (320.0, -287.6), (190.0, -287.6); (190.0, -287.6), (190.0, -252.6); (190.0, -252.6), (60.0, -252.6); (60.0, -252.6), (59.7, -187.1); (59.7, -187.1), (-95.0, -187.6); (-95.0, -187.6), (-95.0, -252.6); (-95.0, -252.6), (-42.3, -217.5); (-42.3, -217.5), (12.9, -303.6); (12.9, -303.6), (-147.4, -409.1); (-147.4, -409.1), (-262.7, -249.0); (-262.7, -249.0), (-181.8, -186.6); (-181.8, -186.6), (-145.0, -242.6); (-145.0, -242.6), (-145.0, 32.4); (-145.0, 32.4), (-205.0, 32.4); (-205.0, 32.4), (-205.0, -22.6); (-205.0, -22.6), (-295.2, -22.2); (-295.2, -22.2), (-365.0, -92.6); (-365.0, -92.6), (-430.0, -27.6); (-430.0, -27.6), (-395.0, 7.4); (-395.0, 7.4), (-440.0, 52.4); (-440.0, 52.4), (-365.0, 127.4); (-365.0, 127.4), (-330.0, 92.4); (-330.0, 92.4), (-295.0, 127.9); (-295.0, 127.9), (-270.0, 102.4); (-270.0, 102.4), (-210.0, 163.4); (-210.0, 163.4), (-170.0, 122.4); (-170.0, 122.4), (-110.0, 122.4); (-110.0, 122.4), (-110.0, 142.4); (-110.0, 142.4), (-30.0, 142.4); (-30.0, 142.4), (-30.0, 62.4); (-30.0, 62.4), (-10.0, 62.4); (-10.0, 62.4), (-10.0, 102.4); (-10.0, 102.4), (105.0, 102.4); (105.0, 102.4), (105.0, 167.4); (105.0, 167.4), (10.0, 167.4); (10.0, 167.4), (10.0, 252.4); (10.0, 252.4), (175.0, 252.4); (175.0, 252.4), (175.0, 287.4); (175.0, 287.4), (280.0, 287.4); (280.0, 287.4), (280.0, 322.4); (280.0, 322.4), (106.0, 322.4); (106.0, 322.4), (104.5, 322.9); (104.5, 322.9), (55.0, 372.4); (55.0, 372.4), (180.0, 498.4); (180.0, 498.4), (245.0, 432.4); (245.0, 432.4), (260.0, 447.4); (260.0, 447.4), (70.0, 637.4); (70.0, 637.4), (10.0, 577.4); (10.0, 577.4), (45.0, 542.4); (45.0, 542.4), (-20.0, 477.4); (-20.0, 477.4), (-230.0, 477.4); (-230.0, 477.4), (-230.0, 622.4); (-230.0, 622.4), (-355.0, 497.4); (-355.0, 497.4), (-405.0, 547.4); (-405.0, 547.4), (-375.0, 577.4); (-375.0, 577.4), (-435.0, 637.4); (-435.0, 637.4), (-435.0, 817.4); (-435.0, 817.4), (-489.8, 817.3); (-489.8, 817.3), (-489.3, 747.6); (-489.3, 747.6), (-539.8, 747.8); (-539.8, 747.8), (-539.8, 668.0); (-539.8, 668.0), (-619.8, 668.0); (-619.8, 668.0), (-619.5, 617.6); (-619.5, 617.6), (-715.2, 617.7); (-715.2, 617.7), (-714.6, 507.5); (-714.6, 507.5), (-770.1, 507.9); (-770.1, 507.9), (-769.9, 442.6); (-769.9, 442.6), (-809.2, 442.8); (-809.2, 442.8), (-810.0, 312.4); (-810.0, 312.4), (-860.0, 312.4); (-860.0, 312.4), (-860.0, 237.4); (-860.0, 237.4), (-905.0, 237.4); (-905.0, 237.4), (-905.0, 143.4); (-905.0, 143.4), (-1015.0, 142.4); (-1015.0, 142.4), (-1015.0, 62.4); (-1015.0, 62.4), (-1425.0, 62.9); (-1425.0, 62.9), (-1425.0, 142.4); (-1425.0, 142.4), (-1330.0, 143.0); (-1330.0, 143.0), (-1330.0, 312.4); (-1330.0, 312.4), (-1430.0, 312.8); (-1430.0, 312.8), (-1430.0, 397.4); (-1430.0, 397.4), (-1515.0, 397.4); (-1515.0, 397.4), (-1515.0, 508.4); (-1515.0, 508.4), (-1365.0, 508.4); (-1365.0, 508.4), (-1365.0, 462.4); (-1365.0, 462.4), (-1234.3, 462.3); (-1234.3, 462.3), (-1235.0, 517.4); (-1235.0, 517.4), (-1315.0, 517.4); (-1315.0, 517.4), (-1315.0, 562.4); (-1315.0, 562.4), (-1420.0, 563.4); (-1420.0, 563.4), (-1420.0, 643.4); (-1420.0, 643.4), (-1265.0, 642.4); (-1265.0, 642.4), (-1265.0, 707.4); (-1265.0, 707.4), (-1345.0, 707.4); (-1345.0, 707.4), (-1345.0, 742.4); (-1345.0, 742.4), (-1635.0, 742.4); (-1635.0, 742.4), (-1635.0, 712.4); (-1635.0, 712.4), (-1545.0, 712.4); (-1545.0, 712.4), (-1520.0, 682.4); (-1520.0, 682.4), (-1520.0, 592.4); (-1520.0, 592.4), (-1555.0, 557.4); (-1555.0, 557.4), (-1670.0, 557.4); (-1670.0, 557.4), (-1695.0, 582.4); (-1695.0, 582.4), (-1695.0, 672.4); (-1695.0, 672.4), (-1760.0, 672.4); (-1760.0, 672.4), (-1760.0, 582.4); (-1760.0, 582.4), (-1785.0, 557.4); (-1785.0, 557.4), (-1915.0, 557.4); (-1915.0, 557.4), (-1950.0, 592.4); (-1950.0, 592.4), (-1950.0, 687.4); (-1950.0, 687.4), (-1925.0, 712.4); (-1925.0, 712.4), (-1830.0, 712.4); (-1830.0, 712.4), (-1830.0, 797.4); (-1830.0, 797.4), (-1865.0, 797.4); (-1865.0, 797.4), (-1865.0, 753.4); (-1865.0, 753.4), (-2020.0, 752.4); (-2020.0, 752.4), (-2020.0, 602.4); (-2020.0, 602.4), (-2265.0, 602.4); (-2265.0, 602.4), (-2265.0, 633.4); (-2265.0, 633.4), (-2365.0, 632.4); (-2365.0, 632.4), (-2365.0, 612.4); (-2365.0, 612.4), (-2665.0, 612.4); (-2665.0, 612.4), (-2665.0, 712.4); (-2665.0, 712.4), (-2480.0, 712.4); (-2480.0, 712.4), (-2480.0, 732.4); (-2480.0, 732.4), (-2265.0, 732.4); (-2265.0, 732.4), (-2265.0, 792.4); (-2265.0, 792.4), (-2400.0, 792.4); (-2400.0, 792.4), (-2400.0, 877.4); (-2400.0, 877.4), (-2210.0, 877.4); (-2210.0, 877.4), (-2210.0, 917.4); (-2210.0, 917.4), (-2110.0, 917.4); (-2110.0, 917.4), (-2110.0, 947.4); (-2110.0, 947.4), (-2190.0, 947.4); (-2190.0, 947.4), (-2190.0, 1027.4); (-2190.0, 1027.4), (-2085.0, 1027.4); (-2085.0, 1027.4), (-2085.0, 1127.4); (-2085.0, 1127.4), (-2250.0, 1292.4); (-2250.0, 1292.4), (-2215.0, 1327.4); (-2215.0, 1327.4), (-2175.0, 1327.4); (-2175.0, 1327.4), (-2350.0, 1502.4); (-2350.0, 1502.4), (-2350.0, 1647.4); (-2350.0, 1647.4), (-2215.0, 1647.4); (-2215.0, 1647.4), (-2215.0, 1468.4); (-2215.0, 1468.4), (-2125.0, 1377.4); (-2125.0, 1377.4), (-2124.0, 1418.4); (-2124.0, 1418.4), (-2090.0, 1452.4); (-2090.0, 1452.4), (-1890.0, 1252.4); (-1890.0, 1252.4), (-2015.0, 1127.4); (-2015.0, 1127.4), (-2015.0, 1027.4); (-2015.0, 1027.4), (-1780.0, 1027.4); (-1780.0, 1027.4), (-1780.0, 947.4); (-1780.0, 947.4), (-1920.0, 947.4); (-1920.0, 947.4), (-1920.0, 917.4); (-1920.0, 917.4), (-1680.0, 917.4); (-1680.0, 917.4), (-1680.0, 797.4); (-1680.0, 797.4), (-1760.0, 797.4); (-1760.0, 797.4), (-1760.0, 712.4); (-1760.0, 712.4), (-1695.0, 712.4); (-1695.0, 712.4), (-1695.0, 772.4); (-1695.0, 772.4), (-1680.0, 787.4); (-1680.0, 787.4), (-1550.0, 787.4); (-1550.0, 787.4), (-1535.0, 802.4); (-1535.0, 802.4), (-1535.0, 807.4); (-1347.2, 808.1), (-1535.0, 807.4); |] let targets_4 = Array.to_list [| (1154.5, 646.9); (1259.0, 772.4); (1298.5, 595.9); (-620.0, 592.4); (-339.5, 1158.4); (139.5, 1528.9); (343.0, 1779.9); (640.5, 1732.4); (15.5, 1736.9); (-233.5, 1533.4); (204.0, 1021.9); (177.5, 958.9); (856.5, 1062.4); (814.7, 1116.2); (416.5, 1150.4); (543.5, 872.4); (768.5, 158.4); (846.0, 205.9); (828.5, 330.9); (726.5, 351.9); (716.0, 249.9); |] let level_4 = Array.to_list [| (203.2, 350.6), (136.0, 265.4); (136.0, 265.4), (122.0, 282.4); (122.0, 282.4), (136.2, 369.6); (136.2, 369.6), (29.2, 381.6); (29.2, 381.6), (-2.8, 327.6); (-2.8, 327.6), (-122.8, 330.6); (-122.8, 330.6), (-130.2, 449.1); (-130.2, 449.1), (-70.8, 635.6); (-70.8, 635.6), (-95.8, 686.6); (-95.8, 686.6), (-369.0, 686.4); (-369.0, 686.4), (-375.0, 800.1); (-375.0, 800.1), (-355.8, 908.9); (-355.8, 908.9), (-290.2, 947.1); (-290.2, 947.1), (-155.0, 1140.4); (-155.0, 1140.4), (-186.2, 1318.1); (-186.2, 1318.1), (-229.2, 1345.1); (-229.2, 1345.1), (-416.2, 1234.1); (-416.2, 1234.1), (-480.2, 1251.1); (-480.2, 1251.1), (-502.2, 1078.1); (-502.2, 1078.1), (-641.2, 1065.1); (-641.2, 1065.1), (-702.0, 1018.4); (-702.0, 1018.4), (-520.2, 930.1); (-520.2, 930.1), (-438.2, 907.4); (-438.2, 907.4), (-453.8, 797.4); (-453.8, 797.4), (-444.0, 682.4); (-444.0, 682.4), (-515.0, 686.4); (-515.0, 686.4), (-531.0, 639.4); (-531.0, 639.4), (-501.8, 574.6); (-501.8, 574.6), (-426.0, 581.4); (-426.0, 581.4), (-383.0, 598.4); (-383.0, 598.4), (-251.0, 605.4); (-251.0, 605.4), (-227.8, 248.6); (-227.8, 248.6), (-98.8, 224.6); (-98.8, 224.6), (26.0, 237.4); (26.0, 237.4), (-2.0, 191.4); (-2.0, 191.4), (-18.0, 117.4); (-18.0, 117.4), (-7.8, 87.6); (-7.8, 87.6), (147.2, 81.6); (147.2, 81.6), (123.0, -29.6); (123.0, -29.6), (29.0, -109.6); (29.0, -109.6), (-22.8, -217.4); (-22.8, -217.4), (-245.0, -155.1); (-245.0, -155.1), (-347.4, 106.4); (-347.4, 106.4), (-379.8, 128.6); (-379.8, 128.6), (-401.2, 130.6); (-401.2, 130.6), (-359.8, 383.6); (-359.8, 383.6), (-407.8, 406.6); (-407.8, 406.6), (-417.8, 530.6); (-417.8, 530.6), (-509.8, 528.6); (-509.8, 528.6), (-594.8, 665.6); (-594.8, 665.6), (-662.0, 680.4); (-662.0, 680.4), (-690.0, 650.4); (-690.0, 650.4), (-700.0, 540.4); (-700.0, 540.4), (-594.0, 438.4); (-594.0, 438.4), (-585.0, 389.4); (-585.0, 389.4), (-531.0, 345.4); (-531.0, 345.4), (-465.8, 136.6); (-465.8, 136.6), (-504.8, 132.6); (-504.8, 132.6), (-577.8, 205.6); (-577.8, 205.6), (-612.8, 108.6); (-612.8, 108.6), (-528.0, -38.6); (-528.0, -38.6), (-398.0, -180.6); (-398.0, -180.6), (-305.8, -248.4); (-305.8, -248.4), (-409.0, -187.6); (-409.0, -187.6), (-550.0, -52.6); (-550.0, -52.6), (-733.8, 233.6); (-733.8, 233.6), (-781.0, 484.4); (-781.0, 484.4), (-802.8, 999.6); (-802.8, 999.6), (-730.0, 1155.4); (-730.0, 1155.4), (-632.0, 1235.4); (-632.0, 1235.4), (-509.0, 1417.4); (-509.0, 1417.4), (-287.0, 1430.4); (-287.0, 1430.4), (-225.0, 1414.4); (-225.0, 1414.4), (-34.0, 1431.4); (-34.0, 1431.4), (165.0, 1331.4); (165.0, 1331.4), (360.0, 1393.4); (360.0, 1393.4), (585.0, 1427.4); (585.0, 1427.4), (766.0, 1545.4); (766.0, 1545.4), (866.0, 1587.4); (866.0, 1587.4), (872.0, 1648.4); (872.0, 1648.4), (1128.0, 1635.4); (1128.0, 1635.4), (1245.0, 1566.4); (1245.0, 1566.4), (1330.0, 1422.4); (1330.0, 1422.4), (1539.0, 1144.4); (1539.0, 1144.4), (1603.0, 898.4); (1603.0, 898.4), (1624.0, 614.4); (1624.0, 614.4), (1559.0, 451.4); (1559.0, 451.4), (1467.0, 641.4); (1467.0, 641.4), (1511.0, 775.4); (1511.0, 775.4), (1425.0, 839.4); (1425.0, 839.4), (1401.0, 793.4); (1401.0, 793.4), (1267.0, 853.4); (1267.0, 853.4), (1137.0, 802.4); (1137.0, 802.4), (1068.0, 594.4); (1068.0, 594.4), (1226.0, 581.4); (1226.0, 581.4), (1229.0, 514.4); (1229.0, 514.4), (1296.0, 451.4); (1296.0, 451.4), (1367.0, 556.4); (1367.0, 556.4), (1432.0, 523.4); (1432.0, 523.4), (1462.0, 413.4); (1462.0, 413.4), (1254.0, 339.4); (1254.0, 339.4), (1226.0, 219.4); (1226.0, 219.4), (1108.0, 80.4); (1108.0, 80.4), (1051.0, -127.6); (1051.0, -127.6), (1008.0, -174.6); (1008.0, -174.6), (693.2, -110.4); (693.2, -110.4), (414.0, -277.6); (414.0, -277.6), (325.2, -382.4); (325.2, -382.4), (61.2, -244.4); (61.2, -244.4), (108.0, -158.6); (108.0, -158.6), (203.5, -59.6); (203.5, -59.6), (224.2, 77.6); (224.2, 77.6), (357.0, 19.4); (357.0, 19.4), (474.0, 17.4); (474.0, 17.4), (547.2, 33.6); (547.2, 33.6), (535.0, 181.4); (535.0, 181.4), (506.0, 261.4); (506.0, 261.4), (558.0, 306.4); (558.0, 306.4), (617.0, 222.4); (617.0, 222.4), (676.8, 63.6); (676.8, 63.6), (826.0, -0.6); (826.0, -0.6), (978.0, 146.4); (978.0, 146.4), (979.0, 343.4); (979.0, 343.4), (922.0, 401.4); (922.0, 401.4), (967.0, 564.4); (967.0, 564.4), (941.0, 582.4); (941.0, 582.4), (883.0, 562.4); (883.0, 562.4), (764.0, 637.4); (764.0, 637.4), (744.0, 679.4); (744.0, 679.4), (874.0, 916.4); (874.0, 916.4), (1035.0, 950.4); (1035.0, 950.4), (1033.0, 1074.4); (1033.0, 1074.4), (939.0, 1097.4); (939.0, 1097.4), (855.0, 1250.4); (855.0, 1250.4), (697.0, 1291.4); (697.0, 1291.4), (687.0, 1134.4); (687.0, 1134.4), (598.0, 1104.4); (598.0, 1104.4), (495.0, 1221.4); (495.0, 1221.4), (378.0, 1243.4); (378.0, 1243.4), (247.0, 1113.4); (247.0, 1113.4), (130.0, 1100.4); (130.0, 1100.4), (66.0, 979.4); (66.0, 979.4), (117.0, 818.4); (117.0, 818.4), (231.0, 686.4); (231.0, 686.4), (396.0, 599.4); (396.0, 599.4), (478.0, 420.4); (478.0, 420.4), (436.0, 376.4); (436.0, 376.4), (301.3, 391.7); (301.3, 391.7), (282.2, 340.6); (203.2, 350.6), (282.2, 340.6); (1303.0, -65.6), (1349.0, -26.6); (1349.0, -26.6), (1451.0, -23.6); (1451.0, -23.6), (1327.0, -170.6); (1303.0, -65.6), (1327.0, -170.6); (1073.0, -208.6), (1080.0, -244.6); (1080.0, -244.6), (950.0, -272.6); (950.0, -272.6), (897.0, -183.6); (1073.0, -208.6), (897.0, -183.6); (492.0, -467.6), (545.0, -456.6); (545.0, -456.6), (600.0, -517.6); (600.0, -517.6), (411.0, -539.6); (492.0, -467.6), (411.0, -539.6); (-361.0, 1645.4), (-297.0, 1666.4); (-297.0, 1666.4), (-293.0, 1506.4); (-293.0, 1506.4), (-452.0, 1480.4); (-361.0, 1645.4), (-452.0, 1480.4); (752.0, 1793.8), (817.0, 1812.8); (817.0, 1812.8), (870.0, 1698.8); (870.0, 1698.8), (762.0, 1693.8); (752.0, 1793.8), (762.0, 1693.8); (531.0, 1930.4), (691.0, 1901.4); (691.0, 1901.4), (729.0, 1838.4); (729.0, 1838.4), (563.0, 1805.4); (531.0, 1930.4), (563.0, 1805.4); (438.0, 1807.4), (490.0, 1812.4); (490.0, 1812.4), (521.0, 1681.4); (521.0, 1681.4), (424.0, 1629.4); (438.0, 1807.4), (424.0, 1629.4); (97.0, 1820.4), (221.0, 1921.4); (221.0, 1921.4), (207.0, 1767.4); (207.0, 1767.4), (143.0, 1737.4); (97.0, 1820.4), (143.0, 1737.4); (84.0, 1629.4), (211.0, 1692.4); (211.0, 1692.4), (224.0, 1601.4); (224.0, 1601.4), (101.0, 1585.4); (84.0, 1629.4), (101.0, 1585.4); (146.0, 1418.4), (232.0, 1498.4); (232.0, 1498.4), (277.0, 1480.4); (277.0, 1480.4), (287.0, 1435.4); (287.0, 1435.4), (180.0, 1394.4); (146.0, 1418.4), (180.0, 1394.4); (-6.0, 1561.4), (45.0, 1590.4); (45.0, 1590.4), (88.0, 1494.4); (88.0, 1494.4), (69.0, 1442.4); (69.0, 1442.4), (-32.0, 1494.4); (-6.0, 1561.4), (-32.0, 1494.4); (461.0, 1555.4), (554.0, 1598.8); (554.0, 1598.8), (564.0, 1487.4); (564.0, 1487.4), (501.0, 1470.4); (461.0, 1555.4), (501.0, 1470.4); (-144.0, 1571.4), (-62.0, 1577.4); (-62.0, 1577.4), (-95.0, 1495.4); (-95.0, 1495.4), (-135.0, 1495.4); (-144.0, 1571.4), (-135.0, 1495.4); (327.6, 1520.8), (392.6, 1551.8); (392.6, 1551.8), (441.6, 1464.8); (441.6, 1464.8), (333.6, 1449.8); (327.6, 1520.8), (333.6, 1449.8); (286.0, 1976.4), (329.0, 1988.4); (329.0, 1988.4), (392.0, 1868.4); (392.0, 1868.4), (278.0, 1856.4); (286.0, 1976.4), (278.0, 1856.4); (-171.0, 1807.4), (-34.0, 1874.4); (-34.0, 1874.4), (-30.0, 1824.4); (-30.0, 1824.4), (-148.4, 1724.4); (-171.0, 1807.4), (-148.4, 1724.4); (275.0, 1691.4), (366.0, 1651.4); (366.0, 1651.4), (368.0, 1619.4); (368.0, 1619.4), (288.0, 1577.4); (275.0, 1691.4), (288.0, 1577.4); (-120.0, 1679.4), (-96.0, 1700.4); (-96.0, 1700.4), (-42.0, 1630.4); (-42.0, 1630.4), (-116.0, 1624.4); (-120.0, 1679.4), (-116.0, 1624.4); (-247.0, 1746.4), (-209.0, 1765.4); (-209.0, 1765.4), (-176.0, 1652.4); (-176.0, 1652.4), (-252.0, 1651.4); (-247.0, 1746.4), (-252.0, 1651.4); (620.0, 1639.4), (691.0, 1660.4); (691.0, 1660.4), (724.0, 1586.4); (724.0, 1586.4), (616.0, 1516.4); (620.0, 1639.4), (616.0, 1516.4); (1792.8, 943.1), (1771.5, 1082.0); (1771.5, 1082.0), (1737.0, 1216.2); (1737.0, 1216.2), (1689.9, 1344.8); (1689.9, 1344.8), (1630.9, 1467.1); (1630.9, 1467.1), (1560.8, 1582.6); (1560.8, 1582.6), (1480.2, 1690.4); (1480.2, 1690.4), (1389.8, 1789.8); (1389.8, 1789.8), (1290.4, 1880.2); (1290.4, 1880.2), (1182.6, 1960.8); (1182.6, 1960.8), (1067.1, 2030.9); (1067.1, 2030.9), (944.8, 2089.9); (944.8, 2089.9), (816.2, 2137.0); (816.2, 2137.0), (682.0, 2171.5); (682.0, 2171.5), (543.1, 2192.8); (543.1, 2192.8), (400.0, 2200.0); (400.0, 2200.0), (256.9, 2192.8); (256.9, 2192.8), (118.0, 2171.5); (118.0, 2171.5), (-16.2, 2137.0); (-16.2, 2137.0), (-144.8, 2089.9); (-144.8, 2089.9), (-267.1, 2030.9); (-267.1, 2030.9), (-382.6, 1960.8); (-382.6, 1960.8), (-490.4, 1880.2); (-490.4, 1880.2), (-589.8, 1789.8); (-589.8, 1789.8), (-680.2, 1690.4); (-680.2, 1690.4), (-760.8, 1582.6); (-760.8, 1582.6), (-830.9, 1467.1); (-830.9, 1467.1), (-889.9, 1344.8); (-889.9, 1344.8), (-937.0, 1216.2); (-937.0, 1216.2), (-971.5, 1082.0); (-971.5, 1082.0), (-992.8, 943.1); (-992.8, 943.1), (-1000.0, 800.0); (-1000.0, 800.0), (-992.8, 656.9); (-992.8, 656.9), (-971.5, 518.0); (-971.5, 518.0), (-937.0, 383.8); (-937.0, 383.8), (-889.9, 255.2); (-889.9, 255.2), (-830.9, 132.9); (-830.9, 132.9), (-760.8, 17.4); (-760.8, 17.4), (-680.2, -90.4); (-680.2, -90.4), (-589.8, -189.8); (-589.8, -189.8), (-490.4, -280.2); (-490.4, -280.2), (-382.6, -360.8); (-382.6, -360.8), (-267.1, -430.9); (-267.1, -430.9), (-144.8, -489.9); (-144.8, -489.9), (-16.2, -537.0); (-16.2, -537.0), (118.0, -571.5); (118.0, -571.5), (256.9, -592.8); (256.9, -592.8), (400.0, -600.0); (400.0, -600.0), (543.1, -592.8); (543.1, -592.8), (682.0, -571.5); (682.0, -571.5), (816.2, -537.0); (816.2, -537.0), (944.8, -489.9); (944.8, -489.9), (1067.1, -430.9); (1067.1, -430.9), (1182.6, -360.8); (1182.6, -360.8), (1290.4, -280.2); (1290.4, -280.2), (1389.8, -189.8); (1389.8, -189.8), (1480.2, -90.4); (1480.2, -90.4), (1560.8, 17.4); (1560.8, 17.4), (1630.9, 132.9); (1630.9, 132.9), (1689.9, 255.2); (1689.9, 255.2), (1737.0, 383.8); (1737.0, 383.8), (1771.5, 518.0); (1771.5, 518.0), (1792.8, 656.9); (1792.8, 656.9), (1800.0, 800.0); (1792.8, 943.1), (1800.0, 800.0); (15.0, 1839.4), (14.0, 1924.4); (14.0, 1924.4), (98.0, 1904.4); (98.0, 1904.4), (37.0, 1832.4); (15.0, 1839.4), (37.0, 1832.4); (409.0, 1959.4), (469.0, 1963.4); (469.0, 1963.4), (481.0, 1887.4); (481.0, 1887.4), (447.0, 1881.4); (409.0, 1959.4), (447.0, 1881.4); (125.0, 1961.4), (163.0, 2017.4); (163.0, 2017.4), (223.0, 1991.4); (223.0, 1991.4), (156.0, 1947.4); (125.0, 1961.4), (156.0, 1947.4); (442.0, 832.4), (455.0, 818.4); (455.0, 818.4), (487.0, 805.4); (487.0, 805.4), (470.0, 706.4); (470.0, 706.4), (391.0, 699.4); (391.0, 699.4), (331.0, 753.4); (331.0, 753.4), (322.5, 820.4); (442.0, 832.4), (322.5, 820.4); (541.0, 1005.4), (530.0, 939.4); (530.0, 939.4), (469.0, 918.4); (469.0, 918.4), (448.0, 883.4); (448.0, 883.4), (353.0, 877.4); (353.0, 877.4), (334.0, 972.4); (334.0, 972.4), (433.0, 1038.4); (541.0, 1005.4), (433.0, 1038.4); (758.0, 965.4), (706.0, 863.4); (706.0, 863.4), (627.0, 888.4); (627.0, 888.4), (619.0, 912.4); (619.0, 912.4), (592.0, 938.4); (592.0, 938.4), (607.0, 1000.4); (607.0, 1000.4), (715.0, 1049.4); (758.0, 965.4), (715.0, 1049.4); (589.0, 809.4), (613.0, 832.4); (613.0, 832.4), (682.0, 799.4); (682.0, 799.4), (656.0, 728.4); (656.0, 728.4), (573.0, 702.4); (573.0, 702.4), (540.0, 706.4); (540.0, 706.4), (544.0, 800.4); (589.0, 809.4), (544.0, 800.4); (546.0, 582.4), (552.0, 533.4); (552.0, 533.4), (489.0, 501.4); (489.0, 501.4), (456.0, 595.4); (546.0, 582.4), (456.0, 595.4); (708.0, 665.4), (733.0, 615.4); (733.0, 615.4), (651.0, 586.4); (651.0, 586.4), (626.0, 618.4); (708.0, 665.4), (626.0, 618.4); (1883.8, 648.7), (1861.1, 500.3); (1861.1, 500.3), (1824.2, 357.1); (1824.2, 357.1), (1774.0, 219.8); (1774.0, 219.8), (1711.0, 89.1); (1711.0, 89.1), (1636.1, -34.1); (1636.1, -34.1), (1550.0, -149.2); (1550.0, -149.2), (1453.5, -255.4); (1453.5, -255.4), (1347.3, -351.9); (1347.3, -351.9), (1232.2, -438.0); (1232.2, -438.0), (1108.9, -512.9); (1108.9, -512.9), (978.3, -575.9); (978.3, -575.9), (841.0, -626.2); (841.0, -626.2), (697.7, -663.0); (697.7, -663.0), (549.3, -685.7); (549.3, -685.7), (396.6, -693.4); (396.6, -693.4), (243.8, -685.7); (243.8, -685.7), (95.4, -663.0); (95.4, -663.0), (-47.8, -626.2); (-47.8, -626.2), (-185.1, -575.9); (-185.1, -575.9), (-315.8, -512.9); (-315.8, -512.9), (-439.1, -438.0); (-439.1, -438.0), (-554.2, -351.9); (-554.2, -351.9), (-660.3, -255.4); (-660.3, -255.4), (-756.9, -149.2); (-756.9, -149.2), (-842.9, -34.1); (-842.9, -34.1), (-917.8, 89.1); (-917.8, 89.1), (-980.8, 219.8); (-980.8, 219.8), (-1031.1, 357.1); (-1031.1, 357.1), (-1068.0, 500.3); (-1068.0, 500.3), (-1090.6, 648.7); (-1090.6, 648.7), (-1098.4, 801.5); (-1098.4, 801.5), (-1090.6, 954.3); (-1090.6, 954.3), (-1068.0, 1102.7); (-1068.0, 1102.7), (-1031.1, 1245.9); (-1031.1, 1245.9), (-980.8, 1383.2); (-980.8, 1383.2), (-917.8, 1513.9); (-917.8, 1513.9), (-842.9, 1637.1); (-842.9, 1637.1), (-756.9, 1752.2); (-756.9, 1752.2), (-660.3, 1858.4); (-660.3, 1858.4), (-554.2, 1954.9); (-554.2, 1954.9), (-439.1, 2041.0); (-439.1, 2041.0), (-315.8, 2115.9); (-315.8, 2115.9), (-185.1, 2178.9); (-185.1, 2178.9), (-47.8, 2229.2); (-47.8, 2229.2), (95.4, 2266.0); (95.4, 2266.0), (243.8, 2288.7); (243.8, 2288.7), (396.6, 2296.4); (396.6, 2296.4), (549.3, 2288.7); (549.3, 2288.7), (697.7, 2266.0); (697.7, 2266.0), (841.0, 2229.2); (841.0, 2229.2), (978.3, 2178.9); (978.3, 2178.9), (1108.9, 2115.9); (1108.9, 2115.9), (1232.2, 2041.0); (1232.2, 2041.0), (1347.3, 1954.9); (1347.3, 1954.9), (1453.5, 1858.4); (1453.5, 1858.4), (1550.0, 1752.2); (1550.0, 1752.2), (1636.1, 1637.1); (1636.1, 1637.1), (1711.0, 1513.9); (1711.0, 1513.9), (1774.0, 1383.2); (1774.0, 1383.2), (1824.2, 1245.9); (1824.2, 1245.9), (1861.1, 1102.7); (1861.1, 1102.7), (1883.8, 954.3); (1883.8, 954.3), (1891.5, 801.5); (1883.8, 648.7), (1891.5, 801.5); |] let player_initial_pos_2 = [| 200.0; 190.0 |] let player_initial_pos_3 = [| 150.0; 120.0 |] let player_initial_pos_4 = [| 177.6; 224.4 |] type level = { player_initial_pos : float array; segments : segment list; targets : (float * float) list; } let levels = [| { player_initial_pos = player_initial_pos_2; segments = level_2; targets = targets_2; }; { player_initial_pos = player_initial_pos_3; segments = level_3; targets = targets_3; }; { player_initial_pos = player_initial_pos_4; segments = level_4; targets = targets_4; }; |] (* Main *) let () = let i = ref 0 in let level = levels.(!i) in (* Player *) let avatar = { cx = level.player_initial_pos.(0); cy = level.player_initial_pos.(1); r = 10.6; vx = 0.0; vy = 0.0; static = false; touched = false; } in (* Targets *) let to_circles targets = List.map (fun (cx, cy) -> { cx; cy; r = 9.6; vx = 0.0; vy = 0.0; static = true; touched = false; } ) targets in let circles = ref (to_circles level.targets) in let segments = ref level.segments in let gravity = 2.6 in (* Gravity *) let dt = 0.1 in let restitution = 0.6 in (* Coefficient of restitution (0.8 means 20% energy loss) *) let g_angle = ref (3.141592 /. 2.0) in (* Gravity angle *) (* Next Level *) let j = ref 0 in let next_level () = let n = Array.length levels in i := (!i + 1) mod n; let level = levels.(!i) in j := 0; g_angle := (3.141592 /. 2.0); circles := to_circles level.targets; segments := level.segments; avatar.cx <- level.player_initial_pos.(0); avatar.cy <- level.player_initial_pos.(1); avatar.vx <- 0.0; avatar.vy <- 0.0; in let ( += ) v a = v := !v +. a in let ( -= ) v a = v := !v -. a in (* Run the simulation *) let animate () = if !j > 160 then next_level (); (* Rotate the Gravity *) if keys.right then g_angle -= 0.032; if keys.left then g_angle += 0.032; let gx = (cos !g_angle) *. gravity in let gy = (sin !g_angle) *. gravity in let gravity = (gx, gy) in circles := List.filter (fun c -> not c.touched) !circles; let _circles = avatar :: !circles in (* Update Circles *) update_circles _circles !segments gravity dt restitution; update_circles _circles !segments gravity dt restitution; (* Display Background *) display_background (); (* Push Matrix *) Canvas.save ctx; let c = avatar in let cx = (int_of_float c.cx) in let cy = (int_of_float c.cy) in (* Zoom out if 'S' key is pressed *) let sc = if keys.s then 0.4 else 0.8 in (* Scale centered to the middle of the screen *) Canvas.translate ctx (width / 2) (height / 2); Canvas.scale ctx sc sc; Canvas.translate ctx (width / -2) (height / -2); (* Rotation centered to the middle of the screen *) Canvas.translate ctx (width / 2) (height / 2); Canvas.rotate ctx ((3.141592 /. 2.0) -. !g_angle); Canvas.translate ctx (width / -2) (height / -2); (* Translation to put the avatar in the middle of the screen *) Canvas.translate ctx ((width / 2) - (cx)) ((height / 2) - (cy)); (* Display Level *) display_level _circles !segments; (* Pop Matrix *) Canvas.restore ctx; (* Display Text *) let n = List.length !circles in if n > 0 then begin Canvas.font ctx "bold 12px Arial"; Canvas.fillStyle ctx black; Canvas.textBaseline ctx "top"; Canvas.textAlign ctx "right"; let s = Printf.sprintf "targets: %d" n in Canvas.fillText ctx s (width - 12) (10); end else begin if keys.n then (keys.n <- false; next_level ()); incr j; Canvas.font ctx "bold 16px Arial"; Canvas.textBaseline ctx "top"; Canvas.textAlign ctx "right"; let s = "Success!" in Canvas.fillStyle ctx black; Canvas.fillText ctx s (width - 17) (14); Canvas.fillStyle ctx green; Canvas.fillText ctx s (width - 16) (13); let s = "Press 'n' for next level" in Canvas.font ctx "bold 11px Arial"; Canvas.fillStyle ctx black; Canvas.textBaseline ctx "top"; Canvas.textAlign ctx "right"; Canvas.fillText ctx s (width - 16) (34); end; () in (* Event Listeners *) Canvas.addKeyEventListener Canvas.window "keydown" (ev_keychange KeyDown) true; Canvas.addKeyEventListener Canvas.window "keyup" (ev_keychange KeyUp) true; (* Animate at 26 frames by seconds *) let _ = Canvas.setInterval animate (1000/26) in () ;;