1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.replica.replicaisland;
18
19import com.replica.replicaisland.CollisionParameters.HitType;
20
21/**
22 * GameObject defines any object that resides in the game world (character, background, special
23 * effect, enemy, etc).  It is a collection of GameComponents which implement its behavior;
24 * GameObjects themselves have no intrinsic behavior.  GameObjects are also "bags of data" that
25 * components can use to share state (direct component-to-component communication is discouraged).
26 */
27public class GameObject extends PhasedObjectManager {
28    private final static float COLLISION_SURFACE_DECAY_TIME = 0.3f;
29    // These fields are managed by components.
30    private Vector2 mPosition;
31    private Vector2 mVelocity;
32    private Vector2 mTargetVelocity;
33    private Vector2 mAcceleration;
34    private Vector2 mImpulse;
35
36    private Vector2 mBackgroundCollisionNormal;
37
38    private float mLastTouchedFloorTime;
39    private float mLastTouchedCeilingTime;
40    private float mLastTouchedLeftWallTime;
41    private float mLastTouchedRightWallTime;
42
43    public boolean positionLocked;
44
45    public float activationRadius;
46    public boolean destroyOnDeactivation;
47
48    public int life;
49
50    public int lastReceivedHitType;
51
52    public Vector2 facingDirection;
53    public float width;
54    public float height;
55
56    private static final int DEFAULT_LIFE = 1;
57
58    public enum ActionType {
59        INVALID,
60        IDLE,
61        MOVE,
62        ATTACK,
63        HIT_REACT,
64        DEATH,
65        HIDE,
66        FROZEN
67    }
68
69    private ActionType mCurrentAction;
70
71    public enum Team {
72        NONE,
73        PLAYER,
74        ENEMY
75    }
76
77    public Team team;
78
79    public GameObject() {
80        super();
81
82        mPosition = new Vector2();
83        mVelocity = new Vector2();
84        mTargetVelocity = new Vector2();
85        mAcceleration = new Vector2();
86        mImpulse = new Vector2();
87        mBackgroundCollisionNormal = new Vector2();
88
89        facingDirection = new Vector2(1, 0);
90
91        reset();
92    }
93
94    @Override
95    public void reset() {
96        removeAll();
97        commitUpdates();
98
99        mPosition.zero();
100        mVelocity.zero();
101        mTargetVelocity.zero();
102        mAcceleration.zero();
103        mImpulse.zero();
104        mBackgroundCollisionNormal.zero();
105        facingDirection.set(1.0f, 1.0f);
106
107        mCurrentAction = ActionType.INVALID;
108        positionLocked = false;
109        activationRadius = 0;
110        destroyOnDeactivation = false;
111        life = DEFAULT_LIFE;
112        team = Team.NONE;
113        width = 0.0f;
114        height = 0.0f;
115
116        lastReceivedHitType = HitType.INVALID;
117    }
118
119    // Utility functions
120    public final boolean touchingGround() {
121        final TimeSystem time = sSystemRegistry.timeSystem;
122        final float gameTime = time.getGameTime();
123        final boolean touching = gameTime > 0.1f &&
124            Utils.close(mLastTouchedFloorTime, time.getGameTime(), COLLISION_SURFACE_DECAY_TIME);
125        return touching;
126    }
127
128    public final boolean touchingCeiling() {
129        final TimeSystem time = sSystemRegistry.timeSystem;
130        final float gameTime = time.getGameTime();
131        final boolean touching = gameTime > 0.1f &&
132            Utils.close(mLastTouchedCeilingTime, time.getGameTime(), COLLISION_SURFACE_DECAY_TIME);
133        return touching;
134    }
135
136    public final boolean touchingLeftWall() {
137        final TimeSystem time = sSystemRegistry.timeSystem;
138        final float gameTime = time.getGameTime();
139        final boolean touching = gameTime > 0.1f &&
140            Utils.close(mLastTouchedLeftWallTime, time.getGameTime(), COLLISION_SURFACE_DECAY_TIME);
141        return touching;
142    }
143
144    public final boolean touchingRightWall() {
145        final TimeSystem time = sSystemRegistry.timeSystem;
146        final float gameTime = time.getGameTime();
147        final boolean touching = gameTime > 0.1f &&
148            Utils.close(mLastTouchedRightWallTime, time.getGameTime(), COLLISION_SURFACE_DECAY_TIME);
149        return touching;
150    }
151
152    public final Vector2 getPosition() {
153        return mPosition;
154    }
155
156    public final void setPosition(Vector2 position) {
157        mPosition.set(position);
158    }
159
160    public final float getCenteredPositionX() {
161        return mPosition.x + (width / 2.0f);
162    }
163
164    public final float getCenteredPositionY() {
165        return mPosition.y + (height / 2.0f);
166    }
167
168    public final Vector2 getVelocity() {
169        return mVelocity;
170    }
171
172    public final void setVelocity(Vector2 velocity) {
173        mVelocity.set(velocity);
174    }
175
176    public final Vector2 getTargetVelocity() {
177        return mTargetVelocity;
178    }
179
180    public final void setTargetVelocity(Vector2 targetVelocity) {
181        mTargetVelocity.set(targetVelocity);
182    }
183
184    public final Vector2 getAcceleration() {
185        return mAcceleration;
186    }
187
188    public final void setAcceleration(Vector2 acceleration) {
189        mAcceleration.set(acceleration);
190    }
191
192    public final Vector2 getImpulse() {
193        return mImpulse;
194    }
195
196    public final void setImpulse(Vector2 impulse) {
197        mImpulse.set(impulse);
198    }
199
200    public final Vector2 getBackgroundCollisionNormal() {
201        return mBackgroundCollisionNormal;
202    }
203
204    public final void setBackgroundCollisionNormal(Vector2 normal) {
205        mBackgroundCollisionNormal.set(normal);
206    }
207
208    public final float getLastTouchedFloorTime() {
209        return mLastTouchedFloorTime;
210    }
211
212    public final void setLastTouchedFloorTime(float lastTouchedFloorTime) {
213        mLastTouchedFloorTime = lastTouchedFloorTime;
214    }
215
216    public final float getLastTouchedCeilingTime() {
217        return mLastTouchedCeilingTime;
218    }
219
220    public final void setLastTouchedCeilingTime(float lastTouchedCeilingTime) {
221        mLastTouchedCeilingTime = lastTouchedCeilingTime;
222    }
223
224    public final float getLastTouchedLeftWallTime() {
225        return mLastTouchedLeftWallTime;
226    }
227
228    public final void setLastTouchedLeftWallTime(float lastTouchedLeftWallTime) {
229        mLastTouchedLeftWallTime = lastTouchedLeftWallTime;
230    }
231
232    public final float getLastTouchedRightWallTime() {
233        return mLastTouchedRightWallTime;
234    }
235
236    public final void setLastTouchedRightWallTime(float lastTouchedRightWallTime) {
237        mLastTouchedRightWallTime = lastTouchedRightWallTime;
238    }
239
240    public final ActionType getCurrentAction() {
241        return mCurrentAction;
242    }
243
244    public final void setCurrentAction(ActionType type) {
245        mCurrentAction = type;
246    }
247}
248