13c1e67e433728684b5f228c5d4f3e5b1457bb271sm/*
23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project
33c1e67e433728684b5f228c5d4f3e5b1457bb271sm *
43c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Licensed under the Apache License, Version 2.0 (the "License");
53c1e67e433728684b5f228c5d4f3e5b1457bb271sm * you may not use this file except in compliance with the License.
63c1e67e433728684b5f228c5d4f3e5b1457bb271sm * You may obtain a copy of the License at
73c1e67e433728684b5f228c5d4f3e5b1457bb271sm *
83c1e67e433728684b5f228c5d4f3e5b1457bb271sm *      http://www.apache.org/licenses/LICENSE-2.0
93c1e67e433728684b5f228c5d4f3e5b1457bb271sm *
103c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Unless required by applicable law or agreed to in writing, software
113c1e67e433728684b5f228c5d4f3e5b1457bb271sm * distributed under the License is distributed on an "AS IS" BASIS,
123c1e67e433728684b5f228c5d4f3e5b1457bb271sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133c1e67e433728684b5f228c5d4f3e5b1457bb271sm * See the License for the specific language governing permissions and
143c1e67e433728684b5f228c5d4f3e5b1457bb271sm * limitations under the License.
153c1e67e433728684b5f228c5d4f3e5b1457bb271sm */
163c1e67e433728684b5f228c5d4f3e5b1457bb271sm
173c1e67e433728684b5f228c5d4f3e5b1457bb271sm package com.replica.replicaisland;
18cfd74d65d832137e20e193c960802afba73b5d38sm
19cfd74d65d832137e20e193c960802afba73b5d38smimport com.replica.replicaisland.SoundSystem.Sound;
20cfd74d65d832137e20e193c960802afba73b5d38sm
21cfd74d65d832137e20e193c960802afba73b5d38smpublic class DoorAnimationComponent extends GameComponent {
22cfd74d65d832137e20e193c960802afba73b5d38sm
23cfd74d65d832137e20e193c960802afba73b5d38sm    public static final class Animation {
24cfd74d65d832137e20e193c960802afba73b5d38sm        // Animations
25cfd74d65d832137e20e193c960802afba73b5d38sm        public static final int CLOSED = 0;
26cfd74d65d832137e20e193c960802afba73b5d38sm        public static final int OPEN = 1;
27cfd74d65d832137e20e193c960802afba73b5d38sm        public static final int CLOSING = 2;
28cfd74d65d832137e20e193c960802afba73b5d38sm        public static final int OPENING = 3;
29cfd74d65d832137e20e193c960802afba73b5d38sm    }
30cfd74d65d832137e20e193c960802afba73b5d38sm
31cfd74d65d832137e20e193c960802afba73b5d38sm    // State
32cfd74d65d832137e20e193c960802afba73b5d38sm    protected static final int STATE_CLOSED = 0;
33cfd74d65d832137e20e193c960802afba73b5d38sm    protected static final int STATE_OPEN = 1;
34cfd74d65d832137e20e193c960802afba73b5d38sm    protected static final int STATE_CLOSING = 2;
35cfd74d65d832137e20e193c960802afba73b5d38sm    protected static final int STATE_OPENING = 3;
36cfd74d65d832137e20e193c960802afba73b5d38sm
37cfd74d65d832137e20e193c960802afba73b5d38sm    protected final static float DEFAULT_STAY_OPEN_TIME = 5.0f;
38cfd74d65d832137e20e193c960802afba73b5d38sm
39cfd74d65d832137e20e193c960802afba73b5d38sm    private SpriteComponent mSprite;
40cfd74d65d832137e20e193c960802afba73b5d38sm    private int mState;
41cfd74d65d832137e20e193c960802afba73b5d38sm    private ChannelSystem.Channel mChannel;
42cfd74d65d832137e20e193c960802afba73b5d38sm    private SolidSurfaceComponent mSolidSurface;
43cfd74d65d832137e20e193c960802afba73b5d38sm    private float mStayOpenTime;
44cfd74d65d832137e20e193c960802afba73b5d38sm    private Sound mCloseSound;
45cfd74d65d832137e20e193c960802afba73b5d38sm    private Sound mOpenSound;
46cfd74d65d832137e20e193c960802afba73b5d38sm
47cfd74d65d832137e20e193c960802afba73b5d38sm    public DoorAnimationComponent() {
48cfd74d65d832137e20e193c960802afba73b5d38sm        super();
49cfd74d65d832137e20e193c960802afba73b5d38sm        setPhase(ComponentPhases.ANIMATION.ordinal());
50cfd74d65d832137e20e193c960802afba73b5d38sm        reset();
51cfd74d65d832137e20e193c960802afba73b5d38sm    }
52cfd74d65d832137e20e193c960802afba73b5d38sm
53cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
54cfd74d65d832137e20e193c960802afba73b5d38sm    public void reset() {
55cfd74d65d832137e20e193c960802afba73b5d38sm        mSprite = null;
56cfd74d65d832137e20e193c960802afba73b5d38sm        mState = STATE_CLOSED;
57cfd74d65d832137e20e193c960802afba73b5d38sm        mChannel = null;
58cfd74d65d832137e20e193c960802afba73b5d38sm        mSolidSurface = null;
59cfd74d65d832137e20e193c960802afba73b5d38sm        mStayOpenTime = DEFAULT_STAY_OPEN_TIME;
60cfd74d65d832137e20e193c960802afba73b5d38sm        mCloseSound = null;
61cfd74d65d832137e20e193c960802afba73b5d38sm        mOpenSound = null;
62cfd74d65d832137e20e193c960802afba73b5d38sm    }
63cfd74d65d832137e20e193c960802afba73b5d38sm
64cfd74d65d832137e20e193c960802afba73b5d38sm    private void open(float timeSinceTriggered, GameObject parentObject) {
65cfd74d65d832137e20e193c960802afba73b5d38sm        if (mSprite != null) {
66cfd74d65d832137e20e193c960802afba73b5d38sm            final float openAnimationLength = mSprite.findAnimation(Animation.OPENING).getLength();
67cfd74d65d832137e20e193c960802afba73b5d38sm
68cfd74d65d832137e20e193c960802afba73b5d38sm
69cfd74d65d832137e20e193c960802afba73b5d38sm
70cfd74d65d832137e20e193c960802afba73b5d38sm            if (timeSinceTriggered > openAnimationLength) {
71cfd74d65d832137e20e193c960802afba73b5d38sm                // snap open.
72cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.OPEN);
73cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_OPEN;
74cfd74d65d832137e20e193c960802afba73b5d38sm                if (mSolidSurface != null) {
75cfd74d65d832137e20e193c960802afba73b5d38sm                    parentObject.remove(mSolidSurface);
76cfd74d65d832137e20e193c960802afba73b5d38sm                }
77cfd74d65d832137e20e193c960802afba73b5d38sm            } else {
78cfd74d65d832137e20e193c960802afba73b5d38sm                float timeOffset = timeSinceTriggered;
79cfd74d65d832137e20e193c960802afba73b5d38sm                if (mState == STATE_CLOSING) {
80cfd74d65d832137e20e193c960802afba73b5d38sm                    // opening and closing animations are the same length.
81cfd74d65d832137e20e193c960802afba73b5d38sm                    // if we're in the middle of one and need to go to the other,
82cfd74d65d832137e20e193c960802afba73b5d38sm                    // we can start the new one mid-way through so that the door appears to
83cfd74d65d832137e20e193c960802afba73b5d38sm                    // simply reverse direction.
84cfd74d65d832137e20e193c960802afba73b5d38sm                    timeOffset = openAnimationLength - mSprite.getCurrentAnimationTime();
85cfd74d65d832137e20e193c960802afba73b5d38sm                } else {
86cfd74d65d832137e20e193c960802afba73b5d38sm                	if (mSolidSurface != null) {
87cfd74d65d832137e20e193c960802afba73b5d38sm                        parentObject.remove(mSolidSurface);
88cfd74d65d832137e20e193c960802afba73b5d38sm                    }
89cfd74d65d832137e20e193c960802afba73b5d38sm                }
90cfd74d65d832137e20e193c960802afba73b5d38sm
91cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_OPENING;
92cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.OPENING);
93cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.setCurrentAnimationTime(timeOffset);
94cfd74d65d832137e20e193c960802afba73b5d38sm
95cfd74d65d832137e20e193c960802afba73b5d38sm                if (mOpenSound != null) {
96cfd74d65d832137e20e193c960802afba73b5d38sm                	SoundSystem sound = sSystemRegistry.soundSystem;
97cfd74d65d832137e20e193c960802afba73b5d38sm                	if (sound != null) {
98cfd74d65d832137e20e193c960802afba73b5d38sm                		sound.play(mOpenSound, false, SoundSystem.PRIORITY_NORMAL);
99cfd74d65d832137e20e193c960802afba73b5d38sm                	}
100cfd74d65d832137e20e193c960802afba73b5d38sm                }
101cfd74d65d832137e20e193c960802afba73b5d38sm            }
102cfd74d65d832137e20e193c960802afba73b5d38sm        }
103cfd74d65d832137e20e193c960802afba73b5d38sm    }
104cfd74d65d832137e20e193c960802afba73b5d38sm
105cfd74d65d832137e20e193c960802afba73b5d38sm    private void close(float timeSinceTriggered, GameObject parentObject) {
106cfd74d65d832137e20e193c960802afba73b5d38sm        if (mSprite != null) {
107cfd74d65d832137e20e193c960802afba73b5d38sm            final float closeAnimationLength = mSprite.findAnimation(Animation.CLOSING).getLength();
108cfd74d65d832137e20e193c960802afba73b5d38sm
109cfd74d65d832137e20e193c960802afba73b5d38sm            if (timeSinceTriggered > mStayOpenTime + closeAnimationLength) {
110cfd74d65d832137e20e193c960802afba73b5d38sm                // snap open.
111cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.CLOSED);
112cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_CLOSED;
113cfd74d65d832137e20e193c960802afba73b5d38sm                if (mSolidSurface != null) {
114cfd74d65d832137e20e193c960802afba73b5d38sm                    parentObject.add(mSolidSurface);
115cfd74d65d832137e20e193c960802afba73b5d38sm                }
116cfd74d65d832137e20e193c960802afba73b5d38sm            } else {
117cfd74d65d832137e20e193c960802afba73b5d38sm                float timeOffset = timeSinceTriggered - mStayOpenTime;
118cfd74d65d832137e20e193c960802afba73b5d38sm                if (mState == STATE_OPENING) {
119cfd74d65d832137e20e193c960802afba73b5d38sm                    timeOffset = closeAnimationLength - mSprite.getCurrentAnimationTime();
120cfd74d65d832137e20e193c960802afba73b5d38sm                }
121cfd74d65d832137e20e193c960802afba73b5d38sm
122cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_CLOSING;
123cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.CLOSING);
124cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.setCurrentAnimationTime(timeOffset);
125cfd74d65d832137e20e193c960802afba73b5d38sm                if (mCloseSound != null) {
126cfd74d65d832137e20e193c960802afba73b5d38sm                	SoundSystem sound = sSystemRegistry.soundSystem;
127cfd74d65d832137e20e193c960802afba73b5d38sm                	if (sound != null) {
128cfd74d65d832137e20e193c960802afba73b5d38sm                		sound.play(mCloseSound, false, SoundSystem.PRIORITY_NORMAL);
129cfd74d65d832137e20e193c960802afba73b5d38sm                	}
130cfd74d65d832137e20e193c960802afba73b5d38sm                }
131cfd74d65d832137e20e193c960802afba73b5d38sm            }
132cfd74d65d832137e20e193c960802afba73b5d38sm        }
133cfd74d65d832137e20e193c960802afba73b5d38sm    }
134cfd74d65d832137e20e193c960802afba73b5d38sm
135cfd74d65d832137e20e193c960802afba73b5d38sm
136cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
137cfd74d65d832137e20e193c960802afba73b5d38sm    public void update(float timeDelta, BaseObject parent) {
138cfd74d65d832137e20e193c960802afba73b5d38sm        if (mChannel != null) {
139cfd74d65d832137e20e193c960802afba73b5d38sm            if (mChannel.value != null && mChannel.value instanceof ChannelSystem.ChannelFloatValue) {
140cfd74d65d832137e20e193c960802afba73b5d38sm                final float lastPressedTime = ((ChannelSystem.ChannelFloatValue)mChannel.value).value;
141cfd74d65d832137e20e193c960802afba73b5d38sm                TimeSystem time = sSystemRegistry.timeSystem;
142cfd74d65d832137e20e193c960802afba73b5d38sm                final float gameTime = time.getGameTime();
143cfd74d65d832137e20e193c960802afba73b5d38sm                final float delta = gameTime - lastPressedTime;
144cfd74d65d832137e20e193c960802afba73b5d38sm                if (delta < mStayOpenTime
145cfd74d65d832137e20e193c960802afba73b5d38sm                        && (mState == STATE_CLOSED || mState == STATE_CLOSING)) {
146cfd74d65d832137e20e193c960802afba73b5d38sm                    open(delta, (GameObject)parent);
147cfd74d65d832137e20e193c960802afba73b5d38sm
148cfd74d65d832137e20e193c960802afba73b5d38sm                } else if (delta > mStayOpenTime
149cfd74d65d832137e20e193c960802afba73b5d38sm                        && (mState == STATE_OPEN || mState == STATE_OPENING)) {
150cfd74d65d832137e20e193c960802afba73b5d38sm                    close(delta, (GameObject)parent);
151cfd74d65d832137e20e193c960802afba73b5d38sm                }
152cfd74d65d832137e20e193c960802afba73b5d38sm            }
153cfd74d65d832137e20e193c960802afba73b5d38sm        }
154cfd74d65d832137e20e193c960802afba73b5d38sm        if (mSprite != null) {
155cfd74d65d832137e20e193c960802afba73b5d38sm
156cfd74d65d832137e20e193c960802afba73b5d38sm
157cfd74d65d832137e20e193c960802afba73b5d38sm            if (mState == STATE_OPENING && mSprite.animationFinished()) {
158cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.OPEN);
159cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_OPEN;
160cfd74d65d832137e20e193c960802afba73b5d38sm            } else if (mState == STATE_CLOSING && mSprite.animationFinished()) {
161cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.CLOSED);
162cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_CLOSED;
163cfd74d65d832137e20e193c960802afba73b5d38sm                if (mSolidSurface != null) {
164cfd74d65d832137e20e193c960802afba73b5d38sm                    ((GameObject)parent).add(mSolidSurface);
165cfd74d65d832137e20e193c960802afba73b5d38sm                }
166cfd74d65d832137e20e193c960802afba73b5d38sm            }
167cfd74d65d832137e20e193c960802afba73b5d38sm
168cfd74d65d832137e20e193c960802afba73b5d38sm            // Deal with the case where the animation and state are out of sync
169cfd74d65d832137e20e193c960802afba73b5d38sm            // (side-effect of possession).
170cfd74d65d832137e20e193c960802afba73b5d38sm            // TODO: figure out a better way to do this.
171cfd74d65d832137e20e193c960802afba73b5d38sm            if (mSprite.getCurrentAnimation() == Animation.OPENING && mState == STATE_CLOSED) {
172cfd74d65d832137e20e193c960802afba73b5d38sm                mSprite.playAnimation(Animation.CLOSING);
173cfd74d65d832137e20e193c960802afba73b5d38sm                mState = STATE_CLOSING;
174cfd74d65d832137e20e193c960802afba73b5d38sm            }
175cfd74d65d832137e20e193c960802afba73b5d38sm
176cfd74d65d832137e20e193c960802afba73b5d38sm        }
177cfd74d65d832137e20e193c960802afba73b5d38sm    }
178cfd74d65d832137e20e193c960802afba73b5d38sm
179cfd74d65d832137e20e193c960802afba73b5d38sm    public void setSprite(SpriteComponent sprite) {
180cfd74d65d832137e20e193c960802afba73b5d38sm        mSprite = sprite;
181cfd74d65d832137e20e193c960802afba73b5d38sm    }
182cfd74d65d832137e20e193c960802afba73b5d38sm
183cfd74d65d832137e20e193c960802afba73b5d38sm    public void setChannel(ChannelSystem.Channel channel) {
184cfd74d65d832137e20e193c960802afba73b5d38sm        mChannel = channel;
185cfd74d65d832137e20e193c960802afba73b5d38sm    }
186cfd74d65d832137e20e193c960802afba73b5d38sm
187cfd74d65d832137e20e193c960802afba73b5d38sm    public void setSolidSurface(SolidSurfaceComponent surface) {
188cfd74d65d832137e20e193c960802afba73b5d38sm        mSolidSurface = surface;
189cfd74d65d832137e20e193c960802afba73b5d38sm    }
190cfd74d65d832137e20e193c960802afba73b5d38sm
191cfd74d65d832137e20e193c960802afba73b5d38sm    public void setStayOpenTime(float time) {
192cfd74d65d832137e20e193c960802afba73b5d38sm        mStayOpenTime = time;
193cfd74d65d832137e20e193c960802afba73b5d38sm    }
194cfd74d65d832137e20e193c960802afba73b5d38sm
195cfd74d65d832137e20e193c960802afba73b5d38sm    public void setSounds(Sound openSound, Sound closeSound) {
196cfd74d65d832137e20e193c960802afba73b5d38sm    	mOpenSound = openSound;
197cfd74d65d832137e20e193c960802afba73b5d38sm    	mCloseSound = closeSound;
198cfd74d65d832137e20e193c960802afba73b5d38sm    }
199cfd74d65d832137e20e193c960802afba73b5d38sm}
200