1 package ru
.deadsoftware
.cavedroid
.game
;
3 import com
.badlogic
.gdx
.math
.Intersector
;
4 import com
.badlogic
.gdx
.math
.MathUtils
;
5 import com
.badlogic
.gdx
.math
.Rectangle
;
6 import com
.badlogic
.gdx
.math
.Vector2
;
7 import ru
.deadsoftware
.cavedroid
.MainConfig
;
8 import ru
.deadsoftware
.cavedroid
.game
.mobs
.Mob
;
9 import ru
.deadsoftware
.cavedroid
.game
.mobs
.MobsController
;
10 import ru
.deadsoftware
.cavedroid
.game
.mobs
.Player
;
11 import ru
.deadsoftware
.cavedroid
.game
.objects
.Drop
;
12 import ru
.deadsoftware
.cavedroid
.game
.objects
.DropController
;
13 import ru
.deadsoftware
.cavedroid
.game
.world
.GameWorld
;
15 import javax
.inject
.Inject
;
16 import java
.util
.Iterator
;
20 public class GamePhysics
{
22 public static final float PL_SPEED
= 69.072f;
23 public static final float PL_JUMP_VELOCITY
= -133.332f;
25 private final Vector2 gravity
= new Vector2(0, 444.44f);
27 private final GameWorld mGameWorld
;
28 private final MainConfig mMainConfig
;
29 private final MobsController mMobsController
;
30 private final DropController mDropController
;
33 public GamePhysics(GameWorld gameWorld
,
34 MainConfig mainConfig
,
35 MobsController mobsController
,
36 DropController dropController
) {
37 mGameWorld
= gameWorld
;
38 mMainConfig
= mainConfig
;
39 mMobsController
= mobsController
;
40 mDropController
= dropController
;
44 * Checks if mob should jump
46 * @return true if mob should jump
48 private boolean checkJump(Mob mob
) {
49 int dir
= mob
.looksLeft() ?
0 : 1;
50 int blX
= (int) (mob
.getX() + mob
.getWidth() * dir
- 8 + 16 * dir
);
51 int blY
= (int) (mob
.getY() + mob
.getHeight() - 8);
52 int block
= mGameWorld
.getForeMap(blX
/ 16, blY
/ 16);
54 if (checkColl(new Rectangle(blX
, mob
.getY() - 18, mob
.getWidth(), mob
.getHeight()))) {
58 return (block
> 0 && GameItems
.getBlock(block
).toJump() &&
59 (mob
.getY() + mob
.getHeight()) - GameItems
.getBlock(block
).getRectangle(blX
/ 16, blY
/ 16).y
> 8);
62 private boolean checkColl(Rectangle rect
) {
63 int minX
= (int) ((rect
.x
+ rect
.width
/ 2) / 16) - 4;
64 int minY
= (int) ((rect
.y
+ rect
.height
/ 2) / 16) - 4;
65 int maxX
= (int) ((rect
.x
+ rect
.width
/ 2) / 16) + 4;
66 int maxY
= (int) ((rect
.y
+ rect
.height
/ 2) / 16) + 4;
72 if (maxY
> mGameWorld
.getHeight()) {
73 maxY
= mGameWorld
.getHeight();
77 for (int y
= minY
; y
< maxY
; y
++) {
78 for (int x
= minX
; x
< maxX
; x
++) {
79 block
= mGameWorld
.getForeMap(x
, y
);
80 if (block
> 0 && GameItems
.getBlock(block
).hasCollision()) {
81 if (Intersector
.overlaps(rect
, GameItems
.getBlock(block
).getRectangle(x
, y
))) {
91 private int getBlock(Rectangle rect
) {
92 return mGameWorld
.getForeMap((int) (rect
.x
+ rect
.width
/ 2) / 16,
93 (int) (rect
.y
+ rect
.height
/ 8 * 7) / 16);
96 private void dropPhy(Drop drop
, float delta
) {
97 int dropToPlayer
= drop
.closeToPlayer(mGameWorld
, mMobsController
.getPlayer());
98 if (dropToPlayer
> 0) {
99 drop
.moveToPlayer(mGameWorld
, mMobsController
.getPlayer(), dropToPlayer
);
101 if (drop
.getVelocity().x
>= .5f) {
102 drop
.getVelocity().x
-= .5f;
103 } else if (drop
.getVelocity().x
<= -.5f) {
104 drop
.getVelocity().x
+= .5f;
106 drop
.getVelocity().x
= 0;
108 if (drop
.getVelocity().y
< 9) {
109 drop
.getVelocity().y
+= gravity
.y
/ 4;
115 if (checkColl(drop
)) {
116 drop
.getVelocity().set(0, -1);
119 } while (checkColl(drop
));
120 drop
.getVelocity().setZero();
124 private void mobXColl(Mob mob
) {
125 if (checkColl(mob
)) {
126 if (mob
.canJump() && !mob
.isFlyMode()) {
130 if (checkColl(mob
)) {
131 if (mob
.canJump() && !mob
.isFlyMode()) {
137 if (mob
.getVelocity().x
< 0) {
139 } else if (mob
.getVelocity().x
> 0) {
143 mob
.x
= MathUtils
.round(mob
.getX());
145 while (checkColl(mob
)) {
155 mob
.checkWorldBounds(mGameWorld
);
158 private void mobYColl(Mob mob
) {
159 if (checkColl(mob
)) {
162 if (mob
.getVelocity().y
< 0) {
167 mob
.setCanJump(true);
168 mob
.setFlyMode(false);
171 mob
.y
= MathUtils
.round(mob
.getY());
173 while (checkColl(mob
)) {
177 mob
.getVelocity().y
= 0;
181 mob
.setCanJump(checkColl(mob
));
185 if (mob
.getY() > mGameWorld
.getHeightPx()) {
190 private void playerPhy(Player player
, float delta
) {
191 if (player
.isDead()) {
195 if (GameItems
.isFluid(getBlock(player
))) {
196 if (mMainConfig
.isTouch() && player
.getVelocity().x
!= 0 && !player
.swim
&& !player
.isFlyMode()) {
200 if (!player
.isFlyMode() && player
.getVelocity().y
< 270f) {
201 player
.getVelocity().x
+= gravity
.y
/ 4;
203 if (!player
.isFlyMode() && player
.getVelocity().y
> 270f) {
204 player
.getVelocity().add(0, -60f);
207 player
.getVelocity().add(0, -30f);
208 if (player
.getVelocity().y
< -180) {
209 player
.getVelocity().y
= -180;
213 if (!player
.isFlyMode() && player
.getVelocity().y
< 1080) {
214 player
.getVelocity().y
+= gravity
.y
* delta
;
218 player
.y
+= player
.getVelocity().y
* delta
;
221 player
.x
+= player
.getVelocity().x
* (player
.isFlyMode() ?
1.5f : 1) *
222 (GameItems
.isFluid(getBlock(player
)) && !player
.isFlyMode() ?
.8f : 1) * delta
;
226 if (mMainConfig
.isTouch() && !player
.isFlyMode() && player
.canJump() && player
.getVelocity().x
!= 0 && checkJump(player
)) {
227 player
.getVelocity().y
= PL_JUMP_VELOCITY
;
228 player
.setCanJump(false);
232 private void mobPhy(Mob mob
, float delta
) {
233 if (mob
.getType() == Mob
.Type
.MOB
&& GameItems
.isFluid(getBlock(mob
))) {
234 if (mob
.getVelocity().y
> 540) {
235 mob
.getVelocity().add(0, -5.4f);
238 mob
.getVelocity().add(0, -30f);
240 if (mob
.getVelocity().y
< -180) {
241 mob
.getVelocity().y
= -180;
243 } else if (!mob
.isFlyMode() && mob
.getVelocity().y
< 1080) {
244 mob
.getVelocity().add(gravity
);
247 mob
.y
+= mob
.getVelocity().y
* delta
;
254 mob
.x
+= mob
.getVelocity().x
* delta
;
257 if (mob
.canJump() && mob
.getVelocity().x
!= 0 && checkJump(mob
)) {
258 mob
.getVelocity().add(0, -480);
259 mob
.setCanJump(false);
263 void update(float delta
) {
264 Player player
= mMobsController
.getPlayer();
266 for (Iterator
<Drop
> it
= mDropController
.getIterator(); it
.hasNext(); ) {
267 Drop drop
= it
.next();
268 dropPhy(drop
, delta
);
269 if (Intersector
.overlaps(drop
, player
)) {
270 drop
.pickUpDrop(player
);
272 if (drop
.isPickedUp()) {
277 for (Iterator
<Mob
> it
= mMobsController
.getIterator(); it
.hasNext(); ) {
279 mob
.ai(mGameWorld
, delta
);
286 playerPhy(player
, delta
);
287 if (player
.isDead()) {
288 player
.respawn(mGameWorld
);