package me.hammerle.snuviengine.game; import java.util.List; import me.hammerle.snuviengine.api.Shader; import me.hammerle.snuviengine.game.BoxList.Node; import me.hammerle.snuviengine.util.Face; public class Entity implements IBoxListEntry { private static final double STEP = 0.0625; public Game game; public double lastXPos; public double lastYPos; public double xPos; public double yPos; public double width; public double height; public double vx = 0.0f; public double vy = 0.0f; public Node node; public int counter = 0; public Entity(Game game, double width, double height) { this.game = game; xPos = 0.0f; yPos = 0.0f; this.width = width; this.height = height; vx = 1; //Math.random() * 8 + 5; vy = 1; //Math.random() * 8 + 5; } private boolean isColliding(Entity ent) { return xPos + width > ent.xPos && ent.xPos + ent.width > xPos && yPos + height > ent.yPos && ent.yPos + ent.height > yPos; } @Override public boolean isColliding(double minX, double minY, double maxX, double maxY) { return xPos + width > minX && maxX > xPos && yPos + height > minY && maxY > yPos; } public void tick() { if(!(this instanceof Hero)) { if(xPos < STEP) { vx = Math.abs(vx); } if(xPos + width > 400 - STEP) { vx = -Math.abs(vx); } if(yPos < STEP) { vy = Math.abs(vx); } if(yPos + height > 300 - STEP) { vy = -Math.abs(vx); } } lastXPos = xPos; lastYPos = yPos; if(vx == 0.0 && vy == 0.0) { return; } double lvx = vx; double lvy = vy; List list = game.entities.getAllEntitiesAt(this, xPos - STEP + ((vx < 0) ? vx : 0), yPos - STEP + ((vy < 0) ? vy : 0), xPos + STEP + width + ((vx > 0) ? vx : 0), yPos + STEP + height + ((vy > 0) ? vy : 0)); if(list.isEmpty()) { xPos += vx; yPos += vy; game.entities.update(this); return; } while(lvx != 0.0 || lvy != 0.0) { double oldXPos = xPos; double oldYPos = yPos; if(lvx < 0.0) { if(lvx > -STEP) { xPos += lvx; lvx = 0.0; } else { xPos -= STEP; lvx += STEP; } } else if(lvx > 0.0) { if(lvx < STEP) { xPos += lvx; lvx = 0.0; } else { xPos += STEP; lvx -= STEP; } } for(Entity ent : list) { if(this.isColliding(ent)) { lvx = 0.0f; xPos = oldXPos; break; } } if(lvy < 0.0) { if(lvy > -STEP) { yPos += lvy; lvy = 0.0; } else { yPos -= STEP; lvy += STEP; } } else if(lvy > 0.0) { if(lvy < STEP) { yPos += lvy; lvy = 0.0; } else { yPos += STEP; lvy -= STEP; } } for(Entity ent : list) { if(this.isColliding(ent)) { lvy = 0.0f; yPos = oldYPos; break; } } } game.entities.update(this); for(Face f : Face.values()) { double minX = xPos + STEP * f.getOffsetX(); double minY = yPos + STEP * f.getOffsetY(); double maxX = minX + width; double maxY = minY + height; list.stream().filter(ent -> ent.isColliding(minX, minY, maxX, maxY)) .forEach(ent -> onCollide(f, ent)); } } public void onCollide(Face f, Entity ent) { switch(f) { case UP: vy = Math.abs(vy); break; case DOWN: vy = -Math.abs(vy); break; case LEFT: vx = Math.abs(vx); break; case RIGHT: vx = -Math.abs(vx); break; } } public void renderTick(float lag) { Shader.getColorRenderer().setDepth((float) yPos); float x = (float) (lastXPos + (xPos - lastXPos) * lag); float y = (float) (lastYPos + (yPos - lastYPos) * lag); Shader.getColorRenderer().drawRectangle(x, y, (float) (x + width), (float) (y + height), 0x770000FF); } public double getX() { return xPos; } public double getY() { return yPos; } public void setPosition(double x, double y) { xPos = x; yPos = y; } @Override public double getCenterX() { return xPos + width / 2; } @Override public double getCenterY() { return yPos + height / 2; } @Override public double getWidth() { return width; } @Override public double getHeight() { return height; } @Override public Node getNode() { return node; } }