DEADSOFTWARE

One GameProc object for everything
[cavedroid.git] / core / src / ru / deadsoftware / cavecraft / game / GamePhysics.java
1 package ru.deadsoftware.cavecraft.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.cavecraft.CaveGame;
8 import ru.deadsoftware.cavecraft.game.mobs.Mob;
9 import ru.deadsoftware.cavecraft.game.objects.Drop;
10 import ru.deadsoftware.cavecraft.game.objects.Player;
12 import java.util.Iterator;
14 import static ru.deadsoftware.cavecraft.GameScreen.GP;
16 class GamePhysics {
18 static final int PL_SPEED = 2;
20 private Vector2 gravity = new Vector2(0, .9f);;
22 private boolean checkJump(Rectangle rect, int dir) {
23 int bl;
24 int blX = (int) (rect.x + rect.width * dir - 8 + 16 * dir);
25 int blY = (int) (rect.y + rect.height - 8);
27 bl = GP.world.getForeMap(blX / 16, blY / 16);
28 if (checkColl(new Rectangle(blX, rect.y - 18, rect.width, rect.height))) bl = 0;
30 return (bl > 0 && GameItems.getBlock(bl).toJump() &&
31 (rect.y + rect.height) - GameItems.getBlock(bl).getRect(blX / 16, blY / 16).y > 8);
32 }
34 private boolean checkColl(Rectangle rect) {
35 int bl;
36 int minX = (int) ((rect.x + rect.width / 2) / 16) - 4;
37 int minY = (int) ((rect.y + rect.height / 2) / 16) - 4;
38 int maxX = (int) ((rect.x + rect.width / 2) / 16) + 4;
39 int maxY = (int) ((rect.y + rect.height / 2) / 16) + 4;
40 if (minY < 0) minY = 0;
41 if (maxY > GP.world.getHeight()) maxY = GP.world.getHeight();
42 for (int y = minY; y < maxY; y++) {
43 for (int x = minX; x < maxX; x++) {
44 bl = GP.world.getForeMap(x, y);
45 if (bl > 0 && GameItems.getBlock(bl).hasCollision()) {
46 if (Intersector.overlaps(rect, GameItems.getBlock(bl).getRect(x, y))) {
47 return true;
48 }
49 }
50 }
51 }
52 return false;
53 }
55 private int getBlock(Rectangle rect) {
56 return GP.world.getForeMap((int) (rect.x + rect.width / 2) / 16, (int) (rect.y + rect.height / 8 * 7) / 16);
57 }
59 private void dropPhy(Drop drop) {
60 if (drop.closeToPlayer() > 0) {
61 drop.moveToPlayer();
62 } else {
63 if (drop.move.x >= .5f) drop.move.x -= .5f;
64 else if (drop.move.x <= -.5f) drop.move.x += .5f;
65 else drop.move.x = 0;
66 if (drop.move.y < 9) drop.move.y += gravity.y / 4;
67 }
68 drop.pos.add(drop.move);
69 if (drop.pos.x + 8 > GP.world.getWidthPx()) drop.pos.x -= GP.world.getWidthPx();
70 else if (drop.pos.x < 0) drop.pos.x += GP.world.getWidthPx();
71 drop.pos.y = MathUtils.round(drop.pos.y);
72 while (checkColl(drop.getRect())) {
73 drop.pos.y--;
74 drop.move.y = 0;
75 }
76 }
78 private void mobXColl(Mob mob) {
79 if (checkColl(mob.getRect())) {
80 if (mob.canJump && !mob.flyMode) {
81 mob.pos.y -= 8;
82 }
83 if (checkColl(mob.getRect())) {
84 if (mob.canJump && !mob.flyMode) mob.pos.y += 8;
85 int d = 0;
86 if (mob.mov.x < 0) d = 1;
87 else if (mob.mov.x > 0) d = -1;
88 mob.pos.x = MathUtils.round(mob.pos.x);
89 while (checkColl(mob.getRect())) mob.pos.x += d;
90 if (mob.canJump) mob.changeDir();
91 }
92 }
93 if (mob.pos.x + mob.getWidth() / 2 < 0) mob.pos.x += GP.world.getWidthPx();
94 if (mob.pos.x + mob.getWidth() / 2 > GP.world.getWidthPx()) mob.pos.x -= GP.world.getWidthPx();
95 }
97 private void mobYColl(Mob mob) {
98 if (checkColl(mob.getRect())) {
99 int d = -1;
100 if (mob.mov.y < 0) d = 1;
101 if (d == -1) {
102 mob.canJump = true;
103 mob.flyMode = false;
105 mob.pos.y = MathUtils.round(mob.pos.y);
106 while (checkColl(mob.getRect())) mob.pos.y += d;
107 mob.mov.y = 0;
108 if (mob.getType() > 0) {
109 GP.world.setForeMap(mob.getMapX(), mob.getMapY(), mob.getType());
110 mob.kill();
112 } else {
113 mob.canJump = false;
115 if (mob.pos.y > GP.world.getHeightPx()) {
116 mob.kill();
120 private void playerPhy(Player pl) {
121 pl.pos.y += pl.mov.y;
122 mobYColl(pl);
123 if (pl.isDead()) return;
125 if (GameItems.isFluid(getBlock(pl.getRect()))) {
126 if (CaveGame.TOUCH && pl.mov.x != 0 && !pl.swim && !pl.flyMode) pl.swim = true;
127 if (!pl.swim) {
128 if (!pl.flyMode && pl.mov.y < 4.5f) pl.mov.add(gravity.x / 4, gravity.y / 4);
129 if (!pl.flyMode && pl.mov.y > 4.5f) pl.mov.add(0, -1f);
130 } else {
131 pl.mov.add(0, -.5f);
132 if (pl.mov.y < -3) pl.mov.y = -3;
134 } else {
135 if (!pl.flyMode && pl.mov.y < 18) pl.mov.add(gravity);
138 pl.pos.x += pl.mov.x;
139 mobXColl(pl);
141 if (CaveGame.TOUCH && checkJump(pl.getRect(), pl.getDir()) && !pl.flyMode && pl.canJump && pl.mov.x != 0) {
142 pl.mov.add(0, -8);
143 pl.canJump = false;
147 private void mobPhy(Mob mob) {
148 mob.pos.y += mob.mov.y;
149 mobYColl(mob);
150 if (mob.isDead()) return;
152 if (mob.getType() == 0 && GameItems.isFluid(getBlock(mob.getRect()))) {
153 if (mob.mov.y > 9) mob.mov.add(0, -.9f);
154 mob.mov.add(0, -.5f);
155 if (mob.mov.y < -3) mob.mov.y = -3;
156 } else if (!mob.flyMode && mob.mov.y < 18) mob.mov.add(gravity);
158 mob.pos.x += mob.mov.x;
159 mobXColl(mob);
161 if (checkJump(mob.getRect(), mob.getDir()) && mob.canJump && mob.mov.x != 0) {
162 mob.mov.add(0, -8);
163 mob.canJump = false;
167 void update(float delta) {
168 //TODO use delta time
169 for (Iterator<Drop> it = GP.drops.iterator(); it.hasNext(); ) {
170 Drop drop = it.next();
171 dropPhy(drop);
172 if (Intersector.overlaps(drop.getRect(), GP.player.getRect())) drop.pickUpDrop(GP.player);
173 if (drop.pickedUp) it.remove();
176 for (Iterator<Mob> it = GP.mobs.iterator(); it.hasNext(); ) {
177 Mob mob = it.next();
178 mob.ai();
179 mobPhy(mob);
180 if (mob.isDead()) it.remove();
183 playerPhy(GP.player);
184 if (GP.player.isDead()) GP.player.respawn();
186 GP.renderer.setCamPos(
187 GP.player.pos.x + GP.player.getWidth() / 2 - GP.renderer.getWidth() / 2,
188 GP.player.pos.y + GP.player.getHeight() / 2 - GP.renderer.getHeight() / 2);