Update gameplay
This commit is contained in:
parent
49c410d8ff
commit
23fa7646d6
10 changed files with 165 additions and 33 deletions
|
|
@ -17,10 +17,11 @@ import {
|
|||
Circle,
|
||||
PlayerInformation,
|
||||
CharacterTeam,
|
||||
UpdatePlanetOwnershipCommand,
|
||||
UpdateGameState,
|
||||
GameObject,
|
||||
Command,
|
||||
UpdateObjectMessage,
|
||||
OtherPlayerDirection,
|
||||
} from 'shared';
|
||||
import { getTimeInMilliseconds } from '../helper/get-time-in-milliseconds';
|
||||
import { BoundingBox } from '../physics/bounding-boxes/bounding-box';
|
||||
|
|
@ -189,14 +190,46 @@ export class Player extends CommandReceiver {
|
|||
);
|
||||
|
||||
this.sendToPlayer(
|
||||
new UpdatePlanetOwnershipCommand(
|
||||
new UpdateGameState(
|
||||
PlanetPhysical.declaPlanetCount,
|
||||
PlanetPhysical.redPlanetCount,
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private sendToPlayer(command: Command) {
|
||||
this.socket.emit(TransportEvents.ServerToPlayer, serialize(command));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,7 +145,24 @@ body {
|
|||
|
||||
@include square(50px);
|
||||
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 {
|
||||
|
|
@ -165,8 +182,10 @@ body {
|
|||
height: $height;
|
||||
}
|
||||
|
||||
border-radius: 100px;
|
||||
overflow: hidden;
|
||||
|
||||
div:nth-child(1) {
|
||||
border-radius: 100px 0 0 100px;
|
||||
background: $bright-decla;
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +194,6 @@ body {
|
|||
}
|
||||
|
||||
div:nth-child(3) {
|
||||
border-radius: 0 100px 100px 0;
|
||||
background: $bright-red;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ import {
|
|||
SetAspectRatioActionCommand,
|
||||
PlayerInformation,
|
||||
PlayerDiedCommand,
|
||||
UpdatePlanetOwnershipCommand,
|
||||
UpdateGameState,
|
||||
clamp,
|
||||
} from 'shared';
|
||||
import io from 'socket.io-client';
|
||||
import { KeyboardListener } from './commands/generators/keyboard-listener';
|
||||
|
|
@ -54,6 +55,7 @@ export class Game {
|
|||
progressBar.appendChild(this.redPlanetCountElement);
|
||||
}
|
||||
|
||||
private arrowElements: Array<HTMLElement> = [];
|
||||
private async setupCommunication(serverUrl: string): Promise<void> {
|
||||
this.socket = io(serverUrl, {
|
||||
reconnectionDelayMax: 10000,
|
||||
|
|
@ -74,7 +76,7 @@ export class Game {
|
|||
navigator.vibrate(150);
|
||||
}
|
||||
this.overlay.appendChild(this.announcmentText);
|
||||
} else if (command instanceof UpdatePlanetOwnershipCommand) {
|
||||
} else if (command instanceof UpdateGameState) {
|
||||
const all = command.declaCount + command.redCount + command.neutralCount;
|
||||
this.declaPlanetCountElement.style.width = (command.declaCount / all) * 100 + '%';
|
||||
this.neutralPlanetCountElement.style.width =
|
||||
|
|
@ -90,6 +92,53 @@ export class Game {
|
|||
this.overlay.appendChild(this.announcmentText);
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,18 @@ export class PlanetView extends PlanetBase implements ViewObject {
|
|||
private getGradient(): string {
|
||||
const sideDecla = this.ownership < 0.5;
|
||||
const sidePercent = (Math.abs(this.ownership - 0.5) / 0.5) * 100;
|
||||
const color = sideDecla ? 'var(--bright-decla)' : 'var(--bright-red)';
|
||||
return `conic-gradient(
|
||||
${color} ${sidePercent}%,
|
||||
${color} ${sidePercent}%,
|
||||
return sideDecla
|
||||
? `conic-gradient(
|
||||
var(--bright-decla) ${sidePercent}%,
|
||||
var(--bright-decla) ${sidePercent}%,
|
||||
var(--bright-neutral) ${sidePercent}%,
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ export class BlobShape extends Drawable {
|
|||
|
||||
float blobSmoothMin(float a, float b)
|
||||
{
|
||||
const float k = 300.0;
|
||||
float res = exp2(-k * a) + exp2(-k * b);
|
||||
const highp float k = 300.0;
|
||||
highp float res = exp2(-k * a) + exp2(-k * b);
|
||||
return -log2(res) / k;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ export class PlanetShape extends PolygonFactory(settings.planetEdgeCount, 0) {
|
|||
vec2 center = planetCenters[j];
|
||||
float l = planetLengths[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 - (
|
||||
targetTangent * planetTerrain(vec2(
|
||||
l * abs(atan(targetTangent.y, targetTangent.x)),
|
||||
|
|
|
|||
4
frontend/static/chevron.svg
Normal file
4
frontend/static/chevron.svg
Normal 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 |
37
shared/src/commands/types/update-game-state.ts
Normal file
37
shared/src/commands/types/update-game-state.ts
Normal 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,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,10 @@ export * from './commands/types/move-action';
|
|||
export * from './commands/types/primary-action';
|
||||
export * from './commands/types/player-died';
|
||||
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/command-receiver';
|
||||
export * from './commands/types/update-game-state';
|
||||
export * from './commands/command-executors';
|
||||
export * from './commands/command-generator';
|
||||
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/planet-base';
|
||||
export * from './objects/types/projectile-base';
|
||||
export * from './objects/update-message';
|
||||
export * from './objects/update-object-message';
|
||||
export * from './settings';
|
||||
export * from './transport/transport-events';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue