evotars 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +24 -0
- package/dist/config/constants.d.ts +1 -0
- package/dist/entities/EmoteSpitter.d.ts +15 -0
- package/dist/entities/Evotar.d.ts +78 -0
- package/dist/entities/Message.d.ts +27 -0
- package/dist/entities/Name.d.ts +14 -0
- package/dist/entities/SpriteContainer.d.ts +16 -0
- package/dist/entities/TrailEffect.d.ts +15 -0
- package/dist/evotars.d.ts +15 -0
- package/dist/evotars.js +705 -0
- package/dist/evotars.umd.cjs +1 -0
- package/dist/evotarsManager.d.ts +30 -0
- package/dist/helpers/timer.d.ts +14 -0
- package/dist/helpers/types.d.ts +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/services/soundService.d.ts +14 -0
- package/dist/services/spriteService.d.ts +63 -0
- package/dist/types/dto/action.d.ts +56 -0
- package/{src/types/dto/chatter.ts → dist/types/dto/chatter.d.ts} +2 -2
- package/dist/types/dto/event.d.ts +9 -0
- package/dist/types/dto/message.d.ts +8 -0
- package/dist/types/dto/settings.d.ts +5 -0
- package/dist/types/dto/user.d.ts +12 -0
- package/package.json +30 -3
- package/.editorconfig +0 -13
- package/.prettierrc.json +0 -3
- package/index.html +0 -13
- package/index.ts +0 -1
- package/public/fonts/Rubik.ttf +0 -0
- package/public/sounds/jump.mp3 +0 -0
- package/public/sprites/agent/agent.json +0 -166
- package/public/sprites/agent/agent.png +0 -0
- package/public/sprites/cat/cat.json +0 -231
- package/public/sprites/cat/cat.png +0 -0
- package/public/sprites/dude/dude.json +0 -231
- package/public/sprites/dude/dude.png +0 -0
- package/public/sprites/girl/girl.json +0 -231
- package/public/sprites/girl/girl.png +0 -0
- package/public/sprites/nerd/nerd.json +0 -231
- package/public/sprites/nerd/nerd.png +0 -0
- package/public/sprites/senior/senior.json +0 -231
- package/public/sprites/senior/senior.png +0 -0
- package/public/sprites/sith/sith.json +0 -166
- package/public/sprites/sith/sith.png +0 -0
- package/src/app.ts +0 -63
- package/src/config/config.ts +0 -133
- package/src/config/constants.ts +0 -1
- package/src/dudes.ts +0 -71
- package/src/entities/Dude.ts +0 -453
- package/src/entities/DudeEmoteSpitter.ts +0 -60
- package/src/entities/DudeMessage.ts +0 -163
- package/src/entities/DudeName.ts +0 -39
- package/src/entities/DudeSpriteContainer.ts +0 -68
- package/src/entities/DudeTrailEffect.ts +0 -72
- package/src/helpers/timer.ts +0 -43
- package/src/helpers/types.ts +0 -11
- package/src/index.ts +0 -1
- package/src/main.ts +0 -75
- package/src/services/assetsLoader.ts +0 -27
- package/src/services/dudesManager.ts +0 -305
- package/src/services/soundService.ts +0 -28
- package/src/services/spriteProvider.ts +0 -93
- package/src/styles.css +0 -16
- package/src/types/dto/action.ts +0 -68
- package/src/types/dto/event.ts +0 -9
- package/src/types/dto/message.ts +0 -8
- package/src/types/dto/settings.ts +0 -5
- package/src/types/dto/user.ts +0 -13
- package/tsconfig.json +0 -23
- /package/{src/types/dto/index.ts → dist/types/dto/index.d.ts} +0 -0
- /package/{src/types/index.ts → dist/types/index.d.ts} +0 -0
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import * as PIXI from 'pixi.js';
|
|
2
|
-
import { FIXED_DELTA_TIME } from '../config/constants';
|
|
3
|
-
import { Point } from '../helpers/types';
|
|
4
|
-
import {
|
|
5
|
-
DudeLayerAnimatedSprite,
|
|
6
|
-
DudeSpriteLayers,
|
|
7
|
-
} from '../services/spriteProvider';
|
|
8
|
-
import { DEFAULT_DUDE_SCALE } from './Dude';
|
|
9
|
-
|
|
10
|
-
export type DudeSpriteContainerProps = {
|
|
11
|
-
color: {
|
|
12
|
-
[key in DudeSpriteLayers]?: PIXI.Color;
|
|
13
|
-
};
|
|
14
|
-
scale: Point;
|
|
15
|
-
play: boolean;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export class DudeSpriteContainer {
|
|
19
|
-
public container: PIXI.Container = new PIXI.Container();
|
|
20
|
-
|
|
21
|
-
public sprites: DudeLayerAnimatedSprite[];
|
|
22
|
-
|
|
23
|
-
constructor(sprites: DudeLayerAnimatedSprite[]) {
|
|
24
|
-
this.sprites = sprites;
|
|
25
|
-
|
|
26
|
-
this.container.sortableChildren = true;
|
|
27
|
-
|
|
28
|
-
let zIndex = 0;
|
|
29
|
-
|
|
30
|
-
for (const layer of this.sprites) {
|
|
31
|
-
const sprite = layer.sprite;
|
|
32
|
-
this.container.addChild(sprite);
|
|
33
|
-
|
|
34
|
-
sprite.zIndex = ++zIndex;
|
|
35
|
-
sprite.anchor.set(0.5, 0.5);
|
|
36
|
-
sprite.autoUpdate = false;
|
|
37
|
-
sprite.play();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public update(props: DudeSpriteContainerProps): void {
|
|
42
|
-
for (const layer of this.sprites) {
|
|
43
|
-
if (props.play) {
|
|
44
|
-
layer.sprite.update(FIXED_DELTA_TIME * 0.06);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (props.color) {
|
|
48
|
-
for (const colorLayer in props.color) {
|
|
49
|
-
if (colorLayer == layer.layer) {
|
|
50
|
-
const color = props.color[colorLayer];
|
|
51
|
-
|
|
52
|
-
if (color) {
|
|
53
|
-
layer.sprite.alpha = color.alpha;
|
|
54
|
-
layer.sprite.tint = color;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (props.scale.x) {
|
|
61
|
-
layer.sprite.animationSpeed =
|
|
62
|
-
DEFAULT_DUDE_SCALE / Math.abs(props.scale.x);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
this.container.scale.set(props.scale.x, props.scale.y);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import * as PIXI from 'pixi.js';
|
|
2
|
-
import { app } from '../app';
|
|
3
|
-
import { Timer } from '../helpers/timer';
|
|
4
|
-
import { DudeSpriteContainer } from './DudeSpriteContainer';
|
|
5
|
-
|
|
6
|
-
export type DudeTrailEffectProps = {
|
|
7
|
-
play: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export class DudeTrailEffect {
|
|
11
|
-
public container: PIXI.Container = new PIXI.Container();
|
|
12
|
-
|
|
13
|
-
private timer?: Timer;
|
|
14
|
-
|
|
15
|
-
private sprite?: DudeSpriteContainer;
|
|
16
|
-
|
|
17
|
-
private opacityStep = 0.1;
|
|
18
|
-
|
|
19
|
-
private shadowStep = 50;
|
|
20
|
-
|
|
21
|
-
constructor() {
|
|
22
|
-
app.stage.addChild(this.container);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public setSprite(sprite: DudeSpriteContainer) {
|
|
26
|
-
this.sprite = sprite;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public update(props: DudeTrailEffectProps): void {
|
|
30
|
-
for (const child of this.container.children) {
|
|
31
|
-
if (child.alpha > 0) {
|
|
32
|
-
child.alpha = child.alpha - this.opacityStep;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (this.timer && !this.timer.isCompleted) {
|
|
37
|
-
this.timer.tick();
|
|
38
|
-
} else if (props.play) {
|
|
39
|
-
this.timer = new Timer(this.shadowStep);
|
|
40
|
-
|
|
41
|
-
const container = new PIXI.Container();
|
|
42
|
-
|
|
43
|
-
if (this.sprite) {
|
|
44
|
-
for (const layer of this.sprite.sprites) {
|
|
45
|
-
const texture = layer.sprite.texture.clone();
|
|
46
|
-
const sprite = new PIXI.Sprite(texture);
|
|
47
|
-
|
|
48
|
-
sprite.anchor.set(0.5, 0.5);
|
|
49
|
-
sprite.alpha = layer.sprite.alpha;
|
|
50
|
-
sprite.tint = layer.sprite.tint;
|
|
51
|
-
|
|
52
|
-
container.addChild(sprite);
|
|
53
|
-
|
|
54
|
-
container.scale.set(
|
|
55
|
-
this.sprite.container.scale.x,
|
|
56
|
-
this.sprite.container.scale.y
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
container.pivot.set(
|
|
60
|
-
this.sprite.container.pivot.x,
|
|
61
|
-
this.sprite.container.pivot.y
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const globalPosition = this.sprite.container.getGlobalPosition();
|
|
65
|
-
container.position.set(globalPosition.x, globalPosition.y);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
this.container.addChild(container);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
package/src/helpers/timer.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { FIXED_DELTA_TIME } from '../config/constants';
|
|
2
|
-
|
|
3
|
-
export class Timer {
|
|
4
|
-
public isCompleted = false;
|
|
5
|
-
|
|
6
|
-
constructor(public current = 0, private onComplete?: () => void) {}
|
|
7
|
-
|
|
8
|
-
tick(delta: number = FIXED_DELTA_TIME) {
|
|
9
|
-
if (this.isCompleted) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
this.current -= delta;
|
|
14
|
-
|
|
15
|
-
if (this.current < 0) {
|
|
16
|
-
this.isCompleted = true;
|
|
17
|
-
this.onComplete?.();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class Timers {
|
|
23
|
-
private timers: Timer[] = [];
|
|
24
|
-
|
|
25
|
-
public add(current?: number, onComplete?: () => void) {
|
|
26
|
-
this.timers.push(new Timer(current, onComplete));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public tick(delta: number = FIXED_DELTA_TIME) {
|
|
30
|
-
const uncompleted = [];
|
|
31
|
-
|
|
32
|
-
for (const timer of this.timers) {
|
|
33
|
-
if (!timer.isCompleted) {
|
|
34
|
-
timer.tick(delta);
|
|
35
|
-
uncompleted.push(timer);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this.timers = uncompleted;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const timers = new Timers();
|
package/src/helpers/types.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dudes';
|
package/src/main.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Dudes } from "./dudes";
|
|
2
|
-
import { SettingsEntity } from "./types";
|
|
3
|
-
import "./styles.css";
|
|
4
|
-
|
|
5
|
-
const manifest = {
|
|
6
|
-
bundles: [
|
|
7
|
-
{
|
|
8
|
-
name: "main",
|
|
9
|
-
assets: [
|
|
10
|
-
{
|
|
11
|
-
alias: "dude",
|
|
12
|
-
src: "/sprites/dude/dude.json",
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
alias: "sith",
|
|
16
|
-
src: "/sprites/sith/sith.json",
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
alias: "agent",
|
|
20
|
-
src: "/sprites/agent/agent.json",
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
alias: "girl",
|
|
24
|
-
src: "/sprites/girl/girl.json",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
alias: "senior",
|
|
28
|
-
src: "/sprites/senior/senior.json",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
alias: "cat",
|
|
32
|
-
src: "/sprites/cat/cat.json",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
alias: "nerd",
|
|
36
|
-
src: "/sprites/nerd/nerd.json",
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: "fonts",
|
|
42
|
-
assets: [
|
|
43
|
-
{
|
|
44
|
-
alias: "Rubik",
|
|
45
|
-
src: "/fonts/Rubik.ttf",
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const sound = { jump: "/sounds/jump.mp3" };
|
|
53
|
-
const settings: SettingsEntity = {
|
|
54
|
-
fallingDudes: true,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const root = document.getElementById("root");
|
|
58
|
-
|
|
59
|
-
if (root) {
|
|
60
|
-
const dudes = new Dudes(root);
|
|
61
|
-
await dudes.run({ manifest, sound });
|
|
62
|
-
dudes.updateSettings(settings);
|
|
63
|
-
|
|
64
|
-
setTimeout(() => {
|
|
65
|
-
dudes.processMessage({
|
|
66
|
-
message: "Hello!",
|
|
67
|
-
userId: "1",
|
|
68
|
-
emotes: [],
|
|
69
|
-
info: {
|
|
70
|
-
color: "pink",
|
|
71
|
-
displayName: "Dude",
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
}, 500);
|
|
75
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as PIXI from 'pixi.js';
|
|
2
|
-
|
|
3
|
-
export interface AsepriteFrameData extends PIXI.ISpritesheetFrameData {
|
|
4
|
-
duration: number;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface AsepriteData extends PIXI.ISpritesheetData {
|
|
8
|
-
frames: Record<string, AsepriteFrameData>;
|
|
9
|
-
duration: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class AssetsLoader {
|
|
13
|
-
private isLoaded = false;
|
|
14
|
-
|
|
15
|
-
public sheets: Record<string, PIXI.Spritesheet<AsepriteData>> = {};
|
|
16
|
-
|
|
17
|
-
async load(manifest: PIXI.AssetsManifest): Promise<void> {
|
|
18
|
-
if (!this.isLoaded) {
|
|
19
|
-
this.isLoaded = true;
|
|
20
|
-
await PIXI.Assets.init({ manifest });
|
|
21
|
-
this.sheets = await PIXI.Assets.loadBundle('main');
|
|
22
|
-
await PIXI.Assets.loadBundle('fonts');
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const assetsLoader = new AssetsLoader();
|
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MessageEntity,
|
|
3
|
-
RaidData,
|
|
4
|
-
TwitchChatterEntity,
|
|
5
|
-
UserActionEntity,
|
|
6
|
-
isColorUserActionEntity,
|
|
7
|
-
isDashUserActionEntity,
|
|
8
|
-
isGrowUserActionEntity,
|
|
9
|
-
isJumpUserActionEntity,
|
|
10
|
-
} from "../types";
|
|
11
|
-
import * as PIXI from "pixi.js";
|
|
12
|
-
import tinycolor from "tinycolor2";
|
|
13
|
-
import { app } from "../app";
|
|
14
|
-
import { config } from "../config/config";
|
|
15
|
-
import { Dude, DudeProps } from "../entities/Dude";
|
|
16
|
-
import { timers } from "../helpers/timer";
|
|
17
|
-
|
|
18
|
-
type DudesManagerSubscription = {
|
|
19
|
-
onAdd: (dude: Dude) => void;
|
|
20
|
-
onDelete: (dude: Dude) => void;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const DUDE_DESPAWN_TIMER = 1000 * 60 * 5;
|
|
24
|
-
|
|
25
|
-
class DudesManager {
|
|
26
|
-
private viewers: Record<string, Dude | undefined> = {};
|
|
27
|
-
|
|
28
|
-
private raiders: Dude[] = [];
|
|
29
|
-
|
|
30
|
-
private lastDudeActivity: Record<string, number | undefined> = {};
|
|
31
|
-
|
|
32
|
-
private subscriptions: DudesManagerSubscription[] = [];
|
|
33
|
-
|
|
34
|
-
public subscribe(subscription: DudesManagerSubscription) {
|
|
35
|
-
this.subscriptions.push(subscription);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public update() {
|
|
39
|
-
for (const id in this.viewers) {
|
|
40
|
-
const viewer = this.viewers[id];
|
|
41
|
-
|
|
42
|
-
if (viewer) {
|
|
43
|
-
viewer.update();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
for (const dude of this.raiders) {
|
|
48
|
-
dude.update();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public processRaid(data: RaidData) {
|
|
53
|
-
if (!app.settings.fallingRaiders) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const time = (1 / data.viewers) * 5000;
|
|
58
|
-
|
|
59
|
-
const spriteConfig = config.sprites["agent"];
|
|
60
|
-
|
|
61
|
-
for (let i = 0; i < data.viewers; i++) {
|
|
62
|
-
const dude = new Dude({
|
|
63
|
-
isAnonymous: true,
|
|
64
|
-
zIndex: -1,
|
|
65
|
-
sprite: spriteConfig,
|
|
66
|
-
color: new PIXI.Color(data.broadcaster.info.color),
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
timers.add(time * i, () => {
|
|
70
|
-
this.addRaider(dude);
|
|
71
|
-
dude.spawn({ isFalling: true });
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
timers.add(i * time + 30000, () => {
|
|
75
|
-
dude.despawn({
|
|
76
|
-
onComplete: () => {
|
|
77
|
-
this.deleteRaider(dude);
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const dude = this.viewers[data.broadcaster.id];
|
|
84
|
-
|
|
85
|
-
const props: DudeProps = {
|
|
86
|
-
...this.prepareDudeProps(
|
|
87
|
-
data.broadcaster.info.displayName,
|
|
88
|
-
data.broadcaster.info.color,
|
|
89
|
-
),
|
|
90
|
-
scale: 8,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const spawnBroadcaster = () => {
|
|
94
|
-
const dude = new Dude(props);
|
|
95
|
-
this.addViewer(data.broadcaster.id, dude);
|
|
96
|
-
dude.spawn({ isFalling: true, positionX: 0.5 });
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
this.lastDudeActivity[data.broadcaster.id] = performance.now();
|
|
100
|
-
|
|
101
|
-
if (!dude) {
|
|
102
|
-
spawnBroadcaster();
|
|
103
|
-
} else {
|
|
104
|
-
dude.despawn({
|
|
105
|
-
onComplete: () => {
|
|
106
|
-
spawnBroadcaster();
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
public processChatters(data: TwitchChatterEntity[]) {
|
|
113
|
-
for (const id in this.viewers) {
|
|
114
|
-
const lastMessageTime = this.lastDudeActivity[id];
|
|
115
|
-
const spawnedRecently =
|
|
116
|
-
!!lastMessageTime &&
|
|
117
|
-
performance.now() - lastMessageTime < DUDE_DESPAWN_TIMER;
|
|
118
|
-
|
|
119
|
-
if (data.every((chatter) => chatter.userId != id) && !spawnedRecently) {
|
|
120
|
-
const dude = this.viewers[id];
|
|
121
|
-
|
|
122
|
-
if (dude) {
|
|
123
|
-
dude.despawn({
|
|
124
|
-
onComplete: () => {
|
|
125
|
-
this.deleteViewer(id, dude);
|
|
126
|
-
},
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (app.settings.showAnonymousDudes) {
|
|
133
|
-
for (const chatter of data) {
|
|
134
|
-
const dude = this.viewers[chatter.userId];
|
|
135
|
-
|
|
136
|
-
if (!dude) {
|
|
137
|
-
const props = {
|
|
138
|
-
name: chatter.name,
|
|
139
|
-
isAnonymous: !this.hasActivity(chatter.userId),
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const dude = new Dude(props);
|
|
143
|
-
dude.spawn();
|
|
144
|
-
|
|
145
|
-
this.addViewer(chatter.userId, dude);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private hasActivity = (userId: string): boolean =>
|
|
152
|
-
!!this.lastDudeActivity[userId];
|
|
153
|
-
|
|
154
|
-
public doAction(action: UserActionEntity, dude: Dude) {
|
|
155
|
-
if (isJumpUserActionEntity(action)) {
|
|
156
|
-
dude.jump({
|
|
157
|
-
velocityX: action.data.velocityX,
|
|
158
|
-
velocityY: action.data.velocityY,
|
|
159
|
-
cooldown: action.cooldown,
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (isDashUserActionEntity(action)) {
|
|
164
|
-
dude.dash({ force: action.data.force, cooldown: action.cooldown });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (isColorUserActionEntity(action)) {
|
|
168
|
-
const color = tinycolor(action.data.color);
|
|
169
|
-
|
|
170
|
-
if (color && color.isValid()) {
|
|
171
|
-
dude.setUserProps({ color: new PIXI.Color(action.data.color) });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (isGrowUserActionEntity(action)) {
|
|
176
|
-
dude.scale({
|
|
177
|
-
value: action.data.scale,
|
|
178
|
-
duration: action.data.duration,
|
|
179
|
-
cooldown: action.cooldown,
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private prepareDudeProps(
|
|
185
|
-
name: string,
|
|
186
|
-
color?: string,
|
|
187
|
-
sprite?: string,
|
|
188
|
-
): DudeProps {
|
|
189
|
-
const props: DudeProps = {
|
|
190
|
-
name,
|
|
191
|
-
isAnonymous: false,
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
const spriteConfig = sprite ? config.sprites[sprite] : null;
|
|
195
|
-
|
|
196
|
-
if (spriteConfig) {
|
|
197
|
-
props.sprite = spriteConfig;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (color) {
|
|
201
|
-
props.color = new PIXI.Color(color);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return props;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
public processAction(action: UserActionEntity): void {
|
|
208
|
-
const dude = this.viewers[action.userId];
|
|
209
|
-
|
|
210
|
-
const props: DudeProps = this.prepareDudeProps(
|
|
211
|
-
action.info.displayName,
|
|
212
|
-
action.info.color,
|
|
213
|
-
action.info.sprite,
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
if (!dude) {
|
|
217
|
-
const dude = new Dude(props);
|
|
218
|
-
|
|
219
|
-
dude.spawn({
|
|
220
|
-
onComplete: () => {
|
|
221
|
-
const dude = this.viewers[action.userId];
|
|
222
|
-
if (dude) {
|
|
223
|
-
this.doAction(action, dude);
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
this.addViewer(action.userId, dude);
|
|
229
|
-
} else {
|
|
230
|
-
this.doAction(action, dude);
|
|
231
|
-
dude.setProps(props);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
public processMessage(data: MessageEntity): void {
|
|
236
|
-
const props: DudeProps = this.prepareDudeProps(
|
|
237
|
-
data.info.displayName,
|
|
238
|
-
data.info.color,
|
|
239
|
-
data.info.sprite,
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
let dude = this.viewers[data.userId];
|
|
243
|
-
|
|
244
|
-
if (!dude) {
|
|
245
|
-
const isFalling = app.settings.fallingDudes
|
|
246
|
-
? !this.hasActivity(data.userId)
|
|
247
|
-
: false;
|
|
248
|
-
|
|
249
|
-
dude = new Dude(props);
|
|
250
|
-
dude.spawn({ isFalling });
|
|
251
|
-
|
|
252
|
-
this.addViewer(data.userId, dude);
|
|
253
|
-
} else {
|
|
254
|
-
dude.setProps(props);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
this.lastDudeActivity[data.userId] = performance.now();
|
|
258
|
-
|
|
259
|
-
if (data.message) {
|
|
260
|
-
dude.addMessage(data.message);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (data.emotes.length > 0) {
|
|
264
|
-
dude.spitEmotes(data.emotes);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
public addViewer(id: string, dude: Dude): void {
|
|
269
|
-
this.subscriptions.forEach((s) => s.onAdd(dude));
|
|
270
|
-
this.viewers[id] = dude;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
public deleteViewer(id: string, dude: Dude): void {
|
|
274
|
-
this.subscriptions.forEach((s) => s.onDelete(dude));
|
|
275
|
-
delete this.viewers[id];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
public addRaider(dude: Dude): void {
|
|
279
|
-
this.subscriptions.forEach((s) => s.onAdd(dude));
|
|
280
|
-
this.raiders.push(dude);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
public deleteRaider(dude: Dude): void {
|
|
284
|
-
this.subscriptions.forEach((s) => s.onDelete(dude));
|
|
285
|
-
this.raiders = this.raiders.filter((raider) => raider != dude);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
public zIndexDudeMax(from: number) {
|
|
289
|
-
return Object.values(this.viewers).reduce((zIndex, dude) => {
|
|
290
|
-
return dude && zIndex <= dude.container.zIndex
|
|
291
|
-
? dude.container.zIndex + 1
|
|
292
|
-
: zIndex;
|
|
293
|
-
}, from);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
public zIndexDudeMin(from: number) {
|
|
297
|
-
return Object.values(this.viewers).reduce((zIndex, dude) => {
|
|
298
|
-
return dude && zIndex >= dude.container.zIndex
|
|
299
|
-
? dude.container.zIndex - 1
|
|
300
|
-
: zIndex;
|
|
301
|
-
}, from);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export const dudesManager = new DudesManager();
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type SoundManifest = {
|
|
2
|
-
[key: string]: string;
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
class SoundService {
|
|
6
|
-
assets: { [key: string]: HTMLAudioElement } = {};
|
|
7
|
-
|
|
8
|
-
async init(manifest: SoundManifest) {
|
|
9
|
-
this.assets = Object.fromEntries(
|
|
10
|
-
Array.from(Object.entries(manifest)).map(([key, value]) => {
|
|
11
|
-
return [key, new Audio(value)];
|
|
12
|
-
})
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
play(name: string) {
|
|
17
|
-
const audio = this.assets[name];
|
|
18
|
-
|
|
19
|
-
if (audio) {
|
|
20
|
-
audio.volume = 0.2;
|
|
21
|
-
audio.pause();
|
|
22
|
-
audio.currentTime = 0;
|
|
23
|
-
audio.play();
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const soundService = new SoundService();
|