package com.thomshutt.fappybird.drawable;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Polygon;
import com.badlogic.gdx.math.Rectangle;
import com.thomshutt.fappybird.Drawable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class PipeFactory implements Drawable {
private static final int PIPE_INTERVAL_PIXELS = 280;
private static final int MIN_PIPES_IN_MEMORY = 5;
private static final int MIN_PIPE_Y = 210;
private static final int MAX_PIPE_Y = 360;
private final Texture texturePipe;
private final Texture texturePipeTop;
private final int pipeSpeed;
private float screenWidth;
private float screenHeight;
private float pipeWidth;
private float textureScale;
private float pipeHeight;
private List<Pipe> pipes = new ArrayList<Pipe>();
private float pipeGap = 0;
private final Random random = new Random(System.currentTimeMillis());
private int numPipesPassed = 0;
public PipeFactory(FileHandle imageBottom, FileHandle imageTop, int pipeSpeed) {
this.pipeSpeed = pipeSpeed;
this.texturePipe = new Texture(imageBottom);
this.texturePipeTop = new Texture(imageTop);
this.pipes.add(new Pipe(PIPE_INTERVAL_PIXELS, generatePipeY()));
}
private int generatePipeY(){
return -(this.random.nextInt(MAX_PIPE_Y - MIN_PIPE_Y) + MIN_PIPE_Y);
}
@Override
public void tick(float deltaTime) {
for (Pipe pipe : pipes) {
pipe.x -= this.pipeSpeed * deltaTime;
}
while(this.pipes.size() > 0 && this.pipes.get(0).hasMovedOffScreen(this.screenWidth)){
this.pipes.remove(0);
}
while(this.pipes.size() < MIN_PIPES_IN_MEMORY){
this.pipes.add(new Pipe(this.pipes.get(this.pipes.size() - 1).x + PIPE_INTERVAL_PIXELS, generatePipeY()));
}
}
@Override
public void draw(SpriteBatch batch) {
for (Pipe pipe : this.pipes) {
batch.draw(this.texturePipe, pipe.x, pipe.y, pipeWidth, pipeHeight);
batch.draw(this.texturePipeTop, pipe.x, pipe.y + this.pipeHeight + pipeGap, pipeWidth, pipeHeight);
}
}
@Override
public void resize(int width, int height) {
this.screenWidth = width;
this.screenHeight = height;
this.pipeWidth = this.screenHeight / 10;
this.textureScale = this.pipeWidth / this.texturePipe.getWidth() ;
this.pipeHeight = this.texturePipe.getHeight() * textureScale;
this.pipeGap = (this.screenHeight / 10) * 2.8f;
}
@Override
public void screenTouched(boolean touched) {
// Pipes don't care about the screen being touched
}
@Override
public boolean isInCollisionWith(Bird bird) {
for (Pipe pipe : pipes) {
if(bird.getX() > pipe.x && ! pipe.birdHasPassed){
pipe.birdHasPassed = true;
this.numPipesPassed++;
}
// if(intersectRectanglePolygon(bird.getPolygon(), pipe.getBottomRectangle(pipeWidth, pipeHeight))) return true;
// if(intersectRectanglePolygon(bird.getPolygon(), pipe.getTopRectangle(pipeWidth, pipeHeight, pipeGap))) return true;
// if(Intersector.intersectRectangles(bird.getPolygon(), pipe.getBottomRectangle(pipeWidth, pipeHeight), new Rectangle())) return true;
// if(Intersector.intersectRectangles(bird.getPolygon(), pipe.getTopRectangle(pipeWidth, pipeHeight, pipeGap), new Rectangle())) return true;
if(Intersector.overlaps(bird.getCircle(), pipe.getBottomRectangle(pipeWidth, pipeHeight))) return true;
if(Intersector.overlaps(bird.getCircle(), pipe.getTopRectangle(pipeWidth, pipeHeight, pipeGap))) return true;
}
return false;
}
// private static boolean intersectRectanglePolygon(Polygon polygon, Rectangle rectangle){
// return Intersector.
// return false;
// }
public int getNumPipesPassed() {
return numPipesPassed;
}
private class Pipe {
float x;
float y;
boolean birdHasPassed = false;
private Pipe(float x, float y) {
this.x = x;
this.y = y;
}
public Rectangle getBottomRectangle(float pipeWidth, float pipeHeight) {
return new Rectangle(this.x, this.y, pipeWidth, pipeHeight);
}
public Rectangle getTopRectangle(float pipeWidth, float pipeHeight, float pipeGap) {
return new Rectangle(this.x, this.y + pipeGap + pipeHeight, pipeWidth, pipeHeight);
}
public boolean hasMovedOffScreen(float screenWidth) {
return this.x < -screenWidth;
}
}
}