@where-stars-drift/core 1.0.0
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.
- package/LICENSE +20 -0
- package/README.md +143 -0
- package/dist/src/base/bounded-body.d.ts +8 -0
- package/dist/src/base/bounded-body.js +10 -0
- package/dist/src/base/celestial-body.d.ts +12 -0
- package/dist/src/base/celestial-body.js +11 -0
- package/dist/src/base/hoverable.d.ts +10 -0
- package/dist/src/base/hoverable.js +4 -0
- package/dist/src/base/massive-body.d.ts +8 -0
- package/dist/src/base/massive-body.js +10 -0
- package/dist/src/config/effects.d.ts +14 -0
- package/dist/src/config/effects.js +14 -0
- package/dist/src/config/grid.d.ts +10 -0
- package/dist/src/config/grid.js +10 -0
- package/dist/src/config/panel.d.ts +26 -0
- package/dist/src/config/panel.js +26 -0
- package/dist/src/config/simulation.d.ts +21 -0
- package/dist/src/config/simulation.js +23 -0
- package/dist/src/controllers/clan-controller.d.ts +7 -0
- package/dist/src/controllers/clan-controller.js +12 -0
- package/dist/src/controllers/debug-controller.d.ts +45 -0
- package/dist/src/controllers/debug-controller.js +82 -0
- package/dist/src/controllers/effects-controller.d.ts +17 -0
- package/dist/src/controllers/effects-controller.js +71 -0
- package/dist/src/controllers/hover-controller.d.ts +11 -0
- package/dist/src/controllers/hover-controller.js +107 -0
- package/dist/src/controllers/layer-controller.d.ts +16 -0
- package/dist/src/controllers/layer-controller.js +64 -0
- package/dist/src/controllers/physics-controller.d.ts +14 -0
- package/dist/src/controllers/physics-controller.js +152 -0
- package/dist/src/controllers/star-controller.d.ts +12 -0
- package/dist/src/controllers/star-controller.js +38 -0
- package/dist/src/controllers/starship-controller.d.ts +17 -0
- package/dist/src/controllers/starship-controller.js +58 -0
- package/dist/src/draw-debug-line.d.ts +9 -0
- package/dist/src/draw-debug-line.js +29 -0
- package/dist/src/entities/black-hole-factory.d.ts +15 -0
- package/dist/src/entities/black-hole-factory.js +23 -0
- package/dist/src/entities/black-hole-shapes.d.ts +9 -0
- package/dist/src/entities/black-hole-shapes.js +224 -0
- package/dist/src/entities/black-hole.d.ts +69 -0
- package/dist/src/entities/black-hole.js +210 -0
- package/dist/src/entities/clan-manager.d.ts +12 -0
- package/dist/src/entities/clan-manager.js +22 -0
- package/dist/src/entities/clans.d.ts +15 -0
- package/dist/src/entities/clans.js +76 -0
- package/dist/src/entities/comet.d.ts +27 -0
- package/dist/src/entities/comet.js +81 -0
- package/dist/src/entities/docking-point.d.ts +20 -0
- package/dist/src/entities/docking-point.js +22 -0
- package/dist/src/entities/fleet.d.ts +45 -0
- package/dist/src/entities/fleet.js +374 -0
- package/dist/src/entities/formations.d.ts +51 -0
- package/dist/src/entities/formations.js +340 -0
- package/dist/src/entities/meteor.d.ts +26 -0
- package/dist/src/entities/meteor.js +48 -0
- package/dist/src/entities/nebula.d.ts +18 -0
- package/dist/src/entities/nebula.js +43 -0
- package/dist/src/entities/orbit.d.ts +23 -0
- package/dist/src/entities/orbit.js +43 -0
- package/dist/src/entities/pulsar.d.ts +18 -0
- package/dist/src/entities/pulsar.js +41 -0
- package/dist/src/entities/ring.d.ts +13 -0
- package/dist/src/entities/ring.js +26 -0
- package/dist/src/entities/ringed-planet.d.ts +21 -0
- package/dist/src/entities/ringed-planet.js +68 -0
- package/dist/src/entities/sector-grid.d.ts +16 -0
- package/dist/src/entities/sector-grid.js +70 -0
- package/dist/src/entities/star-factory.d.ts +29 -0
- package/dist/src/entities/star-factory.js +47 -0
- package/dist/src/entities/star.d.ts +48 -0
- package/dist/src/entities/star.js +167 -0
- package/dist/src/entities/starship-classes.d.ts +0 -0
- package/dist/src/entities/starship-classes.js +2 -0
- package/dist/src/entities/starship.d.ts +91 -0
- package/dist/src/entities/starship.js +760 -0
- package/dist/src/entities/supernova.d.ts +26 -0
- package/dist/src/entities/supernova.js +54 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +19 -0
- package/dist/src/lib/energy-stream.d.ts +5 -0
- package/dist/src/lib/energy-stream.js +98 -0
- package/dist/src/lib/quadtree.d.ts +31 -0
- package/dist/src/lib/quadtree.js +124 -0
- package/dist/src/lib/simplified-stream.d.ts +6 -0
- package/dist/src/lib/simplified-stream.js +19 -0
- package/dist/src/types.d.ts +14 -0
- package/dist/src/types.js +1 -0
- package/dist/src/ui/black-holes-panel.d.ts +2 -0
- package/dist/src/ui/black-holes-panel.js +76 -0
- package/dist/src/ui/clans-panel.d.ts +2 -0
- package/dist/src/ui/clans-panel.js +20 -0
- package/dist/src/ui/debug-panel-controller.d.ts +41 -0
- package/dist/src/ui/debug-panel-controller.js +285 -0
- package/dist/src/ui/fleets-panel.d.ts +2 -0
- package/dist/src/ui/fleets-panel.js +127 -0
- package/dist/src/ui/formations-panel.d.ts +3 -0
- package/dist/src/ui/formations-panel.js +129 -0
- package/dist/src/ui/panel-config.d.ts +26 -0
- package/dist/src/ui/panel-config.js +26 -0
- package/dist/src/ui/ships-panel.d.ts +12 -0
- package/dist/src/ui/ships-panel.js +61 -0
- package/dist/src/ui/stars-panel.d.ts +2 -0
- package/dist/src/ui/stars-panel.js +120 -0
- package/dist/src/where-stars-drift.d.ts +71 -0
- package/dist/src/where-stars-drift.js +440 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +35 -0
- package/src/base/bounded-body.ts +14 -0
- package/src/base/celestial-body.ts +20 -0
- package/src/base/hoverable.ts +11 -0
- package/src/base/massive-body.ts +14 -0
- package/src/config/effects.ts +15 -0
- package/src/config/grid.ts +11 -0
- package/src/config/panel.ts +26 -0
- package/src/config/simulation.ts +25 -0
- package/src/controllers/clan-controller.ts +19 -0
- package/src/controllers/debug-controller.ts +112 -0
- package/src/controllers/effects-controller.ts +86 -0
- package/src/controllers/hover-controller.ts +128 -0
- package/src/controllers/layer-controller.ts +78 -0
- package/src/controllers/physics-controller.ts +173 -0
- package/src/controllers/star-controller.ts +51 -0
- package/src/controllers/starship-controller.ts +76 -0
- package/src/draw-debug-line.ts +37 -0
- package/src/entities/black-hole-factory.ts +28 -0
- package/src/entities/black-hole-shapes.ts +276 -0
- package/src/entities/black-hole.ts +246 -0
- package/src/entities/clan-manager.ts +33 -0
- package/src/entities/clans.ts +98 -0
- package/src/entities/comet.ts +102 -0
- package/src/entities/docking-point.ts +34 -0
- package/src/entities/fleet.ts +446 -0
- package/src/entities/formations.ts +423 -0
- package/src/entities/meteor.ts +59 -0
- package/src/entities/nebula.ts +50 -0
- package/src/entities/orbit.ts +53 -0
- package/src/entities/pulsar.ts +64 -0
- package/src/entities/ring.ts +42 -0
- package/src/entities/ringed-planet.ts +85 -0
- package/src/entities/sector-grid.ts +81 -0
- package/src/entities/star-factory.ts +59 -0
- package/src/entities/star.ts +222 -0
- package/src/entities/starship-classes.ts +1 -0
- package/src/entities/starship.ts +906 -0
- package/src/entities/supernova.ts +75 -0
- package/src/index.ts +24 -0
- package/src/lib/energy-stream.ts +127 -0
- package/src/lib/quadtree.ts +159 -0
- package/src/lib/simplified-stream.ts +28 -0
- package/src/types.ts +16 -0
- package/src/ui/black-holes-panel.ts +91 -0
- package/src/ui/clans-panel.ts +27 -0
- package/src/ui/debug-panel-controller.ts +339 -0
- package/src/ui/fleets-panel.ts +153 -0
- package/src/ui/formations-panel.ts +155 -0
- package/src/ui/panel-config.ts +26 -0
- package/src/ui/ships-panel.ts +85 -0
- package/src/ui/stars-panel.ts +146 -0
- package/src/where-stars-drift.ts +542 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2026 Volodymyr Lavrynovych
|
|
2
|
+
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
Proprietary and Confidential.
|
|
6
|
+
|
|
7
|
+
This software is the proprietary property of Volodymyr Lavrynovych ("Owner") and is protected by copyright laws and international treaty provisions. You are hereby granted a non-exclusive, non-transferable, limited license to use this software for personal, non-commercial purposes only, subject to the terms and conditions of this license.
|
|
8
|
+
|
|
9
|
+
You may not:
|
|
10
|
+
a) copy, modify, distribute, sell, or lease any part of the software;
|
|
11
|
+
b) reverse engineer or attempt to extract the source code of the software;
|
|
12
|
+
c) remove any copyright or other proprietary notices from the software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Where Stars Drift ✨
|
|
2
|
+
|
|
3
|
+
> A TypeScript canvas library for creating interactive space simulations with realistic physics, celestial bodies, and dynamic fleet behaviors.
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/@where-stars-drift/core)
|
|
7
|
+
|
|
8
|
+
Born from a simple starfield background, **Where Stars Drift** evolved into a complete 2D space simulation engine inspired by classics like Homeworld and Freelancer.
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
- **Celestial Bodies**: Multiple star types, pulsars, ringed planets, black holes with gravitational effects
|
|
13
|
+
- **Dynamic Entities**: Starships with AI behaviors, fleet formations, clans, and tactical movements
|
|
14
|
+
- **Visual Effects**: Nebulas, comets, meteors, supernovas, and energy streams
|
|
15
|
+
- **Physics Engine**: Real gravity simulation, collision detection, and spatial optimization via quadtree
|
|
16
|
+
- **Interactive**: Mouse-driven interactions, hover effects, and responsive animations
|
|
17
|
+
- **Framework Agnostic**: Pure canvas rendering with optional framework wrappers
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @where-stars-drift/core
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 🚀 Quick Start
|
|
26
|
+
|
|
27
|
+
### Vanilla JavaScript / TypeScript
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { WhereStarsDrift } from '@where-stars-drift/core';
|
|
31
|
+
|
|
32
|
+
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
|
|
33
|
+
|
|
34
|
+
const simulation = new WhereStarsDrift(canvas, {
|
|
35
|
+
starsCount: 1000,
|
|
36
|
+
interactive: true,
|
|
37
|
+
debug: false,
|
|
38
|
+
showCatalog: false
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
simulation.start();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 🏗️ Development
|
|
45
|
+
|
|
46
|
+
This project is a monorepo structured with NPM workspaces:
|
|
47
|
+
|
|
48
|
+
- `/packages/where-stars-drift`: The core, framework-agnostic library source code.
|
|
49
|
+
- `/packages/demo-app`: A Next.js application to demonstrate the library's features.
|
|
50
|
+
|
|
51
|
+
### Available Scripts
|
|
52
|
+
|
|
53
|
+
- `npm run dev`: Starts the Next.js development server for the demo app.
|
|
54
|
+
- `npm run build`: Compiles the TypeScript library (`@where-stars-drift/core`) into JavaScript and type definitions in `packages/where-stars-drift/dist`.
|
|
55
|
+
- `npm run build:app`: Builds the Next.js demo application for production.
|
|
56
|
+
- `npm run typecheck`: Runs a TypeScript check across the entire monorepo.
|
|
57
|
+
|
|
58
|
+
## 📦 Publishing
|
|
59
|
+
|
|
60
|
+
The NPM package published is `@where-stars-drift/core` from the `packages/where-stars-drift` directory.
|
|
61
|
+
|
|
62
|
+
To publish the library to npm:
|
|
63
|
+
|
|
64
|
+
1. **Build the library**: Ensure the latest changes are compiled.
|
|
65
|
+
```bash
|
|
66
|
+
npm run build
|
|
67
|
+
```
|
|
68
|
+
The `prepublishOnly` script will automatically run this command before publishing.
|
|
69
|
+
|
|
70
|
+
2. **Publish to npm**:
|
|
71
|
+
```bash
|
|
72
|
+
cd packages/where-stars-drift
|
|
73
|
+
npm publish
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This process is automated via the `.github/workflows/npm-publish.yml` workflow when a new version tag is pushed.
|
|
77
|
+
|
|
78
|
+
## 🌌 Features in Detail
|
|
79
|
+
|
|
80
|
+
### Stars
|
|
81
|
+
|
|
82
|
+
- **Regular Stars**: Twinkling stars with various colors
|
|
83
|
+
- **Pulsars**: Rotating stars with pulsing effects
|
|
84
|
+
- **Ringed Planets**: Planets with orbital rings
|
|
85
|
+
|
|
86
|
+
### Black Holes
|
|
87
|
+
|
|
88
|
+
- Multiple visual styles (spiral, singularity, accretion disk, etc.)
|
|
89
|
+
- Gravitational pull affecting nearby stars
|
|
90
|
+
- Star consumption with supernova effects
|
|
91
|
+
- Energy streams between black holes
|
|
92
|
+
|
|
93
|
+
### Starships
|
|
94
|
+
|
|
95
|
+
- Multiple ship classes (Fighter, Corvette, Frigate, Capital)
|
|
96
|
+
- AI behaviors (idle, traveling, docking, orbiting)
|
|
97
|
+
- Fleet formations (V-formation, line, defensive sphere, etc.)
|
|
98
|
+
- Clan system with different colors and behaviors
|
|
99
|
+
- Mouse interaction (ships flee from cursor)
|
|
100
|
+
|
|
101
|
+
### Physics
|
|
102
|
+
|
|
103
|
+
- Gravity simulation
|
|
104
|
+
- Collision detection via spatial quadtree
|
|
105
|
+
- Orbital mechanics
|
|
106
|
+
- Velocity and acceleration
|
|
107
|
+
|
|
108
|
+
## 🎯 Roadmap
|
|
109
|
+
|
|
110
|
+
- [ ] Performance optimizations
|
|
111
|
+
- [ ] More formation patterns
|
|
112
|
+
- [ ] Configurable color schemes
|
|
113
|
+
- [ ] Sound effects
|
|
114
|
+
- [ ] React/Vue/Angular wrappers
|
|
115
|
+
- [ ] Save/load simulation state
|
|
116
|
+
- [ ] WebGL rendering option
|
|
117
|
+
|
|
118
|
+
## 📄 License
|
|
119
|
+
|
|
120
|
+
Copyright © 2026 Volodymyr Lavrynovych. All Rights Reserved.
|
|
121
|
+
|
|
122
|
+
This software is proprietary and confidential. See [LICENSE](LICENSE) for details.
|
|
123
|
+
|
|
124
|
+
## 🤝 Contributing
|
|
125
|
+
|
|
126
|
+
This is a private repository. Contributions are by invitation only.
|
|
127
|
+
|
|
128
|
+
## 🌐 Links
|
|
129
|
+
|
|
130
|
+
- Website: [starsdrift.space](https://starsdrift.space)
|
|
131
|
+
- Organization: [@where-stars-drift](https://github.com/where-stars-drift)
|
|
132
|
+
- Issues: [GitHub Issues](https://github.com/where-stars-drift/where-stars-drift-core/issues)
|
|
133
|
+
|
|
134
|
+
## 🙏 Acknowledgments
|
|
135
|
+
|
|
136
|
+
Inspired by:
|
|
137
|
+
- Homeworld series
|
|
138
|
+
- Freelancer
|
|
139
|
+
- The beauty of the cosmos
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
*Dedicated to Victoria, the first black hole in this universe* 💫
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the abstract base class for all celestial bodies with physical boundaries.
|
|
3
|
+
*/
|
|
4
|
+
import { CelestialBody } from './celestial-body';
|
|
5
|
+
export declare abstract class BoundedBody extends CelestialBody {
|
|
6
|
+
boundingRadius: number;
|
|
7
|
+
constructor(x: number, y: number, boundingRadius: number);
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the abstract base class for all celestial bodies with physical boundaries.
|
|
3
|
+
*/
|
|
4
|
+
import { CelestialBody } from './celestial-body';
|
|
5
|
+
export class BoundedBody extends CelestialBody {
|
|
6
|
+
constructor(x, y, boundingRadius) {
|
|
7
|
+
super(x, y);
|
|
8
|
+
this.boundingRadius = boundingRadius;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the abstract base class for all celestial bodies.
|
|
3
|
+
*/
|
|
4
|
+
export declare abstract class CelestialBody {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
vx: number;
|
|
8
|
+
vy: number;
|
|
9
|
+
constructor(x: number, y: number);
|
|
10
|
+
abstract update(context: CanvasRenderingContext2D, ...args: any[]): void;
|
|
11
|
+
abstract draw(context: CanvasRenderingContext2D, ...args: any[]): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the abstract base class for all celestial bodies that have mass.
|
|
3
|
+
*/
|
|
4
|
+
import { BoundedBody } from './bounded-body';
|
|
5
|
+
export declare abstract class MassiveBody extends BoundedBody {
|
|
6
|
+
mass: number;
|
|
7
|
+
constructor(x: number, y: number, boundingRadius: number, mass: number);
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the abstract base class for all celestial bodies that have mass.
|
|
3
|
+
*/
|
|
4
|
+
import { BoundedBody } from './bounded-body';
|
|
5
|
+
export class MassiveBody extends BoundedBody {
|
|
6
|
+
constructor(x, y, boundingRadius, mass) {
|
|
7
|
+
super(x, y, boundingRadius);
|
|
8
|
+
this.mass = mass;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized configuration for visual effects in the simulation.
|
|
3
|
+
*/
|
|
4
|
+
export declare const EFFECTS_CONFIG: {
|
|
5
|
+
/**
|
|
6
|
+
* If true, renders the energy streams flowing between two interacting black holes.
|
|
7
|
+
*/
|
|
8
|
+
RENDER_INTER_HOLE_STREAMS: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* If true, renders the energy streams from stars that are being consumed by a black hole.
|
|
11
|
+
* This is computationally expensive and can be disabled for performance.
|
|
12
|
+
*/
|
|
13
|
+
RENDER_STAR_TO_HOLE_STREAMS: boolean;
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized configuration for visual effects in the simulation.
|
|
3
|
+
*/
|
|
4
|
+
export const EFFECTS_CONFIG = {
|
|
5
|
+
/**
|
|
6
|
+
* If true, renders the energy streams flowing between two interacting black holes.
|
|
7
|
+
*/
|
|
8
|
+
RENDER_INTER_HOLE_STREAMS: true,
|
|
9
|
+
/**
|
|
10
|
+
* If true, renders the energy streams from stars that are being consumed by a black hole.
|
|
11
|
+
* This is computationally expensive and can be disabled for performance.
|
|
12
|
+
*/
|
|
13
|
+
RENDER_STAR_TO_HOLE_STREAMS: true,
|
|
14
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized configuration for the sector grid.
|
|
3
|
+
*/
|
|
4
|
+
export const GRID_CONFIG = {
|
|
5
|
+
SECTOR_SIZE: 360,
|
|
6
|
+
LINE_COLOR: 'rgba(100, 120, 150, 0.2)',
|
|
7
|
+
LINE_WIDTH: 0.5,
|
|
8
|
+
FONT: '8px "Roboto Mono", monospace',
|
|
9
|
+
FONT_COLOR: 'rgba(100, 120, 150, 0.3)',
|
|
10
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const PANEL_CONFIG: {
|
|
2
|
+
X: number;
|
|
3
|
+
WIDTH: number;
|
|
4
|
+
HEIGHT_PERCENT: number;
|
|
5
|
+
HEADER_HEIGHT: number;
|
|
6
|
+
TAB_HEIGHT: number;
|
|
7
|
+
ROW_HEIGHT: number;
|
|
8
|
+
GROUP_HEADER_HEIGHT: number;
|
|
9
|
+
PADDING: number;
|
|
10
|
+
BG_COLOR: string;
|
|
11
|
+
BORDER_COLOR: string;
|
|
12
|
+
TEXT_COLOR: string;
|
|
13
|
+
ACCENT_COLOR: string;
|
|
14
|
+
TITLE_FONT: string;
|
|
15
|
+
TAB_FONT: string;
|
|
16
|
+
ROW_FONT: string;
|
|
17
|
+
GROUP_FONT: string;
|
|
18
|
+
SHIP_RENDER_SCALE: number;
|
|
19
|
+
SCROLL_SPEED: number;
|
|
20
|
+
TOGGLE_BUTTON: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
w: number;
|
|
24
|
+
h: number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const PANEL_CONFIG = {
|
|
2
|
+
X: 10,
|
|
3
|
+
WIDTH: 350,
|
|
4
|
+
HEIGHT_PERCENT: 0.5,
|
|
5
|
+
HEADER_HEIGHT: 40,
|
|
6
|
+
TAB_HEIGHT: 30,
|
|
7
|
+
ROW_HEIGHT: 25,
|
|
8
|
+
GROUP_HEADER_HEIGHT: 20,
|
|
9
|
+
PADDING: 10,
|
|
10
|
+
BG_COLOR: 'rgba(0, 0, 0, 0.75)',
|
|
11
|
+
BORDER_COLOR: '#555',
|
|
12
|
+
TEXT_COLOR: '#ddd',
|
|
13
|
+
ACCENT_COLOR: '#aaa',
|
|
14
|
+
TITLE_FONT: '14px "Roboto Mono", monospace',
|
|
15
|
+
TAB_FONT: '11px "Roboto Mono", monospace',
|
|
16
|
+
ROW_FONT: '12px "Roboto Mono", monospace',
|
|
17
|
+
GROUP_FONT: 'bold 12px "Roboto Mono", monospace',
|
|
18
|
+
SHIP_RENDER_SCALE: 1,
|
|
19
|
+
SCROLL_SPEED: 20,
|
|
20
|
+
TOGGLE_BUTTON: {
|
|
21
|
+
x: 15,
|
|
22
|
+
y: 5,
|
|
23
|
+
w: 120,
|
|
24
|
+
h: 22,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized configuration for the night sky simulation.
|
|
3
|
+
*/
|
|
4
|
+
export declare const SIMULATION_CONFIG: {
|
|
5
|
+
STARS_COUNT: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const DEBUG_CONFIG: {
|
|
8
|
+
SHOW_DEBUG_INFO: boolean;
|
|
9
|
+
SHOW_ENTITY_HOVER_INFO: boolean;
|
|
10
|
+
SHOW_STARSHIP_TARGET_LINE: boolean;
|
|
11
|
+
SHOW_INTER_HOLE_DISTANCE: boolean;
|
|
12
|
+
SHOW_FORMATION_TARGET_DOTS: boolean;
|
|
13
|
+
SHOW_CATALOG_PANEL: boolean;
|
|
14
|
+
SHOW_STARSHIP_CATALOG: boolean;
|
|
15
|
+
SHOW_FORMATION_CATALOG: boolean;
|
|
16
|
+
SHOW_CLAN_CATALOG: boolean;
|
|
17
|
+
SHOW_FLEET_CATALOG: boolean;
|
|
18
|
+
SHOW_STAR_CATALOG: boolean;
|
|
19
|
+
SHOW_BLACK_HOLE_CATALOG: boolean;
|
|
20
|
+
SHOW_QUADTREE: boolean;
|
|
21
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized configuration for the night sky simulation.
|
|
3
|
+
*/
|
|
4
|
+
// --- General Simulation ---
|
|
5
|
+
export const SIMULATION_CONFIG = {
|
|
6
|
+
STARS_COUNT: 468,
|
|
7
|
+
};
|
|
8
|
+
// --- Debugging ---
|
|
9
|
+
export const DEBUG_CONFIG = {
|
|
10
|
+
SHOW_DEBUG_INFO: true,
|
|
11
|
+
SHOW_ENTITY_HOVER_INFO: true, // Shows a detailed info panel on hover for individual entities
|
|
12
|
+
SHOW_STARSHIP_TARGET_LINE: true,
|
|
13
|
+
SHOW_INTER_HOLE_DISTANCE: true,
|
|
14
|
+
SHOW_FORMATION_TARGET_DOTS: false,
|
|
15
|
+
SHOW_CATALOG_PANEL: true,
|
|
16
|
+
SHOW_STARSHIP_CATALOG: true,
|
|
17
|
+
SHOW_FORMATION_CATALOG: true,
|
|
18
|
+
SHOW_CLAN_CATALOG: true,
|
|
19
|
+
SHOW_FLEET_CATALOG: true,
|
|
20
|
+
SHOW_STAR_CATALOG: true,
|
|
21
|
+
SHOW_BLACK_HOLE_CATALOG: true,
|
|
22
|
+
SHOW_QUADTREE: false,
|
|
23
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ClanManager } from '../entities/clan-manager';
|
|
2
|
+
export class ClanController {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.clanManager = new ClanManager();
|
|
5
|
+
}
|
|
6
|
+
getNextClan() {
|
|
7
|
+
return this.clanManager.getClanForNewFleet();
|
|
8
|
+
}
|
|
9
|
+
getClans() {
|
|
10
|
+
return this.clanManager.getClans();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the DebugController for managing and drawing debug visualizations.
|
|
3
|
+
*/
|
|
4
|
+
interface Point {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}
|
|
8
|
+
interface BodyWithId extends Point {
|
|
9
|
+
id: number | string;
|
|
10
|
+
}
|
|
11
|
+
export declare class DebugController {
|
|
12
|
+
private linesToDraw;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Resets the list of lines for the current frame.
|
|
16
|
+
*/
|
|
17
|
+
clear(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Registers a line to be drawn between two bodies, preventing duplicates.
|
|
20
|
+
* @param body1 The first body (source).
|
|
21
|
+
* @param body2 The second body (target).
|
|
22
|
+
* @param options Flags to control rendering.
|
|
23
|
+
*/
|
|
24
|
+
registerLine(body1: BodyWithId, body2: BodyWithId, options?: {
|
|
25
|
+
drawLine: boolean;
|
|
26
|
+
showDistance: boolean;
|
|
27
|
+
}): void;
|
|
28
|
+
/**
|
|
29
|
+
* Registers a directional line from a source to a simple point target.
|
|
30
|
+
* Duplicates are not checked here as the source guarantees uniqueness for its own target line.
|
|
31
|
+
* @param source The source body.
|
|
32
|
+
* @param target The target point.
|
|
33
|
+
*/
|
|
34
|
+
registerDirectionalLine(source: BodyWithId, target: Point, options?: {
|
|
35
|
+
drawLine: boolean;
|
|
36
|
+
showDistance: boolean;
|
|
37
|
+
}): void;
|
|
38
|
+
private drawDebugLineWithDistance;
|
|
39
|
+
/**
|
|
40
|
+
* Draws all registered lines for the current frame.
|
|
41
|
+
* @param ctx The canvas rendering context.
|
|
42
|
+
*/
|
|
43
|
+
draw(ctx: CanvasRenderingContext2D): void;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the DebugController for managing and drawing debug visualizations.
|
|
3
|
+
*/
|
|
4
|
+
export class DebugController {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.linesToDraw = new Map();
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Resets the list of lines for the current frame.
|
|
10
|
+
*/
|
|
11
|
+
clear() {
|
|
12
|
+
this.linesToDraw.clear();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Registers a line to be drawn between two bodies, preventing duplicates.
|
|
16
|
+
* @param body1 The first body (source).
|
|
17
|
+
* @param body2 The second body (target).
|
|
18
|
+
* @param options Flags to control rendering.
|
|
19
|
+
*/
|
|
20
|
+
registerLine(body1, body2, options = { drawLine: true, showDistance: true }) {
|
|
21
|
+
// Create a unique, sorted key to prevent duplicate lines (A-B vs B-A)
|
|
22
|
+
const ids = [body1.id.toString(), body2.id.toString()].sort();
|
|
23
|
+
const lineKey = ids.join('-');
|
|
24
|
+
if (!this.linesToDraw.has(lineKey)) {
|
|
25
|
+
this.linesToDraw.set(lineKey, {
|
|
26
|
+
source: { x: body1.x, y: body1.y },
|
|
27
|
+
target: { x: body2.x, y: body2.y },
|
|
28
|
+
options,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Registers a directional line from a source to a simple point target.
|
|
34
|
+
* Duplicates are not checked here as the source guarantees uniqueness for its own target line.
|
|
35
|
+
* @param source The source body.
|
|
36
|
+
* @param target The target point.
|
|
37
|
+
*/
|
|
38
|
+
registerDirectionalLine(source, target, options = { drawLine: true, showDistance: true }) {
|
|
39
|
+
const lineKey = `dir-${source.id}`;
|
|
40
|
+
this.linesToDraw.set(lineKey, { source, target, options });
|
|
41
|
+
}
|
|
42
|
+
drawDebugLineWithDistance(ctx, source, target, drawLine, showDistance) {
|
|
43
|
+
const dx = target.x - source.x;
|
|
44
|
+
const dy = target.y - source.y;
|
|
45
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
46
|
+
// Draw the dashed line if requested
|
|
47
|
+
if (drawLine) {
|
|
48
|
+
ctx.beginPath();
|
|
49
|
+
ctx.setLineDash([2, 4]);
|
|
50
|
+
ctx.moveTo(source.x, source.y);
|
|
51
|
+
ctx.lineTo(target.x, target.y);
|
|
52
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
|
|
53
|
+
ctx.lineWidth = 0.5;
|
|
54
|
+
ctx.stroke();
|
|
55
|
+
ctx.setLineDash([]);
|
|
56
|
+
}
|
|
57
|
+
// Draw the distance text if requested
|
|
58
|
+
if (showDistance) {
|
|
59
|
+
const midX = source.x + dx / 2;
|
|
60
|
+
const midY = source.y + dy / 2;
|
|
61
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
|
|
62
|
+
ctx.font = '10px "Roboto Mono", monospace';
|
|
63
|
+
ctx.textAlign = 'center';
|
|
64
|
+
ctx.textBaseline = 'bottom';
|
|
65
|
+
ctx.fillText(dist.toFixed(0), midX, midY - 2);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Draws all registered lines for the current frame.
|
|
70
|
+
* @param ctx The canvas rendering context.
|
|
71
|
+
*/
|
|
72
|
+
draw(ctx) {
|
|
73
|
+
if (this.linesToDraw.size === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
ctx.save();
|
|
77
|
+
this.linesToDraw.forEach(({ source, target, options }) => {
|
|
78
|
+
this.drawDebugLineWithDistance(ctx, source, target, options.drawLine, options.showDistance);
|
|
79
|
+
});
|
|
80
|
+
ctx.restore();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Supernova } from '../entities/supernova';
|
|
2
|
+
import { Star } from '../entities/star';
|
|
3
|
+
import { BlackHle } from '../entities/black-hole';
|
|
4
|
+
export declare class EffectsController {
|
|
5
|
+
private supernovas;
|
|
6
|
+
private meteors;
|
|
7
|
+
private meteorShowerCooldown;
|
|
8
|
+
private width;
|
|
9
|
+
private height;
|
|
10
|
+
constructor(width: number, height: number);
|
|
11
|
+
private getNewMeteorCooldown;
|
|
12
|
+
addSupernovas(newSupernovas: Supernova[]): void;
|
|
13
|
+
updateAndDrawSupernovas(ctx: CanvasRenderingContext2D): void;
|
|
14
|
+
private spawnMeteorShower;
|
|
15
|
+
updateAndDrawMeteors(ctx: CanvasRenderingContext2D): void;
|
|
16
|
+
drawStarToHoleStreams(ctx: CanvasRenderingContext2D, allStars: Star[], blackHoles: BlackHle[]): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Meteor, METEOR_CONFIG } from '../entities/meteor';
|
|
2
|
+
import { STAR_CONFIG } from '../entities/star';
|
|
3
|
+
import { EFFECTS_CONFIG } from '../config/effects';
|
|
4
|
+
import { drawSimpleStarStream } from '../lib/simplified-stream';
|
|
5
|
+
export class EffectsController {
|
|
6
|
+
constructor(width, height) {
|
|
7
|
+
this.supernovas = [];
|
|
8
|
+
this.meteors = [];
|
|
9
|
+
this.width = width;
|
|
10
|
+
this.height = height;
|
|
11
|
+
this.meteorShowerCooldown = this.getNewMeteorCooldown();
|
|
12
|
+
}
|
|
13
|
+
getNewMeteorCooldown() {
|
|
14
|
+
return Math.random() * METEOR_CONFIG.SHOWER_COOLDOWN_VARIANCE + METEOR_CONFIG.SHOWER_COOLDOWN_MIN;
|
|
15
|
+
}
|
|
16
|
+
addSupernovas(newSupernovas) {
|
|
17
|
+
this.supernovas.push(...newSupernovas);
|
|
18
|
+
}
|
|
19
|
+
updateAndDrawSupernovas(ctx) {
|
|
20
|
+
this.supernovas = this.supernovas.filter(nova => {
|
|
21
|
+
nova.update();
|
|
22
|
+
if (nova.isAlive()) {
|
|
23
|
+
nova.draw(ctx);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
spawnMeteorShower() {
|
|
30
|
+
const radiantX = Math.random() * this.width;
|
|
31
|
+
const radiantY = Math.random() * this.height * 0.5;
|
|
32
|
+
const baseAngle = Math.random() * Math.PI * 2;
|
|
33
|
+
const meteorCount = Math.random() * METEOR_CONFIG.COUNT_VARIANCE + METEOR_CONFIG.COUNT_MIN;
|
|
34
|
+
const showerColor = STAR_CONFIG.RARE_STAR_COLORS[Math.floor(Math.random() * STAR_CONFIG.RARE_STAR_COLORS.length)];
|
|
35
|
+
for (let i = 0; i < meteorCount; i++) {
|
|
36
|
+
const angle = baseAngle + (Math.random() - 0.5) * 0.3;
|
|
37
|
+
const speed = Math.random() * METEOR_CONFIG.SPEED_VARIANCE + METEOR_CONFIG.SPEED_MIN;
|
|
38
|
+
this.meteors.push(new Meteor(radiantX, radiantY, Math.cos(angle) * speed, Math.sin(angle) * speed, showerColor));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
;
|
|
42
|
+
updateAndDrawMeteors(ctx) {
|
|
43
|
+
this.meteorShowerCooldown--;
|
|
44
|
+
if (this.meteorShowerCooldown <= 0) {
|
|
45
|
+
this.spawnMeteorShower();
|
|
46
|
+
this.meteorShowerCooldown = this.getNewMeteorCooldown();
|
|
47
|
+
}
|
|
48
|
+
this.meteors = this.meteors.filter(meteor => {
|
|
49
|
+
meteor.update();
|
|
50
|
+
if (meteor.isAlive(this.width, this.height)) {
|
|
51
|
+
meteor.draw(ctx);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
drawStarToHoleStreams(ctx, allStars, blackHoles) {
|
|
58
|
+
if (!EFFECTS_CONFIG.RENDER_STAR_TO_HOLE_STREAMS)
|
|
59
|
+
return;
|
|
60
|
+
for (const star of allStars) {
|
|
61
|
+
for (const hole of blackHoles) {
|
|
62
|
+
const dx = hole.x - star.x;
|
|
63
|
+
const dy = hole.y - star.y;
|
|
64
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
65
|
+
if (dist < hole.radius + 50) {
|
|
66
|
+
drawSimpleStarStream(ctx, star, hole);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CelestialBody } from '../base/celestial-body';
|
|
2
|
+
export declare class HoverController {
|
|
3
|
+
private bodies;
|
|
4
|
+
constructor(bodies: CelestialBody[]);
|
|
5
|
+
update(mouse: {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
}, isMouseInside: boolean, debug: boolean): void;
|
|
9
|
+
private checkHoverState;
|
|
10
|
+
private updateHoverStates;
|
|
11
|
+
}
|