blob: 52b93364baa09491796b8a1ce6b05ea9c701c457 [file] [log] [blame]
sm0a9f4cfd74d62010-03-18 09:32:06 +00001/*
sm0a9f43c1e67e2010-04-02 17:29:14 +00002 * Copyright (C) 2010 The Android Open Source Project
sm0a9f4cfd74d62010-03-18 09:32:06 +00003 *
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
19
20public class OrbitalMagnetComponent extends GameComponent {
21 private final static float DEFAULT_STRENGTH = 15.0f;
22
23 private float mStrength;
24 private Vector2 mCenter;
25 private Vector2 mDelta;
26 private Vector2 mRim;
27 private Vector2 mVelocity;
28 private float mMagnetRadius;
29 private float mAreaRadius;
30
31 public OrbitalMagnetComponent() {
32 super();
33 mCenter = new Vector2();
34 mDelta = new Vector2();
35 mRim = new Vector2();
36 mVelocity = new Vector2();
37 reset();
38 setPhase(ComponentPhases.COLLISION_DETECTION.ordinal());
39 }
40
41 @Override
42 public void reset() {
43 mCenter.zero();
44 mDelta.zero();
45 mRim.zero();
46 mVelocity.zero();
47 mStrength = DEFAULT_STRENGTH;
48 mAreaRadius = 0.0f;
49 mMagnetRadius = 0.0f;
50 }
51
52 @Override
53 public void update(float timeDelta, BaseObject parent) {
54 GameObjectManager manager = sSystemRegistry.gameObjectManager;
55 if (manager != null) {
56 GameObject player = manager.getPlayer();
57 if (player != null) {
58 GameObject parentObject = (GameObject)parent;
59 applyMagnetism(player,
60 parentObject.getCenteredPositionX(),
61 parentObject.getCenteredPositionY(),
62 timeDelta);
63 }
64 }
65 }
66
67 private void applyMagnetism(GameObject target, float centerX, float centerY, float timeDelta) {
68 mCenter.set(centerX, centerY);
69 final float targetX = target.getCenteredPositionX();
70 final float targetY = target.getCenteredPositionY();
71 mDelta.set(targetX, targetY);
72 mDelta.subtract(mCenter);
73
74 final float distanceFromCenter2 = mDelta.length2();
75 final float area2 = mAreaRadius * mAreaRadius;
76 if (distanceFromCenter2 < area2) {
77 mRim.set(mDelta);
78 mRim.normalize();
79 mRim.multiply(mMagnetRadius);
80 mRim.add(mCenter);
81 // rim is now the closest point on the magnet circle
82
83 // remove gravity
84 final Vector2 targetVelocity = target.getVelocity();
85 GravityComponent gravity = target.findByClass(GravityComponent.class);
86 final Vector2 gravityVector = gravity.getGravity();
87 mVelocity.set(gravityVector);
88 mVelocity.multiply(timeDelta);
89 targetVelocity.subtract(mVelocity);
90
91 mDelta.add(targetVelocity);
92 mDelta.normalize();
93 mDelta.multiply(mMagnetRadius);
94 mDelta.add(mCenter);
95
96 // mDelta is now the next point on the magnet circle in the direction of
97 // movement.
98
99 mDelta.subtract(mRim);
100 mDelta.normalize();
101 // Now mDelta is the tangent to the magnet circle, pointing in the direction
102 // of movement.
103
104 mVelocity.set(mDelta);
105 mVelocity.normalize();
106
107 // mVelocity is now the direction to push the player
108
109 mVelocity.multiply(mStrength);
110 float weight = 1.0f;
111 if (distanceFromCenter2 > mMagnetRadius * mMagnetRadius) {
112 float distance = (float)Math.sqrt(distanceFromCenter2);
113 weight = (distance - mMagnetRadius) / (mAreaRadius - mMagnetRadius);
114 weight = 1.0f - weight;
115 mVelocity.multiply(weight);
116 }
117 final float speed = targetVelocity.length();
118 targetVelocity.add(mVelocity);
119 if (targetVelocity.length2() > (speed * speed)) {
120 targetVelocity.normalize();
121 targetVelocity.multiply(speed);
122 }
123
124 }
125
126 }
127
128 public void setup(float areaRadius, float orbitRadius) {
129 mAreaRadius = areaRadius;
130 mMagnetRadius = orbitRadius;
131 }
132}