DEADSOFTWARE

Update README
[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 if (mVelocity.x != 0f || Math.abs(mAnim) > mAnimDelta * delta) {
103 mAnim += mAnimDelta * delta;
104 } else {
105 mAnim = 0;
108 if (mAnim > 60f) {
109 mAnim = 60f;
110 mAnimDelta = -ANIMATION_SPEED;
111 } else if (mAnim < -60f) {
112 mAnim = -60f;
113 mAnimDelta = ANIMATION_SPEED;
116 if (mVelocity.x == 0f && isAnimationIncreasing()) {
117 mAnimDelta = -mAnimDelta;
121 /**
122 * @return The X coordinate of a mob in blocks
123 */
124 public final int getMapX() {
125 return (int) (x + (getWidth() / 2)) / 16;
128 /**
129 * @return The Y coordinate of mob's upper edge in blocks
130 */
131 public final int getUpperMapY() {
132 return (int) (y / 16);
135 /**
136 * @return The Y coordinate if mob's vertical center in blocks
137 */
138 public final int getMiddleMapY() {
139 return (int) (y + (getHeight() / 2)) / 16;
142 /**
143 * @return The Y coordinate of mob's legs in blocks
144 */
145 public final int getLowerMapY() {
146 return (int) (y + getHeight()) / 16;
149 public final float getWidth() {
150 return width;
153 public final float getHeight() {
154 return height;
157 /**
158 * @return Integer representing a direction in which mob is looking, where 0 is left and 1 is right
159 */
160 public final Direction getDirection() {
161 return mDirection;
164 public final boolean looksLeft() {
165 return mDirection == Direction.LEFT;
168 public final boolean looksRight() {
169 return mDirection == Direction.RIGHT;
172 /**
173 * Switches direction in which mob is looking
174 */
175 protected final void switchDir() {
176 mDirection = looksLeft() ? Direction.RIGHT : Direction.LEFT;
179 public final boolean isDead() {
180 return mDead;
183 public final float getAnim() {
184 return mAnim;
187 /**
188 * Set's mob's dead variable to true and nothing else. It doesn't delete the
189 */
190 public final void kill() {
191 mDead = true;
194 public final void move(float delta) {
195 x += mVelocity.x * delta;
196 y += mVelocity.y * delta;
199 public final Vector2 getVelocity() {
200 return mVelocity;
203 protected final void setVelocity(Vector2 velocity) {
204 mVelocity = velocity;
207 public final boolean canJump() {
208 return mCanJump;
211 public final void setCanJump(boolean canJump) {
212 this.mCanJump = canJump;
215 public final boolean isFlyMode() {
216 return mFlyMode;
219 public final void setFlyMode(boolean flyMode) {
220 this.mFlyMode = flyMode;
223 public final Type getType() {
224 return mType;
227 public final void checkWorldBounds(GameWorld gameWorld) {
228 if (x + width / 2 < 0) {
229 x += gameWorld.getWidthPx();
231 if (x + width / 2 > gameWorld.getWidthPx()) {
232 x -= gameWorld.getWidthPx();
236 public final int getHealth() {
237 return mHealth;
240 public final void attachToController(MobsController controller) {
241 controller.addMob(this);
244 public void damage(int damage) {
245 if (damage == 0) {
246 return;
249 if (damage < 0) {
250 Gdx.app.error(this.getClass().getSimpleName(), "Damage cant be negative!");
251 return;
254 if (mHealth <= Integer.MIN_VALUE + damage) {
255 mHealth = Integer.MIN_VALUE + damage;
258 mHealth -= damage;
259 checkHealth();
262 public void heal(int heal) {
263 if (heal < 0) {
264 Gdx.app.error(this.getClass().getSimpleName(), "Heal cant be negative!");
265 return;
268 if (mHealth >= Integer.MAX_VALUE - heal) {
269 mHealth = Integer.MAX_VALUE - heal;
272 mHealth += heal;
273 checkHealth();
276 public abstract void draw(SpriteBatch spriteBatch, float x, float y, float delta);
278 public abstract void ai(GameWorld gameWorld, GameItemsHolder gameItemsHolder, float delta);
280 public abstract void changeDir();
282 public abstract float getSpeed();
284 public abstract void jump();