1 package ru
.deadsoftware
.cavedroid
.game
.mobs
.player
;
3 import com
.badlogic
.gdx
.graphics
.g2d
.Sprite
;
4 import com
.badlogic
.gdx
.graphics
.g2d
.SpriteBatch
;
5 import com
.badlogic
.gdx
.math
.MathUtils
;
6 import com
.badlogic
.gdx
.math
.Vector2
;
7 import ru
.deadsoftware
.cavedroid
.game
.GameItemsHolder
;
8 import ru
.deadsoftware
.cavedroid
.game
.mobs
.Mob
;
9 import ru
.deadsoftware
.cavedroid
.game
.model
.block
.Block
;
10 import ru
.deadsoftware
.cavedroid
.game
.model
.item
.InventoryItem
;
11 import ru
.deadsoftware
.cavedroid
.game
.model
.item
.Item
;
12 import ru
.deadsoftware
.cavedroid
.game
.objects
.Drop
;
13 import ru
.deadsoftware
.cavedroid
.game
.world
.GameWorld
;
14 import ru
.deadsoftware
.cavedroid
.misc
.Assets
;
15 import ru
.deadsoftware
.cavedroid
.misc
.utils
.SpriteOrigin
;
16 import ru
.deadsoftware
.cavedroid
.misc
.utils
.SpriteUtilsKt
;
18 import javax
.annotation
.CheckForNull
;
20 public class Player
extends Mob
{
22 private static final float SPEED
= 69.072f;
23 private static final float JUMP_VELOCITY
= -133.332f;
25 public static final int MAX_HEALTH
= 20;
26 public static final int INVENTORY_SIZE
= 36;
27 public static final int HOTBAR_SIZE
= 9;
29 private boolean hitting
= false, hittingWithDamage
= false;
30 private float hitAnim
= 0f;
31 private float hitAnimDelta
= ANIMATION_SPEED
;
33 public final Inventory inventory
;
37 public float headRotation
= 0f;
39 public float blockDamage
= 0f;
40 public int cursorX
= 0;
41 public int cursorY
= 0;
44 private Vector2 spawnPoint
= null;
46 public ControlMode controlMode
= ControlMode
.WALK
;
48 public enum ControlMode
{
53 public Player(GameItemsHolder gameItemsHolder
) {
54 super(0, 0, 4, 30, randomDir(), Type
.MOB
, MAX_HEALTH
);
55 inventory
= new Inventory(INVENTORY_SIZE
, HOTBAR_SIZE
, gameItemsHolder
);
59 public void initInventory(GameItemsHolder gameItemsHolder
) {
60 inventory
.initItems(gameItemsHolder
);
63 public void respawn(GameWorld gameWorld
, GameItemsHolder itemsHolder
) {
64 Vector2 pos
= getSpawnPoint(gameWorld
, itemsHolder
);
72 public void decreaseCurrentItemCount(GameItemsHolder gameItemsHolder
) {
77 final InventoryItem item
= inventory
.getActiveItem();
79 if (item
.getAmount() <= 0) {
80 setCurrentInventorySlotItem(gameItemsHolder
.getFallbackItem());
84 private Vector2
getSpawnPoint(GameWorld gameWorld
, GameItemsHolder itemsHolder
) {
85 if (spawnPoint
!= null) {
89 int y
, x
= gameWorld
.getWidth() / 2;
90 for (y
= 0; y
<= gameWorld
.getWorldConfig().getSeaLevel(); y
++) {
91 if (y
== gameWorld
.getWorldConfig().getSeaLevel()) {
92 for (x
= 0; x
< gameWorld
.getWidth(); x
++) {
93 if (gameWorld
.getForeMap(x
, y
).getParams().getHasCollision()) {
96 if (x
== gameWorld
.getWidth() - 1) {
97 gameWorld
.setForeMap(x
, y
, itemsHolder
.getBlock("grass"));
103 if (gameWorld
.hasForeAt(x
, y
) && gameWorld
.getForeMap(x
, y
).hasCollision()) {
107 spawnPoint
= new Vector2(x
* 16 + 8 - getWidth() / 2, (float) y
* 16 - getHeight());
111 public void setDir(Direction dir
) {
112 if (dir
!= getDirection()) {
117 public void setCurrentInventorySlotItem(Item item
) {
118 inventory
.getItems().set(inventory
.getActiveSlot(), item
.toInventoryItem());
122 public float getSpeed() {
128 mVelocity
.y
= JUMP_VELOCITY
;
131 private boolean checkBlockCanBeHit(Block block
) {
132 return !block
.isNone() && block
.getParams().getHitPoints() >= 0;
135 private void hitBlock(GameWorld gameWorld
, GameItemsHolder gameItemsHolder
) {
136 if (!hitting
|| !hittingWithDamage
) {
140 final Block foregroundBlock
= gameWorld
.getForeMap(cursorX
, cursorY
);
141 final Block backgroundBlock
= gameWorld
.getBackMap(cursorX
, cursorY
);
144 if ((checkBlockCanBeHit(foregroundBlock
)) ||
145 (foregroundBlock
.isNone() && checkBlockCanBeHit(backgroundBlock
))) {
147 if (!foregroundBlock
.isNone()) {
148 if (blockDamage
>= foregroundBlock
.getParams().getHitPoints()) {
149 gameWorld
.destroyForeMap(cursorX
, cursorY
);
152 } else if (!backgroundBlock
.isNone()) {
153 if (blockDamage
>= backgroundBlock
.getParams().getHitPoints()) {
154 gameWorld
.destroyBackMap(cursorX
, cursorY
);
159 if (!foregroundBlock
.isNone()) {
160 gameWorld
.placeToForeground(cursorX
, cursorY
, gameItemsHolder
.getFallbackBlock());
161 } else if (!backgroundBlock
.isNone()) {
162 gameWorld
.placeToBackground(cursorX
, cursorY
, gameItemsHolder
.getFallbackBlock());
172 public void ai(GameWorld gameWorld
, GameItemsHolder gameItemsHolder
, float delta
) {
173 updateAnimation(delta
);
174 hitBlock(gameWorld
, gameItemsHolder
);
180 final Block foregroundBlock
= gameWorld
.getForeMap(cursorX
, cursorY
);
181 final Block backgroundBlock
= gameWorld
.getBackMap(cursorX
, cursorY
);
182 @CheckForNull final Block target
;
184 if (checkBlockCanBeHit(foregroundBlock
)) {
185 target
= foregroundBlock
;
186 } else if (checkBlockCanBeHit(backgroundBlock
)) {
187 target
= backgroundBlock
;
192 final boolean canHitBlock
= target
!= null;
194 float multiplier
= 1f;
195 final Item currentItem
= inventory
.getActiveItem().getItem();
196 if (currentItem
instanceof Item
.Tool
&& canHitBlock
) {
197 if (target
.getParams().getToolType() == currentItem
.getClass()
198 && ((Item
.Tool
)currentItem
).getLevel() >= target
.getParams().getToolLevel()) {
199 multiplier
= 2f * ((Item
.Tool
)currentItem
).getLevel();
201 multiplier
*= ((Item
.Tool
)currentItem
).getBlockDamageMultiplier();
204 if (hitting
&& hittingWithDamage
&& canHitBlock
) {
205 blockDamage
+= 60f * delta
* multiplier
;
212 public void changeDir() {
216 public void damage(int damage
) {
222 getVelocity().y
+= JUMP_VELOCITY
/ 3f;
225 super.damage(damage
);
229 public void heal(int heal
) {
236 private void drawItem(SpriteBatch spriteBatch
, float x
, float y
, float anim
) {
237 final Item item
= inventory
.getActiveItem().getItem();
239 if (item
== null || item
.isNone()) {
243 final Sprite sprite
= item
.getSprite();
244 final boolean smallSprite
= !item
.isTool() || item
.isShears();
246 final float originalWidth
= sprite
.getWidth();
247 final float originalHeight
= sprite
.getHeight();
250 sprite
.setSize(Drop
.DROP_SIZE
, Drop
.DROP_SIZE
);
253 final float handLength
= Assets
.playerSprite
[0][2].getHeight();
255 final SpriteOrigin spriteOrigin
= item
.getParams().getInHandSpriteOrigin();
256 final int handMultiplier
= -getDirection().getBasis();
257 final float xOffset
= (-1 + getDirection().getIndex()) * sprite
.getWidth() + 4 + handMultiplier
* (sprite
.getWidth() * spriteOrigin
.getX());
258 final float yOffset
= !smallSprite ?
-sprite
.getHeight() / 2 : 0;
260 float rotate
= anim
+ 30;
263 sprite
.rotate90(looksLeft());
266 final float itemX
= x
+ handLength
* MathUtils
.sin(handMultiplier
* anim
* MathUtils
.degRad
) + xOffset
;
267 final float itemY
= y
+ handLength
* MathUtils
.cos(handMultiplier
* anim
* MathUtils
.degRad
) + yOffset
;
270 sprite
.setFlip(!item
.isTool(), sprite
.isFlipY());
271 SpriteUtilsKt
.applyOrigin(sprite
, spriteOrigin
.getFlipped(true, false));
273 sprite
.setFlip(item
.isTool(), sprite
.isFlipY());
274 SpriteUtilsKt
.applyOrigin(sprite
, spriteOrigin
);
277 sprite
.setRotation(-handMultiplier
* rotate
);
278 sprite
.setPosition(itemX
, itemY
);
279 sprite
.draw(spriteBatch
);
281 // dont forget to reset
282 sprite
.setFlip(false, sprite
.isFlipY());
283 sprite
.setRotation(0);
284 sprite
.setOriginCenter();
285 sprite
.setSize(originalWidth
, originalHeight
);
287 sprite
.rotate90(looksRight());
291 public void startHitting(boolean withDamage
) {
297 hittingWithDamage
= withDamage
;
299 hitAnimDelta
= ANIMATION_SPEED
;
302 public void startHitting() {
306 public void stopHitting() {
311 private float getRightHandAnim(float delta
) {
312 hitAnim
-= hitAnimDelta
* delta
;
314 if (hitAnim
< 30f || hitAnim
> 90f) {
316 hitAnim
= MathUtils
.clamp(hitAnim
, 30f, 90f);
317 hitAnimDelta
= -hitAnimDelta
;
319 hitAnimDelta
= ANIMATION_SPEED
;
324 if (hitAnim
< hitAnimDelta
* delta
) {
335 public void draw(SpriteBatch spriteBatch
, float x
, float y
, float delta
) {
336 final Sprite backHand
= Assets
.playerSprite
[1][2];
337 final Sprite backLeg
= Assets
.playerSprite
[1][3];
338 final Sprite frontLeg
= Assets
.playerSprite
[0][3];
339 final Sprite head
= Assets
.playerSprite
[getDirection().getIndex()][0];
340 final Sprite body
= Assets
.playerSprite
[getDirection().getIndex()][1];
341 final Sprite frontHand
= Assets
.playerSprite
[0][2];
343 float backHandAnim
, frontHandAnim
;
345 final float rightHandAnim
= getRightHandAnim(delta
);
348 backHandAnim
= rightHandAnim
;
349 frontHandAnim
= mAnim
;
351 backHandAnim
= -mAnim
;
352 frontHandAnim
= -rightHandAnim
;
355 SpriteUtilsKt
.drawSprite(spriteBatch
, backHand
, x
+ 2, y
+ 8, backHandAnim
);
358 drawItem(spriteBatch
, x
, y
, -backHandAnim
);
361 SpriteUtilsKt
.drawSprite(spriteBatch
, backLeg
, x
+ 2, y
+ 20, mAnim
);
362 SpriteUtilsKt
.drawSprite(spriteBatch
, frontLeg
, x
+ 2, y
+ 20, -mAnim
);
363 SpriteUtilsKt
.drawSprite(spriteBatch
, head
, x
, y
, headRotation
);
364 SpriteUtilsKt
.drawSprite(spriteBatch
, body
, x
+ 2, y
+ 8);
367 drawItem(spriteBatch
, x
, y
, frontHandAnim
);
370 SpriteUtilsKt
.drawSprite(spriteBatch
, frontHand
, x
+ 2, y
+ 8, frontHandAnim
);