@Override public void update(float timeDelta, BaseObject parent) { if (mSprite != null) { GameObject parentObject = (GameObject) parent; final float velocityX = parentObject.getVelocity().x; GameObject.ActionType currentAction = parentObject.getCurrentAction(); switch (mState) { case IDLING: mSprite.playAnimation(EnemyAnimations.IDLE.ordinal()); if (mFacePlayer) { facePlayer(parentObject); } if (currentAction == GameObject.ActionType.ATTACK) { mState = AnimationState.ATTACKING; } else if (currentAction == GameObject.ActionType.HIDE) { mState = AnimationState.HIDING; } else if (Math.abs(velocityX) > 0.0f) { mState = AnimationState.MOVING; } break; case MOVING: mSprite.playAnimation(EnemyAnimations.MOVE.ordinal()); final float targetVelocityX = parentObject.getTargetVelocity().x; if (!Utils.close(velocityX, 0.0f)) { if (velocityX < 0.0f && targetVelocityX < 0.0f) { parentObject.facingDirection.x = -1.0f; } else if (velocityX > 0.0f && targetVelocityX > 0.0f) { parentObject.facingDirection.x = 1.0f; } } if (currentAction == GameObject.ActionType.ATTACK) { mState = AnimationState.ATTACKING; } else if (currentAction == GameObject.ActionType.HIDE) { mState = AnimationState.HIDING; } else if (Math.abs(velocityX) == 0.0f) { mState = AnimationState.IDLING; } break; case ATTACKING: mSprite.playAnimation(EnemyAnimations.ATTACK.ordinal()); if (currentAction != GameObject.ActionType.ATTACK && mSprite.animationFinished()) { mState = AnimationState.IDLING; } break; case HIDING: mSprite.playAnimation(EnemyAnimations.HIDDEN.ordinal()); if (currentAction != GameObject.ActionType.HIDE) { mState = AnimationState.APPEARING; } break; case APPEARING: if (mFacePlayer) { facePlayer(parentObject); } mSprite.playAnimation(EnemyAnimations.APPEAR.ordinal()); if (mSprite.animationFinished()) { mState = AnimationState.IDLING; } break; } } }
@Override public void update(float timeDelta, BaseObject parent) { if (mSprite != null) { GameObject parentObject = (GameObject) parent; final float velocityX = parentObject.getVelocity().x; final float velocityY = parentObject.getVelocity().y; GameObject.ActionType currentAction = parentObject.getCurrentAction(); if (mJetSprite != null) { mJetSprite.setVisible(false); } if (mSparksSprite != null) { mSparksSprite.setVisible(false); } final TimeSystem time = sSystemRegistry.timeSystem; final float gameTime = time.getGameTime(); if (currentAction != ActionType.HIT_REACT && mPreviousAction == ActionType.HIT_REACT) { mFlickerTimeRemaining = FLICKER_DURATION; } final boolean touchingGround = parentObject.touchingGround(); boolean boosting = mPlayer != null ? mPlayer.getRocketsOn() : false; boolean visible = true; SoundSystem sound = sSystemRegistry.soundSystem; // It's usually not necessary to test to see if sound is enabled or not (when it's disabled, // play() is just a nop), but in this case I have a stream that is maintained for the rocket // sounds. So it's simpler to just avoid that code if sound is off. if (sound.getSoundEnabled()) { if (boosting) { mLastRocketsOnTime = gameTime; } else { if (gameTime - mLastRocketsOnTime < MIN_ROCKET_TIME && velocityY >= 0.0f) { boosting = true; } } if (mRocketSound != null) { if (boosting) { if (mRocketSoundStream == -1) { mRocketSoundStream = sound.play(mRocketSound, true, SoundSystem.PRIORITY_HIGH); mRocketSoundPaused = false; } else if (mRocketSoundPaused) { sound.resume(mRocketSoundStream); mRocketSoundPaused = false; } } else { sound.pause(mRocketSoundStream); mRocketSoundPaused = true; } } } // Normally, for collectables like the coin, we could just tell the object to play // a sound when it is collected. The gems are a special case, though, as we // want to pick a different sound depending on how many have been collected. if (mInventory != null && mRubySound1 != null && mRubySound2 != null && mRubySound3 != null) { InventoryComponent.UpdateRecord inventory = mInventory.getRecord(); final int rubyCount = inventory.rubyCount; if (rubyCount != mLastRubyCount) { mLastRubyCount = rubyCount; switch (rubyCount) { case 1: sound.play(mRubySound1, false, SoundSystem.PRIORITY_NORMAL); break; case 2: sound.play(mRubySound2, false, SoundSystem.PRIORITY_NORMAL); break; case 3: sound.play(mRubySound3, false, SoundSystem.PRIORITY_NORMAL); break; } } } // Turn on visual effects (smoke, etc) when the player's life reaches 1. if (mDamageSwap != null) { if (parentObject.life == 1 && !mDamageSwap.getCurrentlySwapped()) { mDamageSwap.activate(parentObject); } else if (parentObject.life != 1 && mDamageSwap.getCurrentlySwapped()) { mDamageSwap.activate(parentObject); } } float opacity = 1.0f; if (currentAction == ActionType.MOVE) { InputGameInterface input = sSystemRegistry.inputGameInterface; final InputXY dpad = input.getDirectionalPad(); if (dpad.getX() < 0.0f) { parentObject.facingDirection.x = -1.0f; } else if (dpad.getX() > 0.0f) { parentObject.facingDirection.x = 1.0f; } // TODO: get rid of these magic numbers! if (touchingGround) { if (Utils.close(velocityX, 0.0f, 30.0f)) { mSprite.playAnimation(PlayerAnimations.IDLE.ordinal()); } else if (Math.abs(velocityX) > 300.0f) { mSprite.playAnimation(PlayerAnimations.MOVE_FAST.ordinal()); } else { mSprite.playAnimation(PlayerAnimations.MOVE.ordinal()); } final InputButton attackButton = input.getAttackButton(); if (attackButton.getPressed()) { // charge final float pressedTime = gameTime - attackButton.getLastPressedTime(); final float wave = (float) Math.cos(pressedTime * (float) Math.PI * 2.0f); opacity = (wave * 0.25f) + 0.75f; } } else { if (boosting) { if (mJetSprite != null) { mJetSprite.setVisible(true); } if (Math.abs(velocityX) < 100.0f && velocityY > 10.0f) { mSprite.playAnimation(PlayerAnimations.BOOST_UP.ordinal()); } else if (Math.abs(velocityX) > 300.0f) { mSprite.playAnimation(PlayerAnimations.BOOST_MOVE_FAST.ordinal()); } else { mSprite.playAnimation(PlayerAnimations.BOOST_MOVE.ordinal()); } } else { if (Utils.close(velocityX, 0.0f, 1.0f)) { mSprite.playAnimation(PlayerAnimations.IDLE.ordinal()); } else if (Math.abs(velocityX) > 300.0f) { mSprite.playAnimation(PlayerAnimations.MOVE_FAST.ordinal()); } else { mSprite.playAnimation(PlayerAnimations.MOVE.ordinal()); } } } } else if (currentAction == ActionType.ATTACK) { mSprite.playAnimation(PlayerAnimations.STOMP.ordinal()); if (touchingGround && gameTime > mLandThumpDelay) { if (mLandThump != null && sound != null) { // modulate the sound slightly to avoid sounding too similar sound.play( mLandThump, false, SoundSystem.PRIORITY_HIGH, 1.0f, (float) (Math.random() * 0.5f) + 0.75f); mLandThumpDelay = gameTime + LAND_THUMP_DELAY; } } } else if (currentAction == ActionType.HIT_REACT) { mSprite.playAnimation(PlayerAnimations.HIT_REACT.ordinal()); if (velocityX > 0.0f) { parentObject.facingDirection.x = -1.0f; } else if (velocityX < 0.0f) { parentObject.facingDirection.x = 1.0f; } if (mSparksSprite != null) { mSparksSprite.setVisible(true); } } else if (currentAction == ActionType.DEATH) { if (mPreviousAction != currentAction) { if (mExplosionSound != null) { sound.play(mExplosionSound, false, SoundSystem.PRIORITY_NORMAL); } // by default, explode when hit with the DEATH hit type. boolean explodingDeath = parentObject.lastReceivedHitType == HitType.DEATH; // or if touching a death tile. HotSpotSystem hotSpot = sSystemRegistry.hotSpotSystem; if (hotSpot != null) { // TODO: HACK! Unify all this code. if (hotSpot.getHotSpot( parentObject.getCenteredPositionX(), parentObject.getPosition().y + 10.0f) == HotSpotSystem.HotSpotType.DIE) { explodingDeath = true; } } if (explodingDeath) { mExplodingDeath = true; GameObjectFactory factory = sSystemRegistry.gameObjectFactory; GameObjectManager manager = sSystemRegistry.gameObjectManager; if (factory != null && manager != null) { GameObject explosion = factory.spawnEffectExplosionGiant( parentObject.getPosition().x, parentObject.getPosition().y); if (explosion != null) { manager.add(explosion); } } } else { mSprite.playAnimation(PlayerAnimations.DEATH.ordinal()); mExplodingDeath = false; } mFlickerTimeRemaining = 0.0f; if (mSparksSprite != null) { if (!mSprite.animationFinished()) { mSparksSprite.setVisible(true); } } } if (mExplodingDeath) { visible = false; } } else if (currentAction == ActionType.FROZEN) { mSprite.playAnimation(PlayerAnimations.FROZEN.ordinal()); } if (mFlickerTimeRemaining > 0.0f) { mFlickerTimeRemaining -= timeDelta; if (gameTime > mLastFlickerTime + FLICKER_INTERVAL) { mLastFlickerTime = gameTime; mFlickerOn = !mFlickerOn; } mSprite.setVisible(mFlickerOn); if (mJetSprite != null && mJetSprite.getVisible()) { mJetSprite.setVisible(mFlickerOn); } } else { mSprite.setVisible(visible); mSprite.setOpacity(opacity); } mPreviousAction = currentAction; } }