evotars 0.0.9 → 0.0.10

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.
Files changed (61) hide show
  1. package/dist/evotars.js +26282 -0
  2. package/dist/evotars.umd.cjs +1147 -0
  3. package/dist/index.d.ts +175 -0
  4. package/package.json +16 -2
  5. package/.editorconfig +0 -13
  6. package/.prettierrc.json +0 -3
  7. package/index.html +0 -13
  8. package/playground/main.ts +0 -48
  9. package/playground/styles.css +0 -17
  10. package/public/evotars/agent/data.json +0 -18
  11. package/public/evotars/agent/sprite.json +0 -166
  12. package/public/evotars/agent/sprite.png +0 -0
  13. package/public/evotars/cat/data.json +0 -18
  14. package/public/evotars/cat/sprite.json +0 -231
  15. package/public/evotars/cat/sprite.png +0 -0
  16. package/public/evotars/dude/data.json +0 -18
  17. package/public/evotars/dude/sprite.json +0 -231
  18. package/public/evotars/dude/sprite.png +0 -0
  19. package/public/evotars/girl/data.json +0 -18
  20. package/public/evotars/girl/sprite.json +0 -231
  21. package/public/evotars/girl/sprite.png +0 -0
  22. package/public/evotars/nerd/data.json +0 -18
  23. package/public/evotars/nerd/sprite.json +0 -231
  24. package/public/evotars/nerd/sprite.png +0 -0
  25. package/public/evotars/senior/data.json +0 -18
  26. package/public/evotars/senior/sprite.json +0 -231
  27. package/public/evotars/senior/sprite.png +0 -0
  28. package/public/evotars/set.json +0 -10
  29. package/public/evotars/sith/data.json +0 -18
  30. package/public/evotars/sith/sprite.json +0 -166
  31. package/public/evotars/sith/sprite.png +0 -0
  32. package/public/evotars/sponge/data.json +0 -18
  33. package/public/evotars/sponge/sprite.json +0 -231
  34. package/public/evotars/sponge/sprite.png +0 -0
  35. package/public/fonts/Rubik.ttf +0 -0
  36. package/public/sounds/jump.mp3 +0 -0
  37. package/src/app.ts +0 -71
  38. package/src/config/constants.ts +0 -1
  39. package/src/entities/EmoteSpitter.ts +0 -102
  40. package/src/entities/Evotar.ts +0 -468
  41. package/src/entities/Message.ts +0 -164
  42. package/src/entities/Name.ts +0 -33
  43. package/src/entities/SpriteContainer.ts +0 -65
  44. package/src/entities/TrailEffect.ts +0 -73
  45. package/src/evotars.ts +0 -75
  46. package/src/evotarsManager.ts +0 -313
  47. package/src/helpers/timer.ts +0 -43
  48. package/src/helpers/types.ts +0 -4
  49. package/src/index.ts +0 -1
  50. package/src/services/soundService.ts +0 -30
  51. package/src/services/spriteService.ts +0 -167
  52. package/src/types/dto/action.ts +0 -79
  53. package/src/types/dto/chatter.ts +0 -4
  54. package/src/types/dto/event.ts +0 -9
  55. package/src/types/dto/index.ts +0 -6
  56. package/src/types/dto/message.ts +0 -8
  57. package/src/types/dto/settings.ts +0 -5
  58. package/src/types/dto/user.ts +0 -13
  59. package/src/types/index.ts +0 -1
  60. package/tsconfig.json +0 -23
  61. package/vite.config.js +0 -26
@@ -1,468 +0,0 @@
1
- import * as TWEEN from '@tweenjs/tween.js';
2
- import * as PIXI from 'pixi.js';
3
- import { app } from '../app';
4
- import { FIXED_DELTA_TIME } from '../config/constants';
5
- import { Timer } from '../helpers/timer';
6
- import { evotarsManager } from '../evotarsManager';
7
- import { soundService } from '../services/soundService';
8
- import {
9
- EvotarSpriteData,
10
- EvotarSpriteTags,
11
- EvotarAnimatedSprites,
12
- spriteService,
13
- } from '../services/spriteService';
14
- import { EvotarEmoteSpitter } from './EmoteSpitter';
15
- import { EvotarMessage } from './Message';
16
- import { EvotarName } from './Name';
17
- import { EvotarSpriteContainer } from './SpriteContainer';
18
- import { EvotarTrailEffect } from './TrailEffect';
19
-
20
- export type EvotarProps = {
21
- name?: string;
22
- sprite?: string;
23
- color?: PIXI.Color;
24
- direction?: number;
25
- scale?: number;
26
- isAnonymous?: boolean;
27
- zIndex?: number;
28
- };
29
-
30
- export type EvotarSpawnProps = {
31
- isFalling?: boolean;
32
- positionX?: number;
33
- onComplete?: () => void;
34
- };
35
-
36
- export type EvotarDepawnProps = {
37
- onComplete?: () => void;
38
- };
39
-
40
- type EvotarState = Required<EvotarProps>;
41
-
42
- type UserProps = {
43
- color?: PIXI.Color;
44
- };
45
-
46
- export class Evotar {
47
- public container: PIXI.Container = new PIXI.Container();
48
-
49
- private userState: UserProps = {};
50
-
51
- private state: EvotarState = {
52
- name: '',
53
- sprite: '',
54
- color: new PIXI.Color('#969696'),
55
- direction: 1,
56
- scale: 1,
57
- isAnonymous: false,
58
- zIndex: 0,
59
- };
60
-
61
- private animationState: EvotarSpriteTags = EvotarSpriteTags.Idle;
62
-
63
- // TODO: Refactor sprite initializing, move logic to separate file
64
- private sprite?: EvotarSpriteContainer;
65
-
66
- private spriteData: EvotarSpriteData = {
67
- name: 'evotar',
68
- collider: {
69
- x: 0,
70
- y: 0,
71
- w: 0,
72
- h: 0,
73
- },
74
- size: { w: 0, h: 0 },
75
- scale: 1,
76
- flip: false,
77
- colored: [],
78
- };
79
-
80
- private animatedSprites?: EvotarAnimatedSprites;
81
-
82
- public trail: EvotarTrailEffect = new EvotarTrailEffect();
83
-
84
- private name: EvotarName = new EvotarName();
85
-
86
- private message: EvotarMessage = new EvotarMessage(() => {
87
- this.state.zIndex = evotarsManager.zIndexEvotarMax(this.container.zIndex);
88
- });
89
-
90
- private emoteSpitter: EvotarEmoteSpitter = new EvotarEmoteSpitter();
91
-
92
- private velocity: PIXI.IPointData = {
93
- x: 0,
94
- y: 0,
95
- };
96
-
97
- private runSpeed = 0.05;
98
-
99
- private gravity = 0.2;
100
-
101
- private dashAcc = 3;
102
-
103
- private isJumping = false;
104
-
105
- private isDashing = false;
106
-
107
- private isDespawned = false;
108
-
109
- landTimer?: Timer;
110
-
111
- stateTimer?: Timer;
112
-
113
- scaleTimer?: Timer;
114
-
115
- spawnTween?: TWEEN.Tween<PIXI.Container>;
116
-
117
- fadeTween?: TWEEN.Tween<PIXI.Container>;
118
-
119
- scaleTween?: TWEEN.Tween<Evotar>;
120
-
121
- constructor() {
122
- this.container.addChild(this.name.text);
123
- this.container.addChild(this.emoteSpitter.container);
124
- this.container.addChild(this.message.container);
125
-
126
- this.container.sortableChildren = true;
127
- }
128
-
129
- spawn(props: EvotarSpawnProps = { isFalling: false }): void {
130
- const collider = this.spriteData.collider;
131
- const fallingStartY = -(
132
- collider.y +
133
- collider.h -
134
- this.spriteData.size.h / 2
135
- );
136
- const spawnY = props.isFalling ? fallingStartY : app.renderer.height;
137
- const spriteWidth =
138
- this.spriteData.size.w * this.state.scale * this.spriteData.scale;
139
-
140
- const x =
141
- props.positionX != undefined
142
- ? props.positionX * app.renderer.width
143
- : Math.random() * (app.renderer.width - spriteWidth) + spriteWidth / 2;
144
- const y = spawnY * this.state.scale * this.spriteData.scale;
145
-
146
- this.container.x = x;
147
- this.container.y = y;
148
-
149
- this.state.direction = Math.random() > 0.5 ? 1 : -1;
150
-
151
- if (!props.isFalling) {
152
- const zIndex = evotarsManager.zIndexEvotarMin(this.container.zIndex);
153
-
154
- this.state.zIndex = zIndex;
155
- this.container.alpha = 0;
156
-
157
- this.spawnTween = new TWEEN.Tween(this.container)
158
- .to({ alpha: 1 }, 500)
159
- .onComplete(props.onComplete)
160
- .start();
161
- }
162
-
163
- this.stateTimer = new Timer(5000, () => {
164
- if (!this.isJumping) {
165
- this.setAnimationState(EvotarSpriteTags.Run);
166
- }
167
- });
168
- }
169
-
170
- despawn(props: EvotarDepawnProps = {}): void {
171
- if (this.fadeTween && this.fadeTween.isPlaying()) {
172
- return;
173
- }
174
-
175
- this.fadeTween = new TWEEN.Tween(this.container)
176
- .to({ alpha: 0 }, 1000)
177
- .onComplete(() => {
178
- this.isDespawned = true;
179
- props.onComplete && props.onComplete();
180
- })
181
- .start();
182
- }
183
-
184
- scale(options: { value: number; duration: number; cooldown: number }): void {
185
- if (this.scaleTween && this.scaleTween.isPlaying()) {
186
- return;
187
- }
188
-
189
- if (this.scaleTimer && !this.scaleTimer.isCompleted) {
190
- return;
191
- }
192
-
193
- this.scaleTween = new TWEEN.Tween(this)
194
- .to({ state: { scale: options.value ?? 2 } }, 2000)
195
- .onComplete(() => {
196
- this.scaleTimer = new Timer((options.duration ?? 10) * 1000, () => {
197
- this.scaleTween = new TWEEN.Tween(this)
198
- .to({ state: { scale: 1 } }, 2000)
199
- .start();
200
- });
201
- })
202
- .start();
203
- }
204
-
205
- jump(options: {
206
- velocityX: number;
207
- velocityY: number;
208
- cooldown: number;
209
- }): void {
210
- if (this.isDespawned) {
211
- return;
212
- }
213
-
214
- if (!this.isJumping) {
215
- this.isJumping = true;
216
-
217
- this.velocity.x = this.state.direction * (options.velocityX ?? 3.5);
218
- this.velocity.y = options.velocityY ?? -8;
219
-
220
- this.setAnimationState(EvotarSpriteTags.Jump);
221
-
222
- soundService.play('jump');
223
- }
224
- }
225
-
226
- dash(options: { force: number; cooldown: number }): void {
227
- if (this.isDespawned) {
228
- return;
229
- }
230
-
231
- if (!this.isDashing) {
232
- this.isDashing = true;
233
- this.velocity.x = this.state.direction * (options.force ?? 14);
234
- }
235
- }
236
-
237
- async setSprite(sprite: string) {
238
- if (sprite && sprite != this.state.sprite) {
239
- const spriteData = await spriteService.getSpriteData(sprite);
240
-
241
- if (!spriteData) {
242
- return;
243
- }
244
-
245
- this.state.sprite = sprite;
246
-
247
- this.spriteData = spriteData.data;
248
- this.animatedSprites = spriteService.getAnimatedSprites(sprite);
249
-
250
- this.setAnimationState(this.animationState, true);
251
- }
252
- }
253
-
254
- async setProps(props: EvotarProps) {
255
- if (props.sprite) {
256
- await this.setSprite(props.sprite);
257
- }
258
-
259
- this.state = { ...this.state, ...props };
260
- }
261
-
262
- setUserProps(props: UserProps) {
263
- this.userState = { ...this.userState, ...props };
264
- }
265
-
266
- private move() {
267
- const collider = this.spriteData.collider;
268
-
269
- const position = {
270
- x: this.container.position.x,
271
- y: this.container.position.y,
272
- };
273
-
274
- if (this.isDashing) {
275
- const currentVelocitySign = Math.sign(this.velocity.x);
276
-
277
- this.velocity.x =
278
- this.velocity.x -
279
- (currentVelocitySign * this.dashAcc) / Math.abs(this.velocity.x);
280
-
281
- if (currentVelocitySign != Math.sign(this.velocity.x)) {
282
- this.isDashing = false;
283
- this.velocity.x = 0;
284
- } else {
285
- position.x += this.velocity.x;
286
- }
287
- } else {
288
- if (this.stateTimer?.isCompleted) {
289
- this.stateTimer = new Timer(Math.random() * 5000, () => {
290
- if (this.animationState == EvotarSpriteTags.Idle) {
291
- this.setAnimationState(EvotarSpriteTags.Run);
292
- } else if (this.animationState == EvotarSpriteTags.Run) {
293
- this.setAnimationState(EvotarSpriteTags.Idle);
294
- }
295
- });
296
- }
297
-
298
- if (this.animationState == EvotarSpriteTags.Run) {
299
- const speed = this.runSpeed * this.state.direction;
300
- this.velocity.x = speed * FIXED_DELTA_TIME;
301
- }
302
-
303
- this.velocity.y = this.velocity.y + this.gravity;
304
-
305
- position.x += this.velocity.x;
306
- position.y += this.velocity.y;
307
-
308
- if (this.isOnGround(position.y)) {
309
- this.velocity.y = 0;
310
- this.velocity.x = 0;
311
-
312
- position.y = app.renderer.height;
313
-
314
- if (this.animationState == EvotarSpriteTags.Fall) {
315
- this.setAnimationState(EvotarSpriteTags.Land);
316
- this.landTimer = new Timer(200, () => {
317
- this.setAnimationState(EvotarSpriteTags.Idle);
318
- this.isJumping = false;
319
- });
320
- }
321
- }
322
-
323
- if (this.velocity.y > 0) {
324
- this.setAnimationState(EvotarSpriteTags.Fall);
325
- }
326
- }
327
-
328
- if (this.animationState != EvotarSpriteTags.Idle || this.isDashing) {
329
- const halfSpriteWidth =
330
- (collider.w / 2) * this.state.scale * this.spriteData.scale;
331
-
332
- const left = this.container.x - halfSpriteWidth < 0;
333
- const right = this.container.x + halfSpriteWidth > app.renderer.width;
334
-
335
- if (left || right) {
336
- this.state.direction = -this.state.direction;
337
- this.velocity.x = -this.velocity.x;
338
-
339
- if (left) {
340
- position.x = halfSpriteWidth;
341
- }
342
-
343
- if (right) {
344
- position.x = app.renderer.width - halfSpriteWidth;
345
- }
346
- }
347
- }
348
-
349
- this.container.position.set(position.x, position.y);
350
- }
351
-
352
- update(): void {
353
- if (this.isDespawned) {
354
- return;
355
- }
356
-
357
- this.landTimer?.tick();
358
- this.stateTimer?.tick();
359
- this.scaleTimer?.tick();
360
-
361
- this.fadeTween?.update();
362
- this.spawnTween?.update();
363
- this.scaleTween?.update();
364
-
365
- this.container.zIndex = this.state.zIndex;
366
-
367
- const collider = this.spriteData.collider;
368
-
369
- this.name.update({
370
- name: this.state.name,
371
- isVisible: !this.state.isAnonymous,
372
- position: {
373
- y: -collider.h * this.state.scale * this.spriteData.scale,
374
- },
375
- });
376
-
377
- this.message.update({
378
- position: {
379
- y: this.name.text.position.y - this.name.text.height - 6,
380
- },
381
- });
382
-
383
- this.emoteSpitter.update({
384
- position: {
385
- y: this.message.container.position.y - this.message.container.height,
386
- },
387
- });
388
-
389
- this.move();
390
-
391
- if (this.sprite) {
392
- const colors = Object.fromEntries(
393
- this.spriteData.colored.map((layer) => [
394
- layer,
395
- this.userState.color ? this.userState.color : this.state.color,
396
- ]),
397
- );
398
-
399
- const direction = this.spriteData.flip ? this.state.direction : 1;
400
-
401
- this.sprite.update({
402
- color: colors,
403
- scale: {
404
- x: direction * this.state.scale * this.spriteData.scale,
405
- y: this.state.scale * this.spriteData.scale,
406
- },
407
- play: !this.isDashing,
408
- });
409
- }
410
-
411
- this.trail.update({
412
- play: this.isDashing,
413
- });
414
- }
415
-
416
- isOnGround(y: number): boolean {
417
- return y > app.renderer.height;
418
- }
419
-
420
- addMessage(message: string): void {
421
- this.message.add(message);
422
- this.state.isAnonymous = false;
423
- this.fadeTween?.stop();
424
- this.fadeTween = undefined; // https://github.com/tweenjs/tween.js/issues/665
425
- this.container.alpha = 1;
426
- }
427
-
428
- async spitEmotes(emotes: string[]): Promise<void> {
429
- for (const emote of emotes) {
430
- await this.emoteSpitter.add(emote);
431
- }
432
- }
433
-
434
- async setAnimationState(
435
- state: EvotarSpriteTags,
436
- force = false,
437
- ): Promise<void> {
438
- if (this.animationState == state && !force) {
439
- return;
440
- }
441
-
442
- // TODO: Refactor sprite initializing, move logic to separate file
443
- if (!this.animatedSprites) {
444
- return;
445
- }
446
-
447
- this.animationState = state;
448
-
449
- if (this.sprite) {
450
- this.container.removeChild(this.sprite.container);
451
- }
452
-
453
- const animatedSprites =
454
- this.animatedSprites![this.animationState] ??
455
- this.animatedSprites[EvotarSpriteTags.Idle];
456
-
457
- this.sprite = new EvotarSpriteContainer(animatedSprites);
458
-
459
- this.trail.setSprite(this.sprite);
460
-
461
- this.sprite.container.pivot.set(
462
- 0,
463
- this.spriteData.collider.y + this.spriteData.collider.h,
464
- );
465
-
466
- this.container.addChild(this.sprite.container);
467
- }
468
- }
@@ -1,164 +0,0 @@
1
- import { app } from '../app';
2
- import { Timer } from '../helpers/timer';
3
- import { Point } from '../helpers/types';
4
- import { Tween } from '@tweenjs/tween.js';
5
- import * as PIXI from 'pixi.js';
6
-
7
- export type EvotarMesageProps = {
8
- position: Point;
9
- };
10
-
11
- export class EvotarMessage {
12
- public container: PIXI.Container = new PIXI.Container();
13
- public animated: PIXI.Container = new PIXI.Container();
14
-
15
- private text: PIXI.Text = new PIXI.Text(undefined, {
16
- fontFamily: app.font,
17
- fontSize: 20,
18
- fill: 0x222222,
19
- align: 'left',
20
- breakWords: true,
21
- wordWrap: true,
22
- wordWrapWidth: 200,
23
- });
24
-
25
- private padding = 10;
26
- private borderRadius = 10;
27
- private boxColor = 0xeeeeee;
28
-
29
- private fadeShift = 10;
30
-
31
- private isChecking = true;
32
-
33
- private messageQueue: string[] = [];
34
-
35
- private showTween?: Tween<PIXI.Container>;
36
- private hideTween?: Tween<PIXI.Container>;
37
-
38
- private timer?: Timer;
39
-
40
- constructor(private beforeShow: () => void) {
41
- this.container.addChild(this.animated);
42
-
43
- this.text.anchor.set(0.5, 1);
44
- this.text.position.set(0, -this.padding);
45
- }
46
-
47
- private trim(text: PIXI.Text): string {
48
- const metrics = PIXI.TextMetrics.measureText(text.text, text.style);
49
-
50
- return metrics.lines.length > 4
51
- ? metrics.lines.slice(0, 4).join(' ').slice(0, -3) + '...'
52
- : text.text;
53
- }
54
-
55
- public update(props: EvotarMesageProps): void {
56
- this.timer?.tick();
57
-
58
- this.showTween?.update();
59
- this.hideTween?.update();
60
-
61
- if (this.isChecking && this.messageQueue.length > 0) {
62
- this.isChecking = false;
63
-
64
- const message = this.messageQueue.shift();
65
-
66
- if (message) {
67
- this.beforeShow();
68
- this.show(message);
69
- }
70
- }
71
-
72
- this.container.position.x = props.position.x ?? this.container.position.x;
73
- this.container.position.y = props.position.y ?? this.container.position.y;
74
-
75
- const isAnimationPlaying =
76
- this.showTween?.isPlaying() || this.hideTween?.isPlaying();
77
-
78
- if (!this.isChecking && !isAnimationPlaying && this.timer) {
79
- this.animated.position.y = Math.sin(this.timer.current * 0.0025) * 4 - 2;
80
- }
81
- }
82
-
83
- public add(message: string): void {
84
- this.messageQueue.push(message);
85
- }
86
-
87
- private drawBox(text: PIXI.Text) {
88
- const roundedRect = {
89
- x: text.x - this.padding - text.width * text.anchor.x,
90
- y: text.y - this.padding - text.height * text.anchor.y,
91
- w: text.width + this.padding * 2,
92
- h: text.height + this.padding * 2,
93
- };
94
-
95
- const box = new PIXI.Graphics();
96
- box.beginFill(this.boxColor);
97
-
98
- box.drawRoundedRect(
99
- roundedRect.x,
100
- roundedRect.y,
101
- roundedRect.w,
102
- roundedRect.h,
103
- this.borderRadius,
104
- );
105
-
106
- box.drawPolygon(
107
- {
108
- x: roundedRect.x + roundedRect.w / 2 - 10,
109
- y: roundedRect.y + roundedRect.h,
110
- },
111
- {
112
- x: roundedRect.x + roundedRect.w / 2 + 10,
113
- y: roundedRect.y + roundedRect.h,
114
- },
115
- {
116
- x: roundedRect.x + roundedRect.w / 2,
117
- y: roundedRect.y + roundedRect.h + 10 - 4,
118
- },
119
- );
120
-
121
- box.endFill();
122
-
123
- return box;
124
- }
125
-
126
- private show(message: string): void {
127
- this.text.text = message;
128
- this.text.text = this.trim(this.text);
129
-
130
- this.animated.alpha = 0;
131
- this.animated.position.y = this.fadeShift;
132
-
133
- const box = this.drawBox(this.text);
134
-
135
- this.animated.removeChildren();
136
- this.animated.addChild(box, this.text);
137
-
138
- const showProps = {
139
- alpha: 1,
140
- y: this.animated.y - this.fadeShift,
141
- };
142
-
143
- const hideProps = {
144
- alpha: 0,
145
- y: this.animated.y + this.fadeShift,
146
- };
147
-
148
- this.hideTween = new Tween(this.animated)
149
- .to(hideProps, 500)
150
- .onComplete(() => {
151
- this.isChecking = true;
152
- });
153
-
154
- this.showTween = new Tween(this.animated)
155
- .to(showProps, 500)
156
- .onComplete(() => {
157
- this.timer = new Timer(10000, () => {
158
- this.hideTween?.start();
159
- });
160
- });
161
-
162
- this.showTween.start();
163
- }
164
- }
@@ -1,33 +0,0 @@
1
- import { app } from '../app';
2
- import { Point } from '../helpers/types';
3
- import * as PIXI from 'pixi.js';
4
-
5
- export type EvotarNameProps = {
6
- name: string;
7
- position: Point;
8
- isVisible: boolean;
9
- };
10
-
11
- export class EvotarName {
12
- public text: PIXI.Text = new PIXI.Text(undefined, {
13
- fontFamily: app.font,
14
- fontSize: 18,
15
- fill: 0xffffff,
16
- align: 'center',
17
- lineJoin: 'round',
18
- strokeThickness: 4,
19
- stroke: 'black',
20
- });
21
-
22
- constructor() {
23
- this.text.anchor.set(0.5, 1);
24
- this.text.zIndex = 100;
25
- }
26
-
27
- update(props: EvotarNameProps) {
28
- this.text.text = props.name ?? '';
29
- this.text.visible = props.isVisible;
30
- this.text.position.x = props.position.x ?? this.text.position.x;
31
- this.text.position.y = props.position.y ?? this.text.position.y;
32
- }
33
- }