1
0
Fork 0

Added star system links generation

This commit is contained in:
Michaël Lemaire 2015-03-19 01:00:00 +01:00
parent 86b20ffd2b
commit 74d302b64c
5 changed files with 135 additions and 16 deletions

View file

@ -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;
}
}
}

View file

@ -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) {

View 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);
}
});
});
});
});
}

View file

@ -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);
});
});
}

View file

@ -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);
});