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; } } }