package lc.world.objectes; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import lc.block.Block; import lc.world.Ground; import lc.world.World; /** * @author Death */ public class WorldObject { public static final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, VERTICALLY = 4, HORIZONTAL = 5; private World world = null; private Ground ground = null; private final Rectangle rect; private boolean accessoryFlag1; // Вспомогательные флаги public CollisionGround collisionGround = null; public CollisionGroundExpose groundExpose = null; public boolean onLand; public float x, y, speedX, speedY; public float maxSpeedX, maxSpeedY; public float width, height; public float acceleration; // Ускорение public double powAcceleration; //Степень сукорения public boolean gravity; public boolean[] moveKey; public boolean[] moveDir; public Sprite sprite = null; public TypeObjectWorld type; public WorldObject(){ this.rect = new Rectangle(); this.type = TypeObjectWorld.STATIC; this.moveKey = new boolean[4]; this.moveDir = new boolean[4]; this.maxSpeedX = 8; this.maxSpeedY = 8; this.gravity = false; this.onLand = false; this.acceleration = 10; this.powAcceleration = 1.1; this.accessoryFlag1 = false; } public void draw(SpriteBatch b){ if(sprite == null) return; sprite.setPosition(x, y); sprite.setSize(width, height); sprite.draw(b); } public Rectangle getRect(){ return rect.set(x, y, width, height); } public void initPhysics(World map){ this.initPhysics(map, true); } public void initPhysics(World map, boolean g){ this.gravity = g; this.world = map; this.ground = map.ground; } public void move(float f){ if(moveKey[RIGHT]){ speedX += this.voile(f); moveDir[RIGHT] = true; if(speedX > maxSpeedX) speedX = maxSpeedX; }else{ if(moveDir[RIGHT]){ speedX -= this.brake(f); if(speedX < 0){ speedX = 0; moveDir[RIGHT] = false; } } } if(moveKey[LEFT]){ speedX -= this.voile(f); moveDir[LEFT] = true; if(speedX < -maxSpeedX) speedX = -maxSpeedX; }else{ if(moveDir[LEFT]){ speedX += this.brake(f); if(speedX > 0){ speedX = 0; moveDir[LEFT] = false; } } } this.gravity(f); this.moveY(speedY); this.moveX(speedX); if(onLand) this.moveY(-1); // Проверка на землю. } private void gravity(float f){ if(!this.gravity || onLand) return; speedY -= 8 * f; if(speedY > maxSpeedY * 4) speedY = -(maxSpeedY * 4); } public void jump(){ if(!onLand) return;// Если не земля то не даём прыгнуть speedY = 7; } public boolean moveX(float speed){ if(speed == 0) return false; if(Math.abs(speed) > Block.SIZE){ superMoveX(Math.round(speed)); return true; } this.x = this.x + speed; return collisionGround(speed, HORIZONTAL); } public boolean moveY(float speed){ if(speed == 0) return false; if(Math.abs(speed) > Block.SIZE){ superMoveY(Math.round(speed)); return true; } this.y = this.y + speed; return collisionGround(speed, VERTICALLY); } private boolean superMoveX(int speed){ int sizeCell = this.getSizeBlock(); int sx = Math.abs(speed); int vx = sx / speed; while(sx > sizeCell){ this.x = this.x + Block.SIZE * vx; sx -= sizeCell; accessoryFlag1 = collisionGround(speed, HORIZONTAL); if(speed == 0){ sx = 0; break; } if(accessoryFlag1){ return true; } } this.x = this.x + sx * vx; return collisionGround(speed, HORIZONTAL); } private boolean superMoveY(int speed){ int sizeCell = this.getSizeBlock(); int sy = Math.abs(speed); int vy = sy / speed; while(sy > sizeCell){ this.y = this.y + sizeCell * vy; sy -= sizeCell; accessoryFlag1 = collisionGround(speed, VERTICALLY); if(speed == 0){ sy = 0; break; } if(accessoryFlag1){ return true; } } this.y = this.y + sy * vy; return collisionGround(speed, VERTICALLY); } public boolean collisionGround(float speed, int dir){ if(world == null || ground == null) return false; if(collisionBorder()) return true; for(int i = (int)(this.x / this.getSizeBlock()); i < Math.floor(this.x + this.width) / this.getSizeBlock(); i++){ for(int j = (int)(this.y / this.getSizeBlock()); j < Math.floor(this.y + this.height) / this.getSizeBlock(); j++){ boolean collision = ground.getBlock(i, j) != null; if(collision && groundExpose != null){ collision = groundExpose.expose(ground.getBlock(i, j), i, j); } if(collision){ int dirColl = 0; if(dir == HORIZONTAL){ speedX = 0; if(speed > 0){ this.x = i * this.getSizeBlock() - this.width; dirColl = RIGHT; moveDir[RIGHT] = false; }else if(speed < 0){ this.x = i * this.getSizeBlock() + this.getSizeBlock(); dirColl = LEFT; moveDir[LEFT] = false; } }else if(dir == VERTICALLY){ speedY = 0; if(speed > 0){ this.y = j * this.getSizeBlock() - this.height; dirColl = UP; moveDir[UP] = false; }else if(speed < 0){ this.onLand = true; this.y = j * this.getSizeBlock() + this.getSizeBlock(); dirColl = DOWN; moveDir[DOWN] = false; } } if(dirColl != 0 && collisionGround != null){ collisionGround.collision(i, j, dirColl); } return true; } } } if(dir == VERTICALLY){ this.onLand = false; } return false; } private boolean collisionBorder(){ if(this.x < 0){ x = 0; return true; } if(this.y < 0){ y = 0; return true; } if(this.x + this.width > world.getWidth()){ this.x = world.getWidth() - this.width; return true; } if(this.y + this.height > world.getHeight()){ this.y = world.getHeight() - this.height; return true; } return false; } public int getSizeBlock(){ return Block.SIZE; } private float voile(float f){// Ускорение в бока return voile(acceleration, f); } private float voile(float acc, float f){// Общее скорение return (float)Math.pow(acc * f, this.powAcceleration); } private float brake(float f){// Тормажение в бока return brake(acceleration, f); } private float brake(float acc, float f){// Общее ормажение return (float)Math.pow(acc * 2 * f, this.powAcceleration); } }