Added star system links generation
This commit is contained in:
parent
86b20ffd2b
commit
74d302b64c
|
@ -20,5 +20,25 @@ module SpaceTac.Game {
|
|||
isLinking(first: Star, second: Star) {
|
||||
return (this.first === first && this.second === second) || (this.first === second && this.second === first);
|
||||
}
|
||||
|
||||
// Get the length of a link
|
||||
getLength(): number {
|
||||
return this.first.getDistanceTo(this.second);
|
||||
}
|
||||
|
||||
// Check if this link crosses another
|
||||
isCrossing(other: StarLink): boolean {
|
||||
if (this.first === other.first || this.second === other.first || this.first === other.second || this.second === other.second) {
|
||||
return false;
|
||||
}
|
||||
var ccw = (a: Star, b: Star, c: Star): boolean => {
|
||||
return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x);
|
||||
};
|
||||
var cc1 = ccw(this.first, other.first, other.second);
|
||||
var cc2 = ccw(this.second, other.first, other.second);
|
||||
var cc3 = ccw(this.first, this.second, other.first);
|
||||
var cc4 = ccw(this.first, this.second, other.second);
|
||||
return cc1 !== cc2 && cc3 !== cc4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,40 +47,81 @@ module SpaceTac.Game {
|
|||
|
||||
// Generates a universe, with star systems and such
|
||||
generate(starcount: number = 50, random: RandomGenerator = new RandomGenerator()): void {
|
||||
this.stars = [];
|
||||
this.starlinks = [];
|
||||
this.stars = this.generateStars(starcount, random);
|
||||
|
||||
while (starcount) {
|
||||
var links = this.getPotentialLinks();
|
||||
this.starlinks = this.filterCrossingLinks(links);
|
||||
}
|
||||
|
||||
// Generate a given number of stars, not too crowded
|
||||
generateStars(count: number, random: RandomGenerator = new RandomGenerator()): Star[] {
|
||||
var result: Star[] = [];
|
||||
|
||||
while (count) {
|
||||
var x = random.throw() * this.radius * 2.0 - this.radius;
|
||||
var y = random.throw() * this.radius * 2.0 - this.radius;
|
||||
var star = new Star(this, x, y);
|
||||
|
||||
var nearest = this.getNearestTo(star);
|
||||
var nearest = this.getNearestTo(star, result);
|
||||
if (nearest && nearest.getDistanceTo(star) < this.radius * 0.1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.stars.push(star);
|
||||
result.push(star);
|
||||
|
||||
starcount--;
|
||||
count--;
|
||||
}
|
||||
|
||||
this.stars.forEach((first: Star) => {
|
||||
var second = this.getNearestTo(first);
|
||||
if (!this.areLinked(first, second)) {
|
||||
this.starlinks.push(new StarLink(first, second));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get a list of potential links between the stars
|
||||
getPotentialLinks(): StarLink[] {
|
||||
var result: StarLink[] = [];
|
||||
|
||||
this.stars.forEach((first: Star, idx1: number) => {
|
||||
this.stars.forEach((second: Star, idx2: number) => {
|
||||
if (idx1 < idx2) {
|
||||
if (first.getDistanceTo(second) < this.radius * 0.6) {
|
||||
result.push(new StarLink(first, second));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Filter a list of potential links to avoid crossing ones
|
||||
filterCrossingLinks(links: StarLink[]): StarLink[] {
|
||||
var result : StarLink[] = [];
|
||||
|
||||
links.forEach((link1: StarLink) => {
|
||||
var crossed = false;
|
||||
links.forEach((link2: StarLink) => {
|
||||
if (link1 !== link2 && link1.isCrossing(link2) && link1.getLength() >= link2.getLength()) {
|
||||
crossed = true;
|
||||
}
|
||||
});
|
||||
if (!crossed) {
|
||||
result.push(link1);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the star nearest to another
|
||||
getNearestTo(star: Star): Star {
|
||||
if (this.stars.length === 0) {
|
||||
getNearestTo(star: Star, others: Star[] = null): Star {
|
||||
if (others === null) {
|
||||
others = this.stars;
|
||||
}
|
||||
if (others.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
var mindist = this.radius * 2.0;
|
||||
var nearest: Star = null;
|
||||
this.stars.forEach((istar: Star) => {
|
||||
others.forEach((istar: Star) => {
|
||||
if (istar !== star) {
|
||||
var dist = star.getDistanceTo(istar);
|
||||
if (dist < mindist) {
|
||||
|
|
31
src/scripts/game/specs/StarLink.spec.ts
Normal file
31
src/scripts/game/specs/StarLink.spec.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||
|
||||
module SpaceTac.Game.Specs {
|
||||
"use strict";
|
||||
|
||||
describe("StarLink", () => {
|
||||
it("checks link intersection", () => {
|
||||
var star1 = new Star(null, 0, 0);
|
||||
var star2 = new Star(null, 0, 1);
|
||||
var star3 = new Star(null, 1, 0);
|
||||
var star4 = new Star(null, 1, 1);
|
||||
var link1 = new StarLink(star1, star2);
|
||||
var link2 = new StarLink(star1, star3);
|
||||
var link3 = new StarLink(star1, star4);
|
||||
var link4 = new StarLink(star2, star3);
|
||||
var link5 = new StarLink(star2, star4);
|
||||
var link6 = new StarLink(star3, star4);
|
||||
var links = [link1, link2, link3, link4, link5, link6];
|
||||
links.forEach((first: StarLink) => {
|
||||
links.forEach((second: StarLink) => {
|
||||
if (first !== second) {
|
||||
var expected = (first === link3 && second === link4) ||
|
||||
(first === link4 && second === link3);
|
||||
expect(first.isCrossing(second)).toBe(expected);
|
||||
expect(second.isCrossing(first)).toBe(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -42,9 +42,36 @@ module SpaceTac.Game.Specs {
|
|||
|
||||
it("generates star systems", () => {
|
||||
var universe = new Universe();
|
||||
universe.generate(31);
|
||||
var result = universe.generateStars(31);
|
||||
|
||||
expect(universe.stars.length).toBe(31);
|
||||
expect(result.length).toBe(31);
|
||||
});
|
||||
|
||||
it("lists potential links between star systems", () => {
|
||||
var universe = new Universe();
|
||||
universe.stars.push(new Star(universe, 0, 0));
|
||||
universe.stars.push(new Star(universe, 0, 1));
|
||||
universe.stars.push(new Star(universe, 1, 0));
|
||||
|
||||
var result = universe.getPotentialLinks();
|
||||
expect(result.length).toBe(3);
|
||||
expect(result[0]).toEqual(new StarLink(universe.stars[0], universe.stars[1]));
|
||||
expect(result[1]).toEqual(new StarLink(universe.stars[0], universe.stars[2]));
|
||||
expect(result[2]).toEqual(new StarLink(universe.stars[1], universe.stars[2]));
|
||||
});
|
||||
|
||||
it("filters out crossing links", () => {
|
||||
var universe = new Universe();
|
||||
universe.stars.push(new Star(universe, 0, 0));
|
||||
universe.stars.push(new Star(universe, 0, 1));
|
||||
universe.stars.push(new Star(universe, 1, 0));
|
||||
universe.stars.push(new Star(universe, 2, 2));
|
||||
|
||||
var result = universe.getPotentialLinks();
|
||||
expect(result.length).toBe(6);
|
||||
|
||||
var filtered = universe.filterCrossingLinks(result);
|
||||
expect(filtered.length).toBe(5);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ module SpaceTac.View {
|
|||
|
||||
this.universe.starlinks.forEach((link: Game.StarLink) => {
|
||||
var line = this.add.graphics(0, 0, this.stars);
|
||||
line.lineStyle(0.3, 0xFFFFFF);
|
||||
line.lineStyle(0.3, 0xA0A0A0);
|
||||
line.moveTo(link.first.x, link.first.y);
|
||||
line.lineTo(link.second.x, link.second.y);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue