All files / src/model ticker.ts

100% Statements 13/13
100% Branches 2/2
100% Functions 4/4
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 9722x                                                                                                                                             22x 12x     12x 12x 12x 3613x 3605x   3613x 4x 4x           3746x       3617x      
import { NumberLabel, NumberLabelImpl, NumberLabelOptions } from './numberLabel'
 
/**
 * {@link Ticker} の状態.
 *
 * 'enabled': 残り時間の変更を許可します.
 *
 * 'disabled': 残り時間を変更しようとしても無視します.
 */
export type TickerStatus = 'enabled' | 'disabled'
 
/**
 * ゲームの残り時間を制御、描画します.
 */
export interface Ticker extends NumberLabel {
  /**
   * 残り時間が 0 になった際に発火するトリガ
   */
  readonly onExpire: g.Trigger
  /**
   * 残り時間を取得します. (秒単位、0秒以上、小数点以下切り捨て)
   */
  readonly value: number
 
  /**
   * 残り時間を取得します. (フレーム単位、負の値あり、小数点以下あり)
   */
  readonly rawValue: number
 
  /**
   * 残り時間の変更を受け付けるか状態を取得します
   */
  readonly status: TickerStatus
 
  /**
   * ライブラリ利用者が自由に使えるフィールドです.
   */
  vars?: unknown
 
  /**
   * 残り時間の値 (フレーム数) を追加します.
   *
   * カウントダウン形式の場合、引数に負の値を設定してください.
   *
   * @param frame 追加する値 (フレーム数)
   */
  add (frame: number): void
 
  /**
   * 引数の値に残り時間 (フレーム数) を設定します.
   *
   * @param frame 設定する値
   */
  set (frame: number): void
 
  /**
   * 残り時間を設定できるようにします.
   */
  enable (): void
 
  /**
   * 残り時間を設定しようとしても無視します.
   */
  disable (): void
}
 
export type TickerOptions = Omit<NumberLabelOptions, 'value' | 'textAlign'> & {
  frame: number
  vars: unknown
}
 
export class TickerImpl extends NumberLabelImpl implements Ticker {
  readonly onExpire = new g.Trigger()
  vars?: unknown
  constructor ({ scene, frame, font, digit, prefix, suffix, vars }: TickerOptions) {
    super({ scene, value: frame, font, digit, prefix, suffix, textAlign: 'left' })
    this.vars = vars
    scene.onUpdate.add(() => {
      if (this.status === 'enabled') {
        this.add(-1)
      }
      if (this.rawValue <= 0) {
        this.disable()
        this.onExpire.fire()
      }
    })
  }
 
  override get value (): number {
    return Math.max(Math.floor(super.value / g.game.fps), 0)
  }
 
  get rawValue (): number {
    return super.value
  }
}