DEADSOFTWARE

Add joystick touch controls
[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.GameItemsHolder;
9 import ru.deadsoftware.cavedroid.game.world.GameWorld;
11 import java.io.Serializable;
13 /**
14 * Mob class.
15 */
16 public abstract class Mob extends Rectangle implements Serializable {
18 protected static int ANIMATION_SPEED = 360;
20 public enum Type {
21 MOB,
22 SAND,
23 GRAVEL
24 }
26 public enum Direction {
28 LEFT(0, -1),
29 RIGHT(1, 1);
31 private final int index;
32 private final int basis;
34 /**
35 * Index for this direction (left = 0, right = 1)
36 */
37 public final int getIndex() {
38 return index;
39 }
41 /**
42 * Basis for this direction (left = -1, right = 1)
43 */
44 public final int getBasis() {
45 return basis;
46 }
48 Direction(int index, int basis) {
49 this.index = index;
50 this.basis = basis;
51 }
52 }
54 protected Vector2 mVelocity;
55 protected Type mType;
56 protected int mAnimDelta = ANIMATION_SPEED;
57 protected float mAnim;
59 private Direction mDirection;
60 protected boolean mDead;
61 private boolean mCanJump;
62 private boolean mFlyMode;
64 private final int mMaxHealth;
65 private int mHealth;
67 /**
68 * @param x in pixels
69 * @param y in pixels
70 * @param width in pixels
71 * @param height in pixels
72 * @param mDirection Direction in which mob is looking
73 */
74 protected Mob(float x, float y, float width, float height, Direction mDirection, Type type, int maxHealth) {
75 super(x, y, width, height);
76 mVelocity = new Vector2(0, 0);
77 mCanJump = false;
78 mDead = false;
79 this.mDirection = mDirection;
80 this.mType = type;
81 this.mMaxHealth = maxHealth;
82 this.mHealth = mMaxHealth;
83 }
85 protected static Direction randomDir() {
86 return MathUtils.randomBoolean(.5f) ? Direction.LEFT : Direction.RIGHT;
87 }
89 private boolean isAnimationIncreasing() {
90 return mAnim > 0 && mAnimDelta > 0 || mAnim < 0 && mAnimDelta < 0;
91 }
93 private void checkHealth() {
94 mHealth = MathUtils.clamp(mHealth, 0, mMaxHealth);
96 if (mHealth <= 0) {
97 kill();
98 }
99 }
101 protected final void updateAnimation(float delta) {
102 final float velocityMultiplier = (Math.abs(getVelocity().x) / getSpeed());
103 final float animMultiplier = (velocityMultiplier == 0f ? 1f : velocityMultiplier) * delta;
104 final float maxAnim = 60f * (velocityMultiplier == 0f ? 1f : velocityMultiplier);
106 if (mVelocity.x != 0f || Math.abs(mAnim) > mAnimDelta * animMultiplier) {
107 mAnim += mAnimDelta * animMultiplier;
108 } else {
109 mAnim = 0;
112 if (mAnim > maxAnim) {
113 mAnim = maxAnim;
114 mAnimDelta = -ANIMATION_SPEED;
115 } else if (mAnim < -maxAnim) {
116 mAnim = -maxAnim;
117 mAnimDelta = ANIMATION_SPEED;
120 if (mVelocity.x == 0f && isAnimationIncreasing()) {
121 mAnimDelta = -mAnimDelta;
125 /**
126 * @return The X coordinate of a mob in blocks
127 */
128 public final int getMapX() {
129 return (int) (x + (getWidth() / 2)) / 16;
132 /**
133 * @return The Y coordinate of mob's upper edge in blocks
134 */
135 public final int getUpperMapY() {
136 return (int) (y / 16);
139 /**
140 * @return The Y coordinate if mob's vertical center in blocks
141 */
142 public final int getMiddleMapY() {
143 return (int) (y + (getHeight() / 2)) / 16;
146 /**
147 * @return The Y coordinate of mob's legs in blocks
148 */
149 public final int getLowerMapY() {
150 return (int) (y + getHeight()) / 16;
153 public final float getWidth() {
154 return width;
157 public final float getHeight() {
158 return height;
161 /**
162 * @return Integer representing a direction in which mob is looking, where 0 is left and 1 is right
163 */
164 public final Direction getDirection() {
165 return mDirection;
168 public final boolean looksLeft() {
169 return mDirection == Direction.LEFT;
172 public final boolean looksRight() {
173 return mDirection == Direction.RIGHT;
176 /**
177 * Switches direction in which mob is looking
178 */
179 protected final void switchDir() {
180 mDirection = looksLeft() ? Direction.RIGHT : Direction.LEFT;
183 public final boolean isDead() {
184 return mDead;
187 public final float getAnim() {
188 return mAnim;
191 /**
192 * Set's mob's dead variable to true and nothing else. It doesn't delete the
193 */
194 public final void kill() {
195 mDead = true;
198 public final void move(float delta) {
199 x += mVelocity.x * delta;
200 y += mVelocity.y * delta;
203 public final Vector2 getVelocity() {
204 return mVelocity;
207 protected final void setVelocity(Vector2 velocity) {
208 mVelocity = velocity;
211 public final boolean canJump() {
212 return mCanJump;
215 public final void setCanJump(boolean canJump) {
216 this.mCanJump = canJump;
219 public final boolean isFlyMode() {
220 return mFlyMode;
223 public final void setFlyMode(boolean flyMode) {
224 this.mFlyMode = flyMode;
227 public final Type getType() {
228 return mType;
231 public final void checkWorldBounds(GameWorld gameWorld) {
232 if (x + width / 2 < 0) {
233 x += gameWorld.getWidthPx();
235 if (x + width / 2 > gameWorld.getWidthPx()) {
236 x -= gameWorld.getWidthPx();
240 public final int getHealth() {
241 return mHealth;
244 public final void attachToController(MobsController controller) {
245 controller.addMob(this);
248 public void damage(int damage) {
249 if (damage == 0) {
250 return;
253 if (damage < 0) {
254 Gdx.app.error(this.getClass().getSimpleName(), "Damage cant be negative!");
255 return;
258 if (mHealth <= Integer.MIN_VALUE + damage) {
259 mHealth = Integer.MIN_VALUE + damage;
262 mHealth -= damage;
263 checkHealth();
266 public void heal(int heal) {
267 if (heal < 0) {
268 Gdx.app.error(this.getClass().getSimpleName(), "Heal cant be negative!");
269 return;
272 if (mHealth >= Integer.MAX_VALUE - heal) {
273 mHealth = Integer.MAX_VALUE - heal;
276 mHealth += heal;
277 checkHealth();
280 public abstract void draw(SpriteBatch spriteBatch, float x, float y, float delta);
282 public abstract void ai(GameWorld gameWorld, GameItemsHolder gameItemsHolder, float delta);
284 public abstract void changeDir();
286 public abstract float getSpeed();
288 public abstract void jump();