package elm_playground_gamekits
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Genre kits for Playground games: platformers, racing, shoot 'em ups, fighting and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/elm_playground_gamekits.kit_isometric/Isometric.ml.html
Source file Isometric.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Isometric.mli *) open Playground open Basics (* float arithmetics *) type t = { (* where one unit of world x goes on the screen *) ax : number; ay : number; (* and one unit of z *) bx : number; by : number; (* and one unit of height, straight up *) up : number; (* the screen point the world's origin is drawn at *) ox : number; oy : number; (* the world point that sits at that origin *) fx : number; fz : number; } let make ~across:(ax, ay) ~along:(bx, by) ~up = { ax; ay; bx; by; up; ox = 0.; oy = 0.; fx = 0.; fz = 0. } let origin (ox : number) (oy : number) (v : t) : t = { v with ox; oy } let follow (fx : number) (fz : number) (v : t) : t = { v with fx; fz } (* the two lines the whole kit is *) let project (v : t) ((x, y, z) : number * number * number) : number * number = let x = x - v.fx and z = z - v.fz in (v.ox + (v.ax * x) + (v.bx * z), v.oy + (v.ay * x) + (v.by * z) + (v.up * y)) let at (v : t) (p : number * number * number) (s : shape) : shape = let sx, sy = project v p in s |> move sx sy let shadow (v : t) ((x, _y, z) : number * number * number) (s : shape) : shape = at v (x, 0., z) s (* the two lines run backwards, on the floor: a 2x2 system, whose * determinant is not zero as long as the two screen axes are not * parallel (a view worth looking at) *) let ground (v : t) ((sx, sy) : number * number) : number * number = let px = sx - v.ox and py = sy - v.oy in let det = (v.ax * v.by) - (v.ay * v.bx) in (v.fx + (((px * v.by) - (py * v.bx)) / det), v.fz + (((v.ax * py) - (v.ay * px)) / det)) (* The direction this projection flattens to nothing: the one that * solves both lines at once, which is what "no perspective" buys -- * one vector for the whole world instead of a ray per point. * * ax dx + bx dz = 0 -> dx = -(bx / ax) dz * ay dx + by dz + up dy = 0 -> dy = -(ay dx + by dz) / up * * taken with dz = -1, so that it points towards the eye (nearer is a * smaller z in every view a game builds with [along] pointing away). *) let toward_eye (v : t) : number * number * number = let dz = -1. in let dx = -.(v.bx / v.ax) * dz in let dy = -.((v.ay * dx) + (v.by * dz)) / v.up in (dx, dy, dz) (* how far from the eye, along that direction: the dot product with it, * negated so that bigger is farther *) let depth (v : t) ((x, y, z) : number * number * number) : number = let ex, ey, ez = toward_eye v in -.((x * ex) + (y * ey) + (z * ez)) let sorted (l : (number * shape) list) : shape list = List.map snd (List.sort (fun (a, _) (b, _) -> compare b a) l) let sight (v : t) ((x, y, z) : number * number * number) (plane : number) : (number * number) option = let ex, ey, ez = toward_eye v in (* how far along the line of sight the plane is; ez is -1, so this is * z - plane, positive when the plane is between the point and the eye *) let t = (plane - z) / ez in if t <= 0. then None else Some (x + (ex * t), y + (ey * t))
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>