evotars 0.0.7 → 0.0.9

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 (80) hide show
  1. package/.editorconfig +13 -0
  2. package/.prettierrc.json +3 -0
  3. package/README.md +3 -5
  4. package/index.html +13 -0
  5. package/package.json +3 -16
  6. package/playground/main.ts +48 -0
  7. package/playground/styles.css +17 -0
  8. package/public/evotars/agent/data.json +18 -0
  9. package/public/evotars/agent/sprite.json +166 -0
  10. package/public/evotars/agent/sprite.png +0 -0
  11. package/public/evotars/cat/data.json +18 -0
  12. package/public/evotars/cat/sprite.json +231 -0
  13. package/public/evotars/cat/sprite.png +0 -0
  14. package/public/evotars/dude/data.json +18 -0
  15. package/public/evotars/dude/sprite.json +231 -0
  16. package/public/evotars/dude/sprite.png +0 -0
  17. package/public/evotars/girl/data.json +18 -0
  18. package/public/evotars/girl/sprite.json +231 -0
  19. package/public/evotars/girl/sprite.png +0 -0
  20. package/public/evotars/nerd/data.json +18 -0
  21. package/public/evotars/nerd/sprite.json +231 -0
  22. package/public/evotars/nerd/sprite.png +0 -0
  23. package/public/evotars/senior/data.json +18 -0
  24. package/public/evotars/senior/sprite.json +231 -0
  25. package/public/evotars/senior/sprite.png +0 -0
  26. package/public/evotars/set.json +10 -0
  27. package/public/evotars/sith/data.json +18 -0
  28. package/public/evotars/sith/sprite.json +166 -0
  29. package/public/evotars/sith/sprite.png +0 -0
  30. package/public/evotars/sponge/data.json +18 -0
  31. package/public/evotars/sponge/sprite.json +231 -0
  32. package/public/evotars/sponge/sprite.png +0 -0
  33. package/public/fonts/Rubik.ttf +0 -0
  34. package/public/sounds/jump.mp3 +0 -0
  35. package/src/app.ts +71 -0
  36. package/src/config/constants.ts +1 -0
  37. package/src/entities/EmoteSpitter.ts +102 -0
  38. package/src/entities/Evotar.ts +468 -0
  39. package/src/entities/Message.ts +164 -0
  40. package/src/entities/Name.ts +33 -0
  41. package/src/entities/SpriteContainer.ts +65 -0
  42. package/src/entities/TrailEffect.ts +73 -0
  43. package/src/evotars.ts +75 -0
  44. package/src/evotarsManager.ts +313 -0
  45. package/src/helpers/timer.ts +43 -0
  46. package/src/helpers/types.ts +4 -0
  47. package/src/services/soundService.ts +30 -0
  48. package/src/services/spriteService.ts +167 -0
  49. package/src/types/dto/action.ts +79 -0
  50. package/{dist/types/dto/chatter.d.ts → src/types/dto/chatter.ts} +2 -2
  51. package/src/types/dto/event.ts +9 -0
  52. package/src/types/dto/message.ts +8 -0
  53. package/src/types/dto/settings.ts +5 -0
  54. package/src/types/dto/user.ts +13 -0
  55. package/tsconfig.json +23 -0
  56. package/vite.config.js +26 -0
  57. package/dist/app.d.ts +0 -24
  58. package/dist/config/constants.d.ts +0 -1
  59. package/dist/entities/EmoteSpitter.d.ts +0 -15
  60. package/dist/entities/Evotar.d.ts +0 -78
  61. package/dist/entities/Message.d.ts +0 -27
  62. package/dist/entities/Name.d.ts +0 -14
  63. package/dist/entities/SpriteContainer.d.ts +0 -16
  64. package/dist/entities/TrailEffect.d.ts +0 -15
  65. package/dist/evotars.d.ts +0 -15
  66. package/dist/evotars.js +0 -705
  67. package/dist/evotars.umd.cjs +0 -1
  68. package/dist/evotarsManager.d.ts +0 -30
  69. package/dist/helpers/timer.d.ts +0 -14
  70. package/dist/helpers/types.d.ts +0 -10
  71. package/dist/services/soundService.d.ts +0 -14
  72. package/dist/services/spriteService.d.ts +0 -63
  73. package/dist/types/dto/action.d.ts +0 -56
  74. package/dist/types/dto/event.d.ts +0 -9
  75. package/dist/types/dto/message.d.ts +0 -8
  76. package/dist/types/dto/settings.d.ts +0 -5
  77. package/dist/types/dto/user.d.ts +0 -12
  78. /package/{dist/index.d.ts → src/index.ts} +0 -0
  79. /package/{dist/types/dto/index.d.ts → src/types/dto/index.ts} +0 -0
  80. /package/{dist/types/index.d.ts → src/types/index.ts} +0 -0
@@ -0,0 +1,468 @@
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
+ }
@@ -0,0 +1,164 @@
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
+ }
@@ -0,0 +1,33 @@
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
+ }