Fappy Bird

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 4

FAPPY BIRD

class World {
public ArrayList<float[]> clouds = new ArrayList<float[]>();
public void drawClouds() { for (float[] c : this.clouds) { fill(255);
ellipse(c[0], c[1], c[2], c[3]); noFill(); } }
public void createCloud(float w, float h) { this.clouds.add(new float[]
{random(this.clouds.get(this.clouds.size()-1)[0] + w, width), random(height/5), w,
h}); }
public void createClouds(int times, float w, float h) { for (int ii = 0; ii <
times; ii += 1) { this.clouds.add(new float[] {random(width), random(height/5), w,
h}); } }
}

class Bird {
private int x, y, dy;
private int r, g, b;
private float rad, dia, eyeSize, pupilSize;
private boolean wait = true;
Bird(int x, int y, float rad, float eye, float pupil, int r, int g, int b)
{ this.x = x; this.y = y; this.r = r; this.g = g; this.b = b; this.rad = rad;
this.dia = this.rad*2; this.eyeSize = eye; this.pupilSize = pupil; }

public void show() {


fill(this.r, this.g, this.b);
circle(this.x, this.y, this.dia);

// Calculate distance from center of circle to the upper right corner of the
circle
float[] point_on_circle = pointOnCircle(this.x, this.y, this.rad,
radians(315));
float point_x = point_on_circle[0];
float point_y = point_on_circle[1];
//float dist = sqrt(pow(this.rad, 2) / 2);
fill(255);
circle(point_x, point_y, this.eyeSize);
fill(0);
circle(point_x, point_y, this.pupilSize);
noFill();
}

public void flap(float amount) { this.y -= amount; }


public void fall(float amount) {
if (this.wait == false) {
if (this.y + this.rad < height) { this.y += amount; }
else {
println("YOU COLLIDED WITH THE FLOOR!");
println("YOUR SCORE: " + round(score));
game_over = true;
noLoop();
}
}
else { this.wait = false; }
}
}

class Pipe {
private int x, w;
private int r, g, b;
private float y, h;
Pipe(int x, int w, int[] c) { this.x = x; this.w = w; this.r = c[0]; this.g =
c[1]; this.b = c[2]; }

public void build(float y, float h) {


try {
// Assertions to confirm opening is not off of the screen and openings do not
overlap each other
assert y < height && y > 0 : "The bottom of the opening of the pipe should not
be off of the screen";
assert y-h < height && y-h > 0 : "The top of the opening of the pipe should not
be off of the screen";
assert y > y-h : "The bottom of the opening of the pipe and the top of the
opening of the pipe should not overlap";
// Assertion to confirm opening is big enough for the bird
assert h > bird.dia : "The opening of the pipe should be big enough for the
bird.";
this.y = y;
this.h = h;
}
catch (AssertionError e) { println(e); println("Bottom={" + y + "}\nTop={" +
(y-h) + "}" + "\nHeight={" + height + "}"); exit(); }
}

public void show() {


fill(this.r, this.g, this.b);
rect(this.x, 0, this.w, this.y-this.h);
rect(this.x, this.y, this.w, height-this.y);
noFill();
}
public void move(int amount) { this.x -= amount; }
}

float[] pointOnCircle(int x, int y, float rad, float radians) {


return new float[] {x+(rad * cos(radians)), y+(rad * sin(radians))};
}
float[] random_opening(float smallest_height, float biggest_height) {
float[] b_h = new float[2];
b_h[0] = random(biggest_height, height-10);
b_h[1] = random(smallest_height, biggest_height);
return b_h;
}
boolean circlePipeCollision(Bird b, float x, float y, float w, float h) {
float dx = abs(b.x - max(x, min(b.x, x + w)));
float dy = abs(b.y - max(y, min(b.y, y + h)));
return (dx * dx + dy * dy) < (b.rad * b.rad);
}

World world;
Bird bird;
ArrayList<Pipe> pipes = new ArrayList<Pipe>();
boolean check_score = true;
float score = 0;
boolean game_over = false;
void setup() {
fullScreen();
frameRate(120);
focused = true;
int x = width/10; int y = height/2; int rad = height/10;
int eye = 100; int pupil = 15;

// Setting up the game


world = new World();
world.createClouds(5, 300, 100);
bird = new Bird(x, y, rad, eye, pupil, 255, 255, 0);
pipes.add(new Pipe(width, 100, new int[] {0, 255, 0}));
//float[] ro = random_opening(50+bird.dia, 100+bird.dia);
float[] ro = random_opening(200+bird.dia, 300+bird.dia);
pipes.get(0).build(ro[0], ro[1]);
}

void draw() {
if (game_over) { noLoop(); }
// Only update the game if the game currently has the focus
if (focused == true) {
background(0, 150, 255);
world.drawClouds();
bird.show();

float br = bird.rad;
for (Pipe p : pipes) {
int px = p.x; float py = p.y; float ph = p.h; int pw = p.w;
p.show();
for (int ii = 0; ii <= 360; ii += 1) {
if (circlePipeCollision(bird, px, 0, pw, py-ph) ||
circlePipeCollision(bird, px, py, pw, height-py)) {
println("YOU COLLIDED WITH A PIPE!");
println("YOUR SCORE: " + round(score));
game_over = true;
break;
}
}

// Increment score if center of the bird is in a pipe


// Incrementing the score is kind of a hack. It increments by 0.1 because
this statement is checked 10 times per pipe
if (check_score == true) { if (bird.x > px && bird.x < px + pw && bird.y > py
- ph && bird.y < py) { score += 0.1; } }

// No collision, so move pipe and continue checking for collisions


p.move(5);
}
// No collision, so move bird and continue with the program
if (keyPressed == false) { bird.fall(8); }

// If the last pipe is in view, create a new pipe


if (pipes.get(pipes.size()-1).x + pipes.get(pipes.size()-1).w <= width) {
pipes.add(new Pipe(pipes.get(pipes.size()-1).x + 600, 100, new int[] {0, 255,
0}));
// Generate random y value of the size of the pipe's opening
float[] ro = random_opening(150+bird.dia, 150+bird.dia);
// The y value of the bottom of the pipe ranges from enough for the bird to
enter to + 50
pipes.get(pipes.size()-1).build(ro[0], ro[1]);
}

// Checks if the first pipe is off the screen and if it is it is deleted


if (pipes.size() >= 1 && pipes.get(0).x + pipes.get(0).w <= 0)
{ pipes.remove(0); }
}
}

void keyPressed() {
if (game_over == true && key == 89) { loop(); game_over = false; }
if (key == CODED && keyCode == UP) { bird.flap(100); focused = true; bird.wait =
true; }
else { bird.wait = true; }
}

You might also like