Files
shanhe-puzzle/scripts/triangulate-holes.mjs
codex-bot 4845826deb
Shanhe source and offline package checks / verify (pull_request) Failing after 5s
feat: sync Shanhe 2.2 source and add remote package verification
2026-11-01 17:13:46 +08:00

11 lines
1.3 KiB
JavaScript

// Build-only triangulation: the game consumes static convex polygons, no library.
import earcut from 'earcut';import fs from 'node:fs';import assert from 'node:assert/strict';
const filename='src/maps.js',data=JSON.parse(fs.readFileSync(filename,'utf8').replace(/^window\.MAP_DATA=/,'').replace(/;\s*$/,''));
function inside([x,y],ring){let hit=false;for(let i=0,j=ring.length-1;i<ring.length;j=i++){const a=ring[i],b=ring[j];if((a[1]>y)!==(b[1]>y)&&x<(b[0]-a[0])*(y-a[1])/(b[1]-a[1])+a[0])hit=!hit;}return hit;}
let count=0;
for(const lv of data.levels)for(const region of lv.regions){if(!region.holes||!region.holes.length)continue;region.physics=[];let assigned=0;
for(const outer of region.rings){const holes=region.holes.filter(h=>inside(h[0],outer));assigned+=holes.length;if(!holes.length){region.physics.push(outer);continue;}const flat=earcut.flatten([outer,...holes]),indices=earcut(flat.vertices,flat.holes,2);assert.ok(earcut.deviation(flat.vertices,flat.holes,2,indices)<1e-8);
for(let i=0;i<indices.length;i+=3)region.physics.push(indices.slice(i,i+3).map(j=>[flat.vertices[j*2],flat.vertices[j*2+1]]));
}assert.equal(assigned,region.holes.length);count++;}
fs.writeFileSync(filename,'window.MAP_DATA='+JSON.stringify(data)+';\n');console.log('保留内嵌县市的环形碰撞区域:'+count+'块');