/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.replica.replicaisland; import com.replica.replicaisland.SoundSystem.Sound; public class DoorAnimationComponent extends GameComponent { public static final class Animation { // Animations public static final int CLOSED = 0; public static final int OPEN = 1; public static final int CLOSING = 2; public static final int OPENING = 3; } // State protected static final int STATE_CLOSED = 0; protected static final int STATE_OPEN = 1; protected static final int STATE_CLOSING = 2; protected static final int STATE_OPENING = 3; protected final static float DEFAULT_STAY_OPEN_TIME = 5.0f; private SpriteComponent mSprite; private int mState; private ChannelSystem.Channel mChannel; private SolidSurfaceComponent mSolidSurface; private float mStayOpenTime; private Sound mCloseSound; private Sound mOpenSound; public DoorAnimationComponent() { super(); setPhase(ComponentPhases.ANIMATION.ordinal()); reset(); } @Override public void reset() { mSprite = null; mState = STATE_CLOSED; mChannel = null; mSolidSurface = null; mStayOpenTime = DEFAULT_STAY_OPEN_TIME; mCloseSound = null; mOpenSound = null; } private void open(float timeSinceTriggered, GameObject parentObject) { if (mSprite != null) { final float openAnimationLength = mSprite.findAnimation(Animation.OPENING).getLength(); if (timeSinceTriggered > openAnimationLength) { // snap open. mSprite.playAnimation(Animation.OPEN); mState = STATE_OPEN; if (mSolidSurface != null) { parentObject.remove(mSolidSurface); } } else { float timeOffset = timeSinceTriggered; if (mState == STATE_CLOSING) { // opening and closing animations are the same length. // if we're in the middle of one and need to go to the other, // we can start the new one mid-way through so that the door appears to // simply reverse direction. timeOffset = openAnimationLength - mSprite.getCurrentAnimationTime(); } else { if (mSolidSurface != null) { parentObject.remove(mSolidSurface); } } mState = STATE_OPENING; mSprite.playAnimation(Animation.OPENING); mSprite.setCurrentAnimationTime(timeOffset); if (mOpenSound != null) { SoundSystem sound = sSystemRegistry.soundSystem; if (sound != null) { sound.play(mOpenSound, false, SoundSystem.PRIORITY_NORMAL); } } } } } private void close(float timeSinceTriggered, GameObject parentObject) { if (mSprite != null) { final float closeAnimationLength = mSprite.findAnimation(Animation.CLOSING).getLength(); if (timeSinceTriggered > mStayOpenTime + closeAnimationLength) { // snap open. mSprite.playAnimation(Animation.CLOSED); mState = STATE_CLOSED; if (mSolidSurface != null) { parentObject.add(mSolidSurface); } } else { float timeOffset = timeSinceTriggered - mStayOpenTime; if (mState == STATE_OPENING) { timeOffset = closeAnimationLength - mSprite.getCurrentAnimationTime(); } mState = STATE_CLOSING; mSprite.playAnimation(Animation.CLOSING); mSprite.setCurrentAnimationTime(timeOffset); if (mCloseSound != null) { SoundSystem sound = sSystemRegistry.soundSystem; if (sound != null) { sound.play(mCloseSound, false, SoundSystem.PRIORITY_NORMAL); } } } } } @Override public void update(float timeDelta, BaseObject parent) { if (mChannel != null) { if (mChannel.value != null && mChannel.value instanceof ChannelSystem.ChannelFloatValue) { final float lastPressedTime = ((ChannelSystem.ChannelFloatValue)mChannel.value).value; TimeSystem time = sSystemRegistry.timeSystem; final float gameTime = time.getGameTime(); final float delta = gameTime - lastPressedTime; if (delta < mStayOpenTime && (mState == STATE_CLOSED || mState == STATE_CLOSING)) { open(delta, (GameObject)parent); } else if (delta > mStayOpenTime && (mState == STATE_OPEN || mState == STATE_OPENING)) { close(delta, (GameObject)parent); } } } if (mSprite != null) { if (mState == STATE_OPENING && mSprite.animationFinished()) { mSprite.playAnimation(Animation.OPEN); mState = STATE_OPEN; } else if (mState == STATE_CLOSING && mSprite.animationFinished()) { mSprite.playAnimation(Animation.CLOSED); mState = STATE_CLOSED; if (mSolidSurface != null) { ((GameObject)parent).add(mSolidSurface); } } // Deal with the case where the animation and state are out of sync // (side-effect of possession). // TODO: figure out a better way to do this. if (mSprite.getCurrentAnimation() == Animation.OPENING && mState == STATE_CLOSED) { mSprite.playAnimation(Animation.CLOSING); mState = STATE_CLOSING; } } } public void setSprite(SpriteComponent sprite) { mSprite = sprite; } public void setChannel(ChannelSystem.Channel channel) { mChannel = channel; } public void setSolidSurface(SolidSurfaceComponent surface) { mSolidSurface = surface; } public void setStayOpenTime(float time) { mStayOpenTime = time; } public void setSounds(Sound openSound, Sound closeSound) { mOpenSound = openSound; mCloseSound = closeSound; } }