Update gameplay

This commit is contained in:
schmelczerandras 2020-10-23 15:19:04 +02:00
parent 49c410d8ff
commit 23fa7646d6
10 changed files with 165 additions and 33 deletions

View file

@ -17,10 +17,11 @@ import {
Circle, Circle,
PlayerInformation, PlayerInformation,
CharacterTeam, CharacterTeam,
UpdatePlanetOwnershipCommand, UpdateGameState,
GameObject, GameObject,
Command, Command,
UpdateObjectMessage, UpdateObjectMessage,
OtherPlayerDirection,
} from 'shared'; } from 'shared';
import { getTimeInMilliseconds } from '../helper/get-time-in-milliseconds'; import { getTimeInMilliseconds } from '../helper/get-time-in-milliseconds';
import { BoundingBox } from '../physics/bounding-boxes/bounding-box'; import { BoundingBox } from '../physics/bounding-boxes/bounding-box';
@ -189,10 +190,42 @@ export class Player extends CommandReceiver {
); );
this.sendToPlayer( this.sendToPlayer(
new UpdatePlanetOwnershipCommand( new UpdateGameState(
PlanetPhysical.declaPlanetCount, PlanetPhysical.declaPlanetCount,
PlanetPhysical.redPlanetCount, PlanetPhysical.redPlanetCount,
PlanetPhysical.neutralPlanetCount, PlanetPhysical.neutralPlanetCount,
this.getOtherPlayers(),
),
);
}
private getOtherPlayers(): Array<OtherPlayerDirection> {
if (!this.character) {
return [];
}
const viewArea = calculateViewArea(this.center, this.aspectRatio, 0.9);
const bb = new BoundingBox();
bb.topLeft = viewArea.topLeft;
bb.size = viewArea.size;
const playersInViewArea = this.objects
.findIntersecting(bb)
.map((o) => o.gameObject)
.filter((g) => g instanceof PlayerCharacterPhysical);
const otherPlayers = this.players.filter(
(p) => playersInViewArea.indexOf(p.character!) < 0,
);
return otherPlayers.map(
(p) =>
new OtherPlayerDirection(
vec2.normalize(
vec2.create(),
vec2.subtract(vec2.create(), p.center, this.character!.center),
),
p.team,
), ),
); );
} }

View file

@ -145,7 +145,24 @@ body {
@include square(50px); @include square(50px);
border-radius: 1000px; border-radius: 1000px;
mask: url('../static/mask.svg'); mask-image: url('../static/mask.svg');
}
.other-player-arrow {
@include square($large-icon);
@media (max-width: $breakpoint) {
@include square($small-icon);
}
mask-image: url('../static/chevron.svg');
mask-size: contain;
&.decla {
background-color: $bright-decla;
}
&.red {
background-color: $bright-red;
}
} }
.planet-progress { .planet-progress {
@ -165,8 +182,10 @@ body {
height: $height; height: $height;
} }
border-radius: 100px;
overflow: hidden;
div:nth-child(1) { div:nth-child(1) {
border-radius: 100px 0 0 100px;
background: $bright-decla; background: $bright-decla;
} }
@ -175,7 +194,6 @@ body {
} }
div:nth-child(3) { div:nth-child(3) {
border-radius: 0 100px 100px 0;
background: $bright-red; background: $bright-red;
} }
} }

View file

@ -18,7 +18,8 @@ import {
SetAspectRatioActionCommand, SetAspectRatioActionCommand,
PlayerInformation, PlayerInformation,
PlayerDiedCommand, PlayerDiedCommand,
UpdatePlanetOwnershipCommand, UpdateGameState,
clamp,
} from 'shared'; } from 'shared';
import io from 'socket.io-client'; import io from 'socket.io-client';
import { KeyboardListener } from './commands/generators/keyboard-listener'; import { KeyboardListener } from './commands/generators/keyboard-listener';
@ -54,6 +55,7 @@ export class Game {
progressBar.appendChild(this.redPlanetCountElement); progressBar.appendChild(this.redPlanetCountElement);
} }
private arrowElements: Array<HTMLElement> = [];
private async setupCommunication(serverUrl: string): Promise<void> { private async setupCommunication(serverUrl: string): Promise<void> {
this.socket = io(serverUrl, { this.socket = io(serverUrl, {
reconnectionDelayMax: 10000, reconnectionDelayMax: 10000,
@ -74,7 +76,7 @@ export class Game {
navigator.vibrate(150); navigator.vibrate(150);
} }
this.overlay.appendChild(this.announcmentText); this.overlay.appendChild(this.announcmentText);
} else if (command instanceof UpdatePlanetOwnershipCommand) { } else if (command instanceof UpdateGameState) {
const all = command.declaCount + command.redCount + command.neutralCount; const all = command.declaCount + command.redCount + command.neutralCount;
this.declaPlanetCountElement.style.width = (command.declaCount / all) * 100 + '%'; this.declaPlanetCountElement.style.width = (command.declaCount / all) * 100 + '%';
this.neutralPlanetCountElement.style.width = this.neutralPlanetCountElement.style.width =
@ -90,6 +92,53 @@ export class Game {
this.overlay.appendChild(this.announcmentText); this.overlay.appendChild(this.announcmentText);
this.announcmentText.innerText = 'Red team won 🎉'; this.announcmentText.innerText = 'Red team won 🎉';
} }
this.arrowElements
.splice(command.otherPlayerDirections.length, this.arrowElements.length)
.forEach((e) => e.parentElement?.removeChild(e));
for (
let i = this.arrowElements.length;
i < command.otherPlayerDirections.length;
i++
) {
const element = document.createElement('div');
this.arrowElements.push(element);
this.overlay.appendChild(element);
}
this.arrowElements.forEach((e, i) => {
const direction = command.otherPlayerDirections[i].direction;
const team = command.otherPlayerDirections[i].team;
const angle = Math.atan2(direction.y, direction.x);
e.className = 'other-player-arrow ' + team;
const { width, height } = this.overlay.getBoundingClientRect();
const aspectRatio = width / height;
const directionRatio = direction.x / direction.y;
let deltaX: number, deltaY: number;
if (aspectRatio < Math.abs(directionRatio)) {
deltaX = (width / 2) * Math.sign(direction.x);
deltaY = deltaX / directionRatio;
} else {
deltaY = (height / 2) * Math.sign(direction.y);
deltaX = deltaY * directionRatio;
}
const delta = vec2.fromValues(deltaX, deltaY);
const center = vec2.fromValues(width / 2, height / 2);
const p = vec2.add(center, center, delta);
const arrowPadding = 16;
vec2.set(
p,
clamp(p.x, arrowPadding, width - 3 * arrowPadding),
clamp(height - p.y, arrowPadding, height - 3 * arrowPadding),
);
e.style.transform = `translateX(${p.x}px) translateY(${p.y}px) rotate(${
-angle + Math.PI / 2
}rad) translateX(-50%) translateY(-50%)`;
});
} else this.gameObjects.sendCommand(command); } else this.gameObjects.sendCommand(command);
}); });

View file

@ -30,12 +30,18 @@ export class PlanetView extends PlanetBase implements ViewObject {
private getGradient(): string { private getGradient(): string {
const sideDecla = this.ownership < 0.5; const sideDecla = this.ownership < 0.5;
const sidePercent = (Math.abs(this.ownership - 0.5) / 0.5) * 100; const sidePercent = (Math.abs(this.ownership - 0.5) / 0.5) * 100;
const color = sideDecla ? 'var(--bright-decla)' : 'var(--bright-red)'; return sideDecla
return `conic-gradient( ? `conic-gradient(
${color} ${sidePercent}%, var(--bright-decla) ${sidePercent}%,
${color} ${sidePercent}%, var(--bright-decla) ${sidePercent}%,
var(--bright-neutral) ${sidePercent}%, var(--bright-neutral) ${sidePercent}%,
var(--bright-neutral) 100% var(--bright-neutral) 100%
)`
: `conic-gradient(
var(--bright-neutral) 0%,
var(--bright-neutral) ${100 - sidePercent}%,
var(--bright-red) ${100 - sidePercent}%,
var(--bright-red) 100%
)`; )`;
} }
public beforeDestroy(): void { public beforeDestroy(): void {

View file

@ -15,8 +15,8 @@ export class BlobShape extends Drawable {
float blobSmoothMin(float a, float b) float blobSmoothMin(float a, float b)
{ {
const float k = 300.0; const highp float k = 300.0;
float res = exp2(-k * a) + exp2(-k * b); highp float res = exp2(-k * a) + exp2(-k * b);
return -log2(res) / k; return -log2(res) / k;
} }

View file

@ -52,7 +52,9 @@ export class PlanetShape extends PolygonFactory(settings.planetEdgeCount, 0) {
vec2 center = planetCenters[j]; vec2 center = planetCenters[j];
float l = planetLengths[j]; float l = planetLengths[j];
float randomOffset = planetRandoms[j]; float randomOffset = planetRandoms[j];
vec2 targetTangent = normalize(target - center); vec2 targetCenterDelta = target - center;
float targetDistance = length(targetCenterDelta);
vec2 targetTangent = targetCenterDelta / clamp(targetDistance, 0.01, 1000.0);
vec2 noisyTarget = target - ( vec2 noisyTarget = target - (
targetTangent * planetTerrain(vec2( targetTangent * planetTerrain(vec2(
l * abs(atan(targetTangent.y, targetTangent.x)), l * abs(atan(targetTangent.y, targetTangent.x)),

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" stroke-width="1.5" stroke="#03A9F4" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<polyline points="6 15 12 9 18 15" />
</svg>

After

Width:  |  Height:  |  Size: 279 B

View file

@ -0,0 +1,37 @@
import { vec2 } from 'gl-matrix';
import { CharacterTeam } from '../../objects/types/character-team';
import { serializable } from '../../transport/serialization/serializable';
import { Command } from '../command';
@serializable
export class OtherPlayerDirection {
public constructor(
public readonly direction: vec2,
public readonly team: CharacterTeam,
) {}
public toArray(): Array<any> {
return [this.direction, this.team];
}
}
@serializable
export class UpdateGameState extends Command {
public constructor(
public readonly declaCount: number,
public readonly redCount: number,
public readonly neutralCount: number,
public readonly otherPlayerDirections: Array<OtherPlayerDirection>,
) {
super();
}
public toArray(): Array<any> {
return [
this.declaCount,
this.redCount,
this.neutralCount,
this.otherPlayerDirections,
];
}
}

View file

@ -1,17 +0,0 @@
import { serializable } from '../../transport/serialization/serializable';
import { Command } from '../command';
@serializable
export class UpdatePlanetOwnershipCommand extends Command {
public constructor(
public readonly declaCount: number,
public readonly redCount: number,
public readonly neutralCount: number,
) {
super();
}
public toArray(): Array<any> {
return [this.declaCount, this.redCount, this.neutralCount];
}
}

View file

@ -7,9 +7,10 @@ export * from './commands/types/move-action';
export * from './commands/types/primary-action'; export * from './commands/types/primary-action';
export * from './commands/types/player-died'; export * from './commands/types/player-died';
export * from './commands/types/update-objects'; export * from './commands/types/update-objects';
export * from './commands/types/update-planet-ownership'; export * from './commands/types/update-game-state';
export * from './commands/types/secondary-action'; export * from './commands/types/secondary-action';
export * from './commands/command-receiver'; export * from './commands/command-receiver';
export * from './commands/types/update-game-state';
export * from './commands/command-executors'; export * from './commands/command-executors';
export * from './commands/command-generator'; export * from './commands/command-generator';
export * from './commands/broadcast-commands'; export * from './commands/broadcast-commands';
@ -45,7 +46,6 @@ export * from './objects/types/player-character-base';
export * from './objects/types/lamp-base'; export * from './objects/types/lamp-base';
export * from './objects/types/planet-base'; export * from './objects/types/planet-base';
export * from './objects/types/projectile-base'; export * from './objects/types/projectile-base';
export * from './objects/update-message';
export * from './objects/update-object-message'; export * from './objects/update-object-message';
export * from './settings'; export * from './settings';
export * from './transport/transport-events'; export * from './transport/transport-events';