ascii-city 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/js/tui.js +35 -2
  2. package/js/walker.js +34 -1
  3. package/package.json +1 -1
package/js/tui.js CHANGED
@@ -610,6 +610,33 @@ export function run(opts = {}) {
610
610
  if (camMode === 0 && sim.player.mode === 'foot') { // crosshair
611
611
  scr.set(cols >> 1, rows >> 1, 43, cInt('#dce6f0'), -1);
612
612
  }
613
+
614
+ if (sim.player.mode === 'drive') { // ASCII speedometer dial, bottom-right
615
+ const car = sim.player.car;
616
+ const s = Math.min(1, Math.abs(car.speed) / 12);
617
+ const mph = Math.abs(Math.round(car.speed * 8));
618
+ const speedCol = f => f < 0.5 ? '#7ad97a' : f < 0.8 ? '#ffd75f' : '#ff5b5b';
619
+ const RY = 4, RX = RY * 2;
620
+ const cx = cols - RX - 3, cy = rows - 4;
621
+ for (let i = 0; i <= 12; i++) {
622
+ const f = i / 12;
623
+ const a = Math.PI * (1 - f);
624
+ const on = f <= s + 0.01;
625
+ scr.set(Math.round(cx + Math.cos(a) * RX), Math.round(cy - Math.sin(a) * RY),
626
+ i % 6 === 0 ? 111 : 46, cInt(on ? speedCol(f) : '#4a5160'), -1);
627
+ }
628
+ const na = Math.PI * (1 - s);
629
+ const nCos = Math.cos(na), nSin = Math.sin(na);
630
+ const gch = Math.abs(nCos) > 0.85 ? 45 : Math.abs(nSin) > 0.85 ? 124 : (nCos * nSin > 0 ? 47 : 92);
631
+ for (let t = 0.2; t <= 0.82; t += 0.08) {
632
+ scr.set(Math.round(cx + nCos * RX * t), Math.round(cy - nSin * RY * t), gch, cInt(speedCol(s)), -1);
633
+ }
634
+ scr.set(cx, cy, 79, cInt('#c8d0e0'), -1);
635
+ const txt = mph + ' MPH';
636
+ for (let k = 0; k < txt.length; k++) {
637
+ scr.set(cx - (txt.length >> 1) + k, cy + 1, txt.charCodeAt(k), cInt(speedCol(s)), -1);
638
+ }
639
+ }
613
640
  }
614
641
 
615
642
  // --- boot ---
@@ -625,7 +652,13 @@ export function run(opts = {}) {
625
652
  c.heading = h; c.speed = 0; c.npc = true; c.police = pol;
626
653
  if (pol) c.color = '#e8e8f0';
627
654
  };
628
- put(sim.cars[0], 6, -1.2, P.heading + Math.PI / 2, false); // side-on
655
+ if (process.env.ASCII_CITY_DRIVE) {
656
+ const c = sim.cars[0];
657
+ c.x = P.x; c.z = P.z; c.heading = P.heading; c.npc = false; c.police = false;
658
+ c.speed = Number(process.env.ASCII_CITY_DRIVE) || 9;
659
+ P.mode = 'drive'; P.car = c;
660
+ }
661
+ if (!process.env.ASCII_CITY_DRIVE) put(sim.cars[0], 6, -1.2, P.heading + Math.PI / 2, false); // side-on
629
662
  put(sim.cars[1], 10, 1.2, P.heading + Math.PI, true); // cop, facing us
630
663
  sim.peds[0].x = P.x + cy * 4 + px * 2.4; sim.peds[0].z = P.z + sy * 4 + pz * 2.4;
631
664
  sim.peds[1].x = P.x + cy * 6 - px * 2.6; sim.peds[1].z = P.z + sy * 6 - pz * 2.6;
@@ -639,7 +672,7 @@ export function run(opts = {}) {
639
672
  const hud = () => {
640
673
  const P = sim.player;
641
674
  const stars = (sim.police && P.wanted) ? ' WANTED ' + '*'.repeat(P.wanted) : '';
642
- const speedo = P.mode === 'drive' ? ' ' + Math.abs(Math.round(P.car.speed * 8)) + ' MPH' : '';
675
+ const speedo = '';
643
676
  const gps = sim.missions ? sim.gpsDir() : null;
644
677
  const missionTxt = (sim.missions && sim.mission)
645
678
  ? ` [${sim.mission.stage === 'pickup' ? 'PICKUP' : 'DELIVER'}${gps ? ' ' + gps.dir + ' ' + gps.dist : ''}]`
package/js/walker.js CHANGED
@@ -529,8 +529,41 @@ function render() {
529
529
  if (camMode === 0 && sim.player.mode === 'foot') { // crosshair
530
530
  atlas.draw(ctx, '+', '#dce6f0', cols >> 1, rows >> 1);
531
531
  }
532
+
533
+ if (sim.player.mode === 'drive') drawSpeedo(cols, rows);
532
534
  }
533
535
 
536
+ // ASCII speedometer dial: arc of ticks lighting up with speed, rotating needle.
537
+ function speedCol(s) { return s < 0.5 ? '#7ad97a' : s < 0.8 ? '#ffd75f' : '#ff5b5b'; }
538
+ function drawSpeedo(cols, rows) {
539
+ const car = sim.player.car;
540
+ const s = Math.min(1, Math.abs(car.speed) / 12);
541
+ const mph = Math.abs(Math.round(car.speed * 8));
542
+ const RY = Math.max(7, Math.round(rows * 0.11)), RX = Math.round(RY * atlas.ch / atlas.cw);
543
+ const cx = cols - RX - 4, cy = rows - 5;
544
+ for (let i = 0; i <= 12; i++) {
545
+ const f = i / 12;
546
+ const a = Math.PI * (1 - f);
547
+ const on = f <= s + 0.01;
548
+ atlas.draw(ctx, i % 6 === 0 ? 'o' : '.',
549
+ on ? speedCol(f) : '#4a5160',
550
+ Math.round(cx + Math.cos(a) * RX), Math.round(cy - Math.sin(a) * RY));
551
+ }
552
+ const na = Math.PI * (1 - s);
553
+ const nCos = Math.cos(na), nSin = Math.sin(na);
554
+ const g = Math.abs(nCos) > 0.85 ? '-' : Math.abs(nSin) > 0.85 ? '|' : (nCos * nSin > 0 ? '/' : '\\');
555
+ for (let t = 0.2; t <= 0.82; t += 0.06) {
556
+ atlas.draw(ctx, g, speedCol(s), Math.round(cx + nCos * RX * t), Math.round(cy - nSin * RY * t));
557
+ }
558
+ atlas.draw(ctx, 'O', '#c8d0e0', cx, cy);
559
+ const txt = String(mph);
560
+ for (let k = 0; k < txt.length; k++) {
561
+ atlas.draw(ctx, txt[k], speedCol(s), cx - (txt.length >> 1) + k, cy + 2);
562
+ }
563
+ for (let k = 0; k < 3; k++) atlas.draw(ctx, 'MPH'[k], '#6a7284', cx - 1 + k, cy + 3);
564
+ }
565
+
566
+
534
567
  // --- minimap + hud ----------------------------------------------------------------
535
568
 
536
569
  function buildMini() {
@@ -586,7 +619,7 @@ function drawMini() {
586
619
  function updateHud() {
587
620
  const P = sim.player;
588
621
  const stars = (sim.police && P.wanted) ? ' WANTED ' + '*'.repeat(P.wanted) : '';
589
- const speedo = P.mode === 'drive' ? Math.abs(Math.round(P.car.speed * 8)) + ' MPH ' : '';
622
+ const speedo = '';
590
623
  const gps = sim.missions ? sim.gpsDir() : null;
591
624
  const missionTxt = (sim.missions && sim.mission)
592
625
  ? ` [${sim.mission.stage === 'pickup' ? 'PICKUP' : 'DELIVER'}${gps ? ' ' + gps.dir + ' ' + gps.dist : ''}]`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ascii-city",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "An INFINITE seeded ASCII cyberpunk city you can walk around and drive in, right in your terminal (or browser). GTA before GTA 6, in glyphs.",
5
5
  "type": "module",
6
6
  "bin": {