selectReveal(sdkCard) {
    // reset
    if (sdkCard != null) {
      this.setSdkCard(sdkCard);
    } else {
      this.hideSnapshot();
    }

    if (this.sdkCard != null) {
      return new Promise((resolve, reject) => {
        // speed for phase 1 of animation (rotation + outline)
        const rotationSpeed = 0.5;
        // speed for phase 2 of animation (elements appear on card)
        const animationSpeed = 0.5;
        // amount of time of rotation
        const rotateTime = 1.0;
        // starting time for animation of non-rotation elements
        const baseTime = rotateTime - 0.1;

        // custom back easing with heavy overshoot
        const customEaseBackOut = {
          easing(time1) {
            const overshoot = 4.70158;
            time1 -= 1;
            return time1 * time1 * ((overshoot + 1) * time1 + overshoot) + 1;
          },
        };

        // stop all animations
        this.stopAnimations();

        // Prevent asset popping by waiting to be visible until after assets are ready
        this._containerNode.setVisible(false);

        Promise.all([
          this.whenRequiredResourcesReady(),
          this.whenResourcesReady(this.getCardResourceRequestId()),
        ])
          .spread((requiredRequestId, cardResourceRequestId) => {
            if (!this.getAreResourcesValid(requiredRequestId) || !this.getAreResourcesValid(cardResourceRequestId)) return; // load invalidated or resources changed

            // begin: animation base states
            this.cardBackgroundSprite.setOpacity(0.0);
            this._outlineGlow.setOpacity(0.0);
            this._outlineGlowAlt.setOpacity(0.0);
            this._unitShadow.setOpacity(0);
            this.cardNameLabel.setOpacity(0);
            this.cardTypeLabel.setOpacity(0);
            if (this.raritySprite != null) {
              this.raritySprite.setOpacity(0);
            }
            this.hpLabel.setOpacity(0);
            this.atkLabel.setOpacity(0);
            this.cardDescriptionLabel.setOpacity(0);

            this.cardSprite.setOpacity(0);
            if (this.sdkCard instanceof SDK.Entity && this.sdkCard.getWasGeneral()) {
              if (this._signatureCardRing != null) {
                this._signatureCardRing.setOpacity(0);
              }
              if (this._signatureCardSprite != null) {
                this._signatureCardSprite.setOpacity(0);
              }
            } else {
              this._manaGemSprite.setOpacity(0);
              this.manaLabel.setOpacity(0);
            }
            this._containerNode.setVisible(true);
            // end: animation base states

            // animation order: cardback, managem, spriteshadow, sprite, name, type, rarity sprite, description text

            const cardBackAction = cc.sequence(
              cc.delayTime(0.6 * rotationSpeed),
              cc.fadeIn(0.3 * rotationSpeed).easing(cc.easeIn(1.0)),
            );
            this.addAnimationAction(cardBackAction);
            this.cardBackgroundSprite.runAction(cardBackAction);

            const glowAction = cc.sequence(
              cc.show(),
              cc.fadeIn(0.3 * rotationSpeed).easing(cc.easeIn(1.0)),
              cc.delayTime(0.5 * rotationSpeed),
              cc.fadeOut(0.3 * rotationSpeed).easing(cc.easeOut(1.0)),
              cc.hide(),
            );
            this.addAnimationAction(glowAction);
            this._outlineGlow.runAction(glowAction);

            const glowActionTwo = cc.sequence(
              cc.show(),
              cc.delayTime(0.3 * rotationSpeed),
              cc.fadeIn(0.3 * rotationSpeed).easing(cc.easeIn(1.0)),
              cc.fadeOut(0.3 * rotationSpeed).easing(cc.easeOut(1.0)),
              cc.hide(),
            );
            this.addAnimationAction(glowActionTwo);
            this._outlineGlowAlt.runAction(glowActionTwo);

            if (this.sdkCard instanceof SDK.Entity && this.sdkCard.getWasGeneral()) {
              if (this._signatureCardRing != null) {
                this._signatureCardRing.setVisible(true);
                const signatureCardRingAction = cc.spawn(
                  cc.sequence(
                    cc.delayTime(baseTime * animationSpeed),
                    cc.fadeIn(0.1 * animationSpeed),
                  ),
                  cc.sequence(
                    cc.scaleTo(0, 1.1, 1.1),
                    cc.delayTime(baseTime * animationSpeed),
                    cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                  ),
                );
                this.addAnimationAction(signatureCardRingAction);
                this._signatureCardRing.runAction(signatureCardRingAction);
              }

              if (this._signatureCardSprite != null) {
                this._signatureCardSprite.setVisible(true);
                const signatureCardSpriteAction = cc.spawn(
                  cc.sequence(
                    cc.delayTime(baseTime * animationSpeed),
                    cc.fadeIn(0.1 * animationSpeed),
                  ),
                  cc.sequence(
                    cc.scaleTo(0, 1.1, 1.1),
                    cc.delayTime(baseTime * animationSpeed),
                    cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                  ),
                );
                this.addAnimationAction(signatureCardSpriteAction);
                this._signatureCardSprite.runAction(signatureCardSpriteAction);
              }
            } else {
              const manaGemAction = cc.spawn(
                cc.sequence(
                  cc.delayTime(baseTime * animationSpeed),
                  cc.fadeIn(0.1 * animationSpeed),
                ),
                cc.sequence(
                  cc.scaleTo(0, 1.1, 1.1),
                  cc.delayTime(baseTime * animationSpeed),
                  cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                ),
              );
              this.addAnimationAction(manaGemAction);
              this._manaGemSprite.runAction(manaGemAction);

              const manaLabelAction = cc.sequence(
                cc.delayTime((baseTime + 0.08) * animationSpeed),
                cc.fadeIn(0.1 * rotationSpeed).easing(cc.easeOut(1.0)),
              );
              this.addAnimationAction(manaLabelAction);
              this.manaLabel.runAction(manaLabelAction);
            }

            if (!(this.sdkCard instanceof SDK.Tile)) {
              const unitShadowAction = cc.sequence(
                cc.delayTime((baseTime - 0.05) * animationSpeed),
                cc.fadeTo(0.1 * animationSpeed, 150.0).easing(cc.easeOut(1.0)),
              );
              this.addAnimationAction(unitShadowAction);
              this._unitShadow.runAction(unitShadowAction);
            }

            this.cardSprite.setTint(new cc.Color(255, 255, 255, 255));
            const cardSpriteAction = cc.spawn(
              cc.sequence(
                cc.delayTime((baseTime + 0.1) * animationSpeed),
                cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
              ),
              cc.sequence(
                cc.delayTime((baseTime + 0.2) * animationSpeed),
                cc.actionTween(0.1 * animationSpeed, TweenTypes.TINT_FADE, 255.0, 0.0).easing(cc.easeIn(1.0)),
              ),
            );
            this.addAnimationAction(cardSpriteAction);
            this.cardSprite.runAction(cardSpriteAction);

            const cardNameLabelAction = cc.spawn(
              cc.sequence(
                cc.delayTime((baseTime + 0.2) * animationSpeed),
                cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
              ),
              cc.sequence(
                cc.scaleTo(0, 1.2, 1.2),
                cc.delayTime((baseTime + 0.2) * animationSpeed),
                cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
              ),
            );
            this.addAnimationAction(cardNameLabelAction);
            this.cardNameLabel.runAction(cardNameLabelAction);

            const cardTypeLabelAction = cc.spawn(
              cc.sequence(
                cc.delayTime((baseTime + 0.3) * animationSpeed),
                cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
              ),
              cc.sequence(
                cc.scaleTo(0, 1.2, 1.2),
                cc.delayTime((baseTime + 0.3) * animationSpeed),
                cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
              ),
            );
            this.addAnimationAction(cardTypeLabelAction);
            this.cardTypeLabel.runAction(cardTypeLabelAction);

            if (this.raritySprite != null) {
              const raritySpriteAction = cc.spawn(
                cc.sequence(
                  cc.delayTime((baseTime + 0.5) * animationSpeed),
                  cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
                ),
                cc.sequence(
                  cc.scaleTo(0, 1.35, 1.35),
                  cc.delayTime((baseTime + 0.5) * animationSpeed),
                  cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                ),
              );
              this.addAnimationAction(raritySpriteAction);
              this.raritySprite.runAction(raritySpriteAction);
            }

            if (this.sdkCard instanceof SDK.Entity) {
              const hpLabelAction = cc.spawn(
                cc.sequence(
                  cc.delayTime((baseTime + 0.7) * animationSpeed),
                  cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
                ),
                cc.sequence(
                  cc.scaleTo(0, 1.5, 1.5),
                  cc.delayTime((baseTime + 0.7) * animationSpeed),
                  cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                ),
              );
              this.addAnimationAction(hpLabelAction);
              this.hpLabel.runAction(hpLabelAction);

              const atkLabelAction = cc.spawn(
                cc.sequence(
                  cc.delayTime((baseTime + 0.7) * animationSpeed),
                  cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
                ),
                cc.sequence(
                  cc.scaleTo(0, 1.5, 1.5),
                  cc.delayTime((baseTime + 0.7) * animationSpeed),
                  cc.scaleTo(0.2 * animationSpeed, 1, 1).easing(cc.easeOut(1.0)),
                ),
              );
              this.addAnimationAction(atkLabelAction);
              this.atkLabel.runAction(atkLabelAction);

              var cardDescriptionLabelAction = cc.sequence(
                cc.delayTime((baseTime + 0.9) * animationSpeed),
                cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
              );
              this.addAnimationAction(cardDescriptionLabelAction);
              this.cardDescriptionLabel.runAction(cardDescriptionLabelAction);
            } else {
              var cardDescriptionLabelAction = cc.sequence(
                cc.delayTime((baseTime + 0.7) * animationSpeed),
                cc.fadeIn(0.1 * animationSpeed).easing(cc.easeOut(1.0)),
              );
              this.addAnimationAction(cardDescriptionLabelAction);
              this.cardDescriptionLabel.runAction(cardDescriptionLabelAction);
            }

            this.setSecondaryXYZRotation(new cc.kmVec3(-45, 35, 0));
            this.setScale(0.8);
            const revealAction = cc.spawn(
              SecondaryXYZRotateBy.create(rotateTime * rotationSpeed, 45, -35, 0).easing(customEaseBackOut),
              cc.scaleTo(rotateTime * rotationSpeed, 1, 1).easing(customEaseBackOut),
              cc.sequence(
                cc.delayTime(rotateTime * rotationSpeed),
                cc.callFunc(() => {
                  resolve();
                }),
              ),
            );
            this.addAnimationAction(revealAction);
            this.runAction(revealAction);
          });
      })
        .catch((error) => { EventBus.getInstance().trigger(EVENTS.error, error); });
    }
    return Promise.resolve();
  }
Shows a card being revealed for selection.
@param sdkCard
@returns {Promise}