DEADSOFTWARE

Add mob attach to controller
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / mobs / Mob.java
1 package ru.deadsoftware.cavedroid.game.mobs;
3 import com.badlogic.gdx.Gdx;
4 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
5 import com.badlogic.gdx.math.MathUtils;
6 import com.badlogic.gdx.math.Rectangle;
7 import com.badlogic.gdx.math.Vector2;
8 import ru.deadsoftware.cavedroid.game.world.GameWorld;
10 import java.io.Serializable;
12 /**
13 * Mob class.
14 */
15 public abstract class Mob extends Rectangle implements Serializable {
17 protected static int ANIMATION_SPEED = 360;
19 public enum Type {
20 MOB,
21 SAND,
22 GRAVEL
23 }
25 public enum Direction {
27 LEFT(0, -1),
28 RIGHT(1, 1);
30 private final int index;
31 private final int basis;
33 /**
34 * Index for this direction (left = 0, right = 1)
35 */
36 public final int getIndex() {
37 return index;
38 }
40 /**
41 * Basis for this direction (left = -1, right = 1)
42 */
43 public final int getBasis() {
44 return basis;
45 }
47 Direction(int index, int basis) {
48 this.index = index;
49 this.basis = basis;
50 }
51 }
53 protected Vector2 mVelocity;
54 protected Type mType;
55 protected int mAnimDelta = ANIMATION_SPEED;
56 protected float mAnim;
58 private Direction mDirection;
59 protected boolean mDead;
60 private boolean mCanJump;
61 private boolean mFlyMode;
63 private final int mMaxHealth;
64 private int mHealth;
66 /**
67 * @param x in pixels
68 * @param y in pixels
69 * @param width in pixels
70 * @param height in pixels
71 * @param mDirection Direction in which mob is looking
72 */
73 protected Mob(float x, float y, float width, float height, Direction mDirection, Type type, int maxHealth) {
74 super(x, y, width, height);
75 mVelocity = new Vector2(0, 0);
76 mCanJump = false;
77 mDead = false;
78 this.mDirection = mDirection;
79 this.mType = type;
80 this.mMaxHealth = maxHealth;
81 this.mHealth = mMaxHealth;
82 }
84 protected static Direction randomDir() {
85 return MathUtils.randomBoolean(.5f) ? Direction.LEFT : Direction.RIGHT;
86 }
88 private boolean isAnimationIncreasing() {
89 return mAnim > 0 && mAnimDelta > 0 || mAnim < 0 && mAnimDelta < 0;
90 }
92 private void checkHealth() {
93 mHealth = MathUtils.clamp(mHealth, 0, mMaxHealth);
95 if (mHealth <= 0) {
96 kill();
97 }
98 }
100 protected final void updateAnimation(float delta) {
101 if (mVelocity.x != 0f || Math.abs(mAnim) > mAnimDelta * delta) {
102 mAnim += mAnimDelta * delta;
103 } else {
104 mAnim = 0;
107 if (mAnim > 60f) {
108 mAnim = 60f;
109 mAnimDelta = -ANIMATION_SPEED;
110 } else if (mAnim < -60f) {
111 mAnim = -60f;
112 mAnimDelta = ANIMATION_SPEED;
115 if (mVelocity.x == 0f && isAnimationIncreasing()) {
116 mAnimDelta = -mAnimDelta;
120 /**
121 * @return The X coordinate of a mob in blocks
122 */
123 public final int getMapX() {
124 return (int) (x + (getWidth() / 2)) / 16;
127 /**
128 * @return The Y coordinate of mob's upper edge in blocks
129 */
130 public final int getUpperMapY() {
131 return (int) (y / 16);
134 /**
135 * @return The Y coordinate if mob's vertical center in blocks
136 */
137 public final int getMiddleMapY() {
138 return (int) (y + (getHeight() / 2)) / 16;
141 /**
142 * @return The Y coordinate of mob's legs in blocks
143 */
144 public final int getLowerMapY() {
145 return (int) (y + getHeight()) / 16;
148 public final float getWidth() {
149 return width;
152 public final float getHeight() {
153 return height;
156 /**
157 * @return Integer representing a direction in which mob is looking, where 0 is left and 1 is right
158 */
159 public final Direction getDirection() {
160 return mDirection;
163 public final boolean looksLeft() {
164 return mDirection == Direction.LEFT;
167 public final boolean looksRight() {
168 return mDirection == Direction.RIGHT;
171 /**
172 * Switches direction in which mob is looking
173 */
174 protected final void switchDir() {
175 mDirection = looksLeft() ? Direction.RIGHT : Direction.LEFT;
178 public final boolean isDead() {
179 return mDead;
182 public final float getAnim() {
183 return mAnim;
186 /**
187 * Set's mob's dead variable to true and nothing else. It doesn't delete the
188 */
189 public final void kill() {
190 mDead = true;
193 public final void move(float delta) {
194 x += mVelocity.x * delta;
195 y += mVelocity.y * delta;
198 public final Vector2 getVelocity() {
199 return mVelocity;
202 protected final void setVelocity(Vector2 velocity) {
203 mVelocity = velocity;
206 public final boolean canJump() {
207 return mCanJump;
210 public final void setCanJump(boolean canJump) {
211 this.mCanJump = canJump;
214 public final boolean isFlyMode() {
215 return mFlyMode;
218 public final void setFlyMode(boolean flyMode) {
219 this.mFlyMode = flyMode;
222 public final Type getType() {
223 return mType;
226 public final void checkWorldBounds(GameWorld gameWorld) {
227 if (x + width / 2 < 0) {
228 x += gameWorld.getWidthPx();
230 if (x + width / 2 > gameWorld.getWidthPx()) {
231 x -= gameWorld.getWidthPx();
235 public final int getHealth() {
236 return mHealth;
239 public final void attachToController(MobsController controller) {
240 controller.addMob(this);
243 public void damage(int damage) {
244 if (damage < 0) {
245 Gdx.app.error(this.getClass().getSimpleName(), "Damage cant be negative!");
246 return;
249 if (mHealth <= Integer.MIN_VALUE + damage) {
250 mHealth = Integer.MIN_VALUE + damage;
253 mHealth -= damage;
254 checkHealth();
257 public void heal(int heal) {
258 if (heal < 0) {
259 Gdx.app.error(this.getClass().getSimpleName(), "Heal cant be negative!");
260 return;
263 if (mHealth >= Integer.MAX_VALUE - heal) {
264 mHealth = Integer.MAX_VALUE - heal;
267 mHealth += heal;
268 checkHealth();
271 public abstract void draw(SpriteBatch spriteBatch, float x, float y, float delta);
273 public abstract void ai(GameWorld gameWorld, float delta);
275 public abstract void changeDir();
277 public abstract float getSpeed();
279 public abstract void jump();