1
0
Fork 0

More work on new map screen

This commit is contained in:
Michaël Lemaire 2017-01-27 00:01:04 +01:00
parent acd99a2d66
commit d82f89aeb5
14 changed files with 199 additions and 121 deletions

View file

@ -226,10 +226,10 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.1771152"
inkscape:cx="1247.613"
inkscape:cy="542.95678"
inkscape:cx="1424.0698"
inkscape:cy="540.88968"
inkscape:document-units="mm"
inkscape:current-layer="layer5"
inkscape:current-layer="g7289"
showgrid="false"
units="px"
inkscape:snap-bbox="false"
@ -293,12 +293,6 @@
inkscape:groupmode="layer"
id="layer5"
inkscape:label="Zoom 3">
<circle
r="124.77647"
cy="142.875"
cx="291.83255"
id="circle4569"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#424242;stroke-width:0.752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;stroke-dashoffset:0" />
<circle
style="opacity:1;fill:url(#radialGradient4534);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;stroke-dashoffset:0"
id="path4518"
@ -309,7 +303,13 @@
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<circle
style="opacity:0.68800001;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#8d8d8d;stroke-width:0.08964333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
r="124.77647"
cy="142.875"
cx="291.83255"
id="circle4569"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#424242;stroke-width:0.752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;stroke-dashoffset:0" />
<circle
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#464646;stroke-width:0.08964333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path6993"
cx="291.83255"
cy="142.875"
@ -363,29 +363,38 @@
</g>
<g
id="g7289">
<use
height="100%"
width="100%"
transform="translate(54.628606)"
id="use6995"
xlink:href="#path6987"
y="0"
x="0" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path6997"
d="m 397.16236,142.53751 130.8253,0"
style="fill:none;fill-rule:evenodd;stroke:#8bbeff;stroke-width:1.36500001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
r="4.6404414"
cy="142.75548"
cx="397.16235"
id="path6999"
style="opacity:0.68800001;fill:#0f2c3f;fill-opacity:1;fill-rule:evenodd;stroke:#8bbeff;stroke-width:0.565;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<g
id="g4572"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/map/jumpzone.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<use
x="0"
y="0"
xlink:href="#path6987"
id="use6995"
transform="translate(54.628606)"
width="100%"
height="100%" />
<circle
style="opacity:1;fill:#0f2c3f;fill-opacity:1;fill-rule:evenodd;stroke:#8bbeff;stroke-width:0.565;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path6999"
cx="397.16235"
cy="142.75548"
r="4.6404414" />
</g>
</g>
<g
id="g7284">
id="g7284"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/map/state-unknown.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<circle
r="3.9959407"
cy="150.05988"
@ -418,7 +427,10 @@
d="m 401.15031,150.22836 1.78335,1.65025 2.68829,-3.35372"
id="path7294"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/map/state-clear.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<use
x="0"
y="0"
@ -436,7 +448,10 @@
width="100%"
height="100%" />
<g
id="g7323">
id="g7323"
inkscape:export-filename="/home/michael/workspace/perso/spacetac/out/assets/images/map/state-enemy.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<use
style=""
height="100%"

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -13,54 +13,19 @@ module SpaceTac.Game.Specs {
expect(result.length).toBe(2);
expect(result[0]).toEqual(new StarLink(universe.stars[0], universe.stars[1]));
expect(result[1]).toEqual(new StarLink(universe.stars[0], universe.stars[3]));
});
it("generates warp locations", () => {
var universe = new Universe();
universe.stars.push(new Star(universe, 0, 0));
universe.stars.push(new Star(universe, 1, 0));
universe.stars.push(new Star(universe, 1, 1));
universe.addLink(universe.stars[0], universe.stars[1]);
universe.addLink(universe.stars[0], universe.stars[2]);
var getWarps = (star: Star): StarLocation[] => {
var result: StarLocation[] = [];
star.locations.forEach((location: StarLocation) => {
if (location.type === StarLocationType.WARP) {
result.push(location);
}
});
return result;
};
expect(getWarps(universe.stars[0]).length).toBe(0);
expect(getWarps(universe.stars[1]).length).toBe(0);
expect(getWarps(universe.stars[2]).length).toBe(0);
universe.stars[0].generate();
expect(getWarps(universe.stars[0]).length).toBe(2);
expect(getWarps(universe.stars[1]).length).toBe(0);
expect(getWarps(universe.stars[2]).length).toBe(0);
universe.stars[1].generate();
expect(getWarps(universe.stars[0]).length).toBe(2);
expect(getWarps(universe.stars[1]).length).toBe(1);
expect(getWarps(universe.stars[2]).length).toBe(0);
universe.stars[2].generate();
var warps = getWarps(universe.stars[0]);
expect(warps.length).toBe(2);
expect(warps[0].jump_dest).toBe(universe.stars[2].locations[1]);
expect(warps[1].jump_dest).toBe(universe.stars[1].locations[1]);
warps = getWarps(universe.stars[1]);
expect(warps.length).toBe(1);
expect(warps[0].jump_dest).toBe(universe.stars[0].locations[2]);
warps = getWarps(universe.stars[2]);
expect(warps.length).toBe(1);
expect(warps[0].jump_dest).toBe(universe.stars[0].locations[1]);
expect(universe.stars[0].getLinkTo(universe.stars[1])).toEqual(universe.starlinks[0]);
expect(universe.stars[0].getLinkTo(universe.stars[2])).toBeNull();
expect(universe.stars[0].getLinkTo(universe.stars[3])).toEqual(universe.starlinks[1]);
expect(universe.stars[1].getLinkTo(universe.stars[0])).toEqual(universe.starlinks[0]);
expect(universe.stars[1].getLinkTo(universe.stars[2])).toBeNull();
expect(universe.stars[1].getLinkTo(universe.stars[3])).toBeNull();
expect(universe.stars[2].getLinkTo(universe.stars[0])).toBeNull();
expect(universe.stars[2].getLinkTo(universe.stars[1])).toBeNull();
expect(universe.stars[2].getLinkTo(universe.stars[3])).toBeNull();
expect(universe.stars[3].getLinkTo(universe.stars[0])).toEqual(universe.starlinks[1]);
expect(universe.stars[3].getLinkTo(universe.stars[1])).toBeNull();
expect(universe.stars[3].getLinkTo(universe.stars[2])).toBeNull();
});
});
}

View file

@ -77,15 +77,20 @@ module SpaceTac.Game {
// Base level for encounters in this system
level: number;
constructor(universe: Universe = null, x: number = 0, y: number = 0) {
constructor(universe: Universe = null, x = 0, y = 0, name = "") {
super();
this.universe = universe || new Universe();
this.x = x;
this.y = y;
this.radius = 0.1;
this.locations = [];
this.locations = [new StarLocation(this, StarLocationType.STAR, 0, 0)];
this.level = 1;
this.name = name;
}
jasmineToString(): string {
return `Star ${this.name}`;
}
// Get the distance to another star
@ -99,38 +104,22 @@ module SpaceTac.Game {
// Generate the contents of this star system
generate(random: RandomGenerator = new RandomGenerator()): void {
var location_count = random.throwInt(2, 10);
this.locations = this.generateLocations(location_count, random);
this.name = random.choice(Star.NAMES_POOL);
this.generateLocations(location_count, random);
}
// Generate points of interest (*count* doesn't include the star and warp locations)
generateLocations(count: number, random: RandomGenerator = new RandomGenerator()): StarLocation[] {
var result: StarLocation[] = [];
// Add the star
result.push(new StarLocation(this, StarLocationType.STAR, 0, 0));
// Add warp locations around the star
var links = this.getLinks();
links.forEach((link: StarLink) => {
var warp = this.generateOneLocation(StarLocationType.WARP, result, this.radius * 0.3, random);
// If there is an unbound warp location on destination sector, bind with it
var peer_star = link.getPeer(this);
var peer_location = peer_star.findUnboundWarp();
if (peer_location) {
peer_location.setJumpDestination(warp);
warp.setJumpDestination(peer_location);
}
result.push(warp);
});
// Add random locations
generateLocations(count: number, random = new RandomGenerator()): void {
while (count--) {
result.push(this.generateOneLocation(StarLocationType.PLANET, result, this.radius, random));
this.generateOneLocation(StarLocationType.PLANET, this.locations, this.radius * 0.2, this.radius * 0.7, random);
}
}
return result;
// Generate a warp location to another star (to be bound later)
generateWarpLocationTo(other: Star, random = new RandomGenerator()): StarLocation {
let fav_phi = Math.atan2(other.y - this.y, other.x - this.x);
var warp = this.generateOneLocation(StarLocationType.WARP, this.locations, this.radius * 0.8, this.radius * 1, random, fav_phi);
return warp;
}
// Get the number of links to other stars
@ -146,6 +135,32 @@ module SpaceTac.Game {
return result;
}
// Get the link to another star, null of not found
getLinkTo(other: Star): StarLink | null {
var result: StarLink | null = null;
this.universe.starlinks.forEach(link => {
if (link.isLinking(this, other)) {
result = link;
}
});
return result;
}
// Get the warp location to another star, null if not found
getWarpLocationTo(other: Star): StarLocation | null {
var result: StarLocation | null = null;
this.locations.forEach(location => {
if (location.type == StarLocationType.WARP && location.jump_dest && location.jump_dest.star == other) {
result = location;
}
});
return result;
}
// Find an unbound warp location to bind, null if none found
findUnboundWarp(): StarLocation {
var result: StarLocation = null;
@ -160,18 +175,20 @@ module SpaceTac.Game {
// Check if a location is far enough from all other ones
private checkMinDistance(loc: StarLocation, others: StarLocation[]): boolean {
return others.every((iloc: StarLocation): boolean => {
return iloc.getDistanceTo(loc) > this.radius * 0.1;
return iloc.getDistanceTo(loc) > this.radius * 0.15;
});
}
// Generate a single location
private generateOneLocation(type: StarLocationType, others: StarLocation[], radius: number, random: RandomGenerator): StarLocation {
private generateOneLocation(type: StarLocationType, others: StarLocation[], radius_min: number, radius_max: number, random: RandomGenerator, fav_phi: number | null = null): StarLocation {
do {
var x = (random.throw(2) - 1) * radius;
var y = (random.throw(2) - 1) * radius;
var result = new StarLocation(this, type, x, y);
var phi = fav_phi ? (fav_phi + random.throw(0.4) - 0.2) : random.throw(Math.PI * 2);
var r = random.throw(radius_max - radius_min) + radius_min;
var result = new StarLocation(this, type, r * Math.cos(phi), r * Math.sin(phi));
} while (!this.checkMinDistance(result, others));
this.locations.push(result);
return result;
}
}

View file

@ -33,5 +33,44 @@ module SpaceTac.Game.Specs {
var filtered = universe.filterCrossingLinks(result);
expect(filtered.length).toBe(5);
});
it("generates warp locations", () => {
var universe = new Universe();
universe.stars.push(new Star(universe, 0, 0, "0"));
universe.stars.push(new Star(universe, 1, 0, "1"));
universe.stars.push(new Star(universe, 1, 1, "2"));
universe.addLink(universe.stars[0], universe.stars[1]);
universe.addLink(universe.stars[0], universe.stars[2]);
var getWarps = (star: Star): StarLocation[] => {
var result: StarLocation[] = [];
star.locations.forEach((location: StarLocation) => {
if (location.type === StarLocationType.WARP) {
result.push(location);
}
});
return result;
};
expect(getWarps(universe.stars[0]).length).toBe(0);
expect(getWarps(universe.stars[1]).length).toBe(0);
expect(getWarps(universe.stars[2]).length).toBe(0);
universe.generateWarpLocations();
var warps = getWarps(universe.stars[0]);
expect(warps.length).toBe(2);
expect(warps[0].jump_dest.star).toBe(universe.stars[1]);
expect(warps[1].jump_dest.star).toBe(universe.stars[2]);
expect(universe.stars[0].getWarpLocationTo(universe.stars[1])).toBe(warps[0]);
expect(universe.stars[0].getWarpLocationTo(universe.stars[2])).toBe(warps[1]);
warps = getWarps(universe.stars[1]);
expect(warps.length).toBe(1);
expect(warps[0].jump_dest.star).toBe(universe.stars[0]);
expect(universe.stars[1].getWarpLocationTo(universe.stars[2])).toBeNull();
warps = getWarps(universe.stars[2]);
expect(warps.length).toBe(1);
expect(warps[0].jump_dest.star).toBe(universe.stars[0]);
});
});
}

View file

@ -17,7 +17,7 @@ module SpaceTac.Game {
this.stars = [];
this.starlinks = [];
this.radius = 50;
this.radius = 5;
}
// Generates a universe, with star systems and such
@ -27,6 +27,8 @@ module SpaceTac.Game {
var links = this.getPotentialLinks();
this.starlinks = this.filterCrossingLinks(links);
this.generateWarpLocations(random);
this.stars.forEach((star: Star) => {
star.generate(random);
});
@ -76,7 +78,7 @@ module SpaceTac.Game {
// Filter a list of potential links to avoid crossing ones
filterCrossingLinks(links: StarLink[]): StarLink[] {
var result : StarLink[] = [];
var result: StarLink[] = [];
links.forEach((link1: StarLink) => {
var crossed = false;
@ -93,6 +95,18 @@ module SpaceTac.Game {
return result;
}
// Generate warp locations for the links between stars
generateWarpLocations(random = new RandomGenerator()) {
this.starlinks.forEach(link => {
let warp1 = link.first.generateWarpLocationTo(link.second, random);
let warp2 = link.second.generateWarpLocationTo(link.first, random);
warp1.setJumpDestination(warp2);
warp2.setJumpDestination(warp1);
});
}
// Get the star nearest to another
getNearestTo(star: Star, others: Star[] = null): Star {
if (others === null) {
@ -105,7 +119,7 @@ module SpaceTac.Game {
var nearest: Star = null;
others.forEach((istar: Star) => {
if (istar !== star) {
var dist = star.getDistanceTo(istar);
var dist = star.getDistanceTo(istar);
if (dist < mindist) {
nearest = istar;
mindist = dist;

View file

@ -59,8 +59,12 @@ module SpaceTac.View {
this.loadImage("map/starsystem-background.png");
this.loadImage("map/zoom-in.png");
this.loadImage("map/zoom-out.png");
this.loadImage("map/star.png");
this.loadImage("map/planet.png");
this.loadImage("map/location-star.png");
this.loadImage("map/location-planet.png");
this.loadImage("map/location-warp.png");
this.loadImage("map/state-unknown.png");
this.loadImage("map/state-enemy.png");
this.loadImage("map/state-clear.png");
// Load ships
this.loadShip("scout");

View file

@ -12,26 +12,36 @@ module SpaceTac.View {
this.starsystem = starsystem;
let boundary = this.game.add.graphics(0, 0);
boundary.lineStyle(3, 0x424242);
boundary.drawCircle(0, 0, scale);
this.addChild(boundary);
// Show boundary
this.addCircle(starsystem.radius);
// Show locations
starsystem.locations.forEach(location => {
if (location.type == Game.StarLocationType.STAR) {
this.addImage(location.x, location.y, "map-star");
this.addImage(location.x, location.y, "map-location-star");
} else if (location.type == Game.StarLocationType.PLANET) {
let planet = this.addImage(location.x, location.y, "map-planet");
let planet = this.addImage(location.x, location.y, "map-location-planet");
planet.rotation = Math.atan2(location.y, location.x);
this.addCircle(Math.sqrt(location.x * location.x + location.y * location.y), 1);
} else if (location.type == Game.StarLocationType.WARP) {
let warp = this.addImage(location.x, location.y, "map-location-warp");
}
});
}
addImage(x: number, y: number, key: string): Phaser.Image {
let image = this.game.add.image(x * 0.5 / this.scale.x, y * 0.5 / this.scale.y, key);
let image = this.game.add.image(x / this.scale.x, y / this.scale.y, key);
image.anchor.set(0.5, 0.5);
this.addChild(image);
return image;
}
addCircle(radius, width = 3, color = 0x424242): Phaser.Graphics {
let circle = this.game.add.graphics(0, 0);
circle.lineStyle(width, color);
circle.drawCircle(0, 0, radius * 2 / this.scale.x);
this.addChild(circle);
return circle;
}
}
}

View file

@ -12,6 +12,7 @@ module SpaceTac.View {
// Star systems
group: Phaser.Group;
starsystems: StarSystemDisplay[] = [];
starlinks: Phaser.Graphics[] = [];
// Zoom level
zoom = 0;
@ -31,6 +32,18 @@ module SpaceTac.View {
this.group = new Phaser.Group(this.game);
this.add.existing(this.group);
this.starlinks = this.universe.starlinks.map(starlink => {
let loc1 = starlink.first.getWarpLocationTo(starlink.second);
let loc2 = starlink.second.getWarpLocationTo(starlink.first);
let result = new Phaser.Graphics(this.game);
result.lineStyle(0.005, 0x8bbeff);
result.moveTo(starlink.first.x - 0.5 + loc1.x, starlink.first.y - 0.5 + loc1.y);
result.lineTo(starlink.second.x - 0.5 + loc2.x, starlink.second.y - 0.5 + loc2.y);
return result;
});
this.starlinks.forEach(starlink => this.group.addChild(starlink));
this.starsystems = this.universe.stars.map(star => new StarSystemDisplay(this, star));
this.starsystems.forEach(starsystem => this.group.addChild(starsystem));
@ -63,8 +76,8 @@ module SpaceTac.View {
// Set the camera to center on a target, and to display a given span in height
setCamera(x: number, y: number, span: number) {
let scale = 1000 / span;
this.tweens.create(this.group.position).to({ x: 960 - x * scale, y: 540 - y * scale }).start();
this.tweens.create(this.group.scale).to({ x: scale, y: scale }).start();
this.tweens.create(this.group.position).to({ x: 960 - x * scale, y: 540 - y * scale }, 500, Phaser.Easing.Cubic.InOut).start();
this.tweens.create(this.group.scale).to({ x: scale, y: scale }, 500, Phaser.Easing.Cubic.InOut).start();
}
setZoom(level: number) {
@ -73,6 +86,7 @@ module SpaceTac.View {
this.setCamera(0, 0, this.universe.radius * 2);
this.zoom = 0;
} else if (level == 1) {
// TODO Zoom to next-jump accessible
this.setCamera(current_star.x, current_star.y, this.universe.radius * 0.5);
this.zoom = 1;
} else {