blob: ab4990e023f3508917e13167b091a4ccf2200080 [file] [log] [blame]
/*
* 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;
}
}