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_brawler/Stickman.ml.html
Source file Stickman.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(* 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. *) open Playground open Basics (* float arithmetics *) (* See Stickman.mli *) type limb = number * number type pose = { lean : number; front_arm : limb; back_arm : limb; front_leg : limb; back_leg : limb } let stand = { lean = 0.; front_arm = (15., 30.); back_arm = (-15., 10.); front_leg = (8., 0.); back_leg = (-8., 0.) } let lerp (a : pose) (b : pose) (t : number) : pose = let n x y = x + ((y - x) * t) in let l (x1, x2) (y1, y2) = (n x1 y1, n x2 y2) in { lean = n a.lean b.lean; front_arm = l a.front_arm b.front_arm; back_arm = l a.back_arm b.back_arm; front_leg = l a.front_leg b.front_leg; back_leg = l a.back_leg b.back_leg } let at (keys : (int * pose) list) (frame : int) : pose = let rec go l = match l with | (f1, p1) :: ((f2, p2) :: _ as rest) -> if frame <= f1 then p1 else if frame < f2 then lerp p1 p2 (float_of_int (frame -.. f1) / float_of_int (f2 -.. f1)) else go rest | [ (_, p) ] -> p | [] -> stand in go keys (* a limb's direction: from straight down, positive forward *) let dir (a : number) : number * number = (sin (a * pi / 180.), -.cos (a * pi / 180.)) let plus (x, y) k (dx, dy) = (x + (k * dx), y + (k * dy)) (* the joints, for a figure [h] high facing right, its lowest foot on * (0, 0): hip, shoulder, head's center, and each limb's middle joint * and end *) type joints = { hip : number * number; shoulder : number * number; head : number * number; limbs : ((number * number) * (number * number) * (number * number)) list; (* front arm, back arm, front leg, back leg: start, joint, end *) } let joints (h : number) (p : pose) : joints = let hip = (0., 0.) in let shoulder = plus hip (0.3 * h) (sin (p.lean * pi / 180.), cos (p.lean * pi / 180.)) in let head = plus shoulder (0.11 * h) (sin (p.lean * pi / 180.), cos (p.lean * pi / 180.)) in let limb start len (a1, a2) = let j = plus start len (dir a1) in (start, j, plus j len (dir a2)) in let limbs = [ limb shoulder (0.17 * h) p.front_arm; limb shoulder (0.17 * h) p.back_arm; limb hip (0.25 * h) p.front_leg; limb hip (0.25 * h) p.back_leg ] in let lowest = List.fold_left (fun m (_, (_, jy), (_, ey)) -> Float.min m (Float.min jy ey)) 0. (List.filteri (fun i _ -> i >= 2) limbs) in let up (x, y) = (x, y - lowest) in { hip = up hip; shoulder = up shoulder; head = up head; limbs = List.map (fun (a, b, c) -> (up a, up b, up c)) limbs } let hand (h : number) (p : pose) : number * number = match (joints h p).limbs with (_, _, e) :: _ -> e | [] -> (0., 0.) let segment (color : color) (width : number) ((x0, y0) : number * number) ((x1, y1) : number * number) : shape = group [ rectangle color (Float.hypot (x1 - x0) (y1 - y0)) width |> rotate (atan2 (y1 - y0) (x1 - x0) * 180. / pi) |> move ((x0 + x1) / 2.) ((y0 + y1) / 2.); circle color (width / 2.) |> move x1 y1 ] let draw (color : color) (back : color) (h : number) (facing : number) (p : pose) : shape = let j = joints h p in let w = 0.055 * h in let flip (x, y) = (facing * x, y) in let limb c (a, b, e) = [ segment c w (flip a) (flip b); segment c w (flip b) (flip e) ] in match j.limbs with | [ fa; ba; fl; bl ] -> group (limb back ba @ limb back bl @ [ segment color (w * 1.3) (flip j.hip) (flip j.shoulder) ] @ limb color fl @ [ circle color (0.09 * h) |> move (fst (flip j.head)) (snd j.head) ] @ limb color fa) | _ -> group []
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>