package me.hammerle.supersnuvi.entity.components.ai; import java.util.ArrayList; import me.hammerle.snuviengine.api.Shader; import me.hammerle.snuviengine.api.Texture; import me.hammerle.supersnuvi.entity.Entity; import me.hammerle.supersnuvi.gamelogic.Level; import me.hammerle.supersnuvi.tiles.Tile; import me.hammerle.supersnuvi.util.Face; import me.hammerle.supersnuvi.util.Utils; public class PlatformController extends Controller { private final static Texture TEXTURE = new Texture("resources/platform.png"); private static class MoveData { private final float x; private final float y; private final float speedX; private final float speedY; private final int waitTicks; public MoveData(float x, float y, float speedX, float speedY, int waitTicks) { this.x = x; this.y = y; this.speedX = Math.abs(speedX); this.speedY = Math.abs(speedY); this.waitTicks = waitTicks; } } private final ArrayList dataList = new ArrayList<>(); private int moveIndex = 0; private int waitTicks = 0; private int samePosX = 0; private int samePosY = 0; @Override public boolean isAnimated() { return true; } public void addMoveData(float x, float y, float speedX, float speedY, int waitTicks) { dataList.add(new MoveData(x, y, speedX, speedY, waitTicks)); } public void clearMoveData() { dataList.clear(); } private float clamp(float f, float min, float max) { if(f < min) { return min; } else if(f > max) { return max; } return f; } @Override public void tick(Entity ent, Level level) { if(dataList.isEmpty()) { return; } MoveData data = dataList.get(moveIndex); if(ent.isAt(data.x, data.y)) { waitTicks++; if(waitTicks >= data.waitTicks) { waitTicks = 0; moveIndex = (moveIndex + 1) % dataList.size(); } } else { float motionX = clamp(data.x - ent.getX(), -data.speedX, data.speedX); float motionY = clamp(data.y - ent.getY(), -data.speedY, data.speedY); ent.applyOwnForce(motionX, motionY); } } @Override public void renderTick(Entity ent, float lag) { TEXTURE.bind(); float x = Utils.interpolate(ent.getLastX(), ent.getX(), lag); float y = Utils.interpolate(ent.getLastY(), ent.getY(), lag); int mid = (int) Math.ceil((ent.getWidth() / Tile.SIZE) - 2); float endY = y + ent.getHeight(); Shader.getTextureRenderer().drawRectangle(x, y, x + Tile.SIZE, endY, 0.0f, 0.25f, 0.25f, 0.4453125f); x += Tile.SIZE; for(int i = 0; i < mid; i++) { Shader.getTextureRenderer().drawRectangle(x, y, x + Tile.SIZE, endY, 0.25f, 0.25f, 0.5f, 0.4453125f); x += Tile.SIZE; } Shader.getTextureRenderer().drawRectangle(x, y, x + Tile.SIZE, endY, 0.5f, 0.25f, 0.75f, 0.4453125f); } @Override public void onCollideWithEntity(Entity ent, Entity other, Face face) { if(face == Face.UP) { if(ent.getOwnForceY() < 0) { other.applyForce(ent.getOwnForceX(), ent.getOwnForceY() - Entity.GRAVITY * other.getMovement().getGravityFactor()); } else { other.applyForce(ent.getOwnForceX(), ent.getOwnForceY()); } } else if(face == Face.LEFT || face == Face.RIGHT) { other.applyForce(ent.getOwnForceX(), 0.0f); } } }