Skip to content

Instantly share code, notes, and snippets.

@BenMaydan
Last active September 25, 2019 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenMaydan/cb939be2ce0281a844a7190cb1e29c45 to your computer and use it in GitHub Desktop.
Save BenMaydan/cb939be2ce0281a844a7190cb1e29c45 to your computer and use it in GitHub Desktop.
Flappy bird with processing 3 and Java
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; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment