// isokit/nature: trees, hedges, shrubs. /// A tree with a round crown of radius r (m) standing at (x, y) of this sprite. fn tree_at(x, y, r) { let h = 1.4 + r * 0.6; this.ext_box(x - r, y - r, x + r, y + r, 0.0, h + r * 1.8); this.stem(x, y, 0.0, h, 0.7, "trunk"); let R = r * px() * 1.18; this.circle(x, y, h + r * 0.9, R, "leaf l"); this.circle(x, y, h + r * 0.9, R * 0.58, "leaf t", -R * 0.28, -R * 0.3); this } fn meta_tree() { #{ label: "Tree", category: "Nature", icon: "🌳", props: [ #{ key: "r", type: "float", def: 1.6, min: 0.5, max: 6.0, step: 0.1, label: "Crown radius (m)" } ] } } fn prefab_tree(o) { sprite().tree_at(0.0, 0.0, o.p.r); } fn meta_tree_row() { #{ label: "Row of trees", category: "Nature", icon: "🌲", props: [ #{ key: "w", type: "float", def: 30.0, min: 2.0, max: 500.0, step: 1.0, label: "Length (m)" }, #{ key: "spacing", type: "float", def: 6.0, min: 2.0, max: 30.0, step: 0.5, label: "Spacing (m)" }, #{ key: "r", type: "float", def: 1.5, min: 0.5, max: 6.0, step: 0.1, label: "Crown radius (m)" }, ] } } fn prefab_tree_row(o) { let p = o.p; let n = (p.w / p.spacing).floor().to_int() + 1; let step = if n > 1 { p.w / (n - 1) } else { 0.0 }; for i in 0..n { // one sprite per tree; small deterministic size variation sprite().tree_at(-p.w / 2.0 + i * step, 0.0, p.r * (0.85 + 0.3 * hash(i + p.w))); } } fn meta_hedge() { #{ label: "Hedge", category: "Nature", icon: "▬", props: [ #{ key: "w", type: "float", def: 10.0, min: 0.5, max: 300.0, step: 0.5, label: "Length (m)" }, #{ key: "d", type: "float", def: 0.6, min: 0.3, max: 3.0, step: 0.1, label: "Thickness (m)" }, #{ key: "h", type: "float", def: 1.4, min: 0.3, max: 4.0, step: 0.1, label: "Height (m)" }, ] } } fn prefab_hedge(o) { let p = o.p; sprite().box(-p.w / 2.0, -p.d / 2.0, p.w / 2.0, p.d / 2.0, 0.0, p.h, "hedge"); }