Making Flappy Bird in my Game Engine. How hard can it be? - [Helicity.ai Part 3]
Tags: javascript, programming, gamedev, learning
Published: 2023-07-08 21:27:41

Hello everyone! 🙋‍♂️ I thought I'd share my latest game development adventure with you all. Recently, I thought to myself, _"Making Flappy Bird in my own game engine? How hard can it be?" 🤔_

I learned a lot of things I need to add to my Engine.

[Helicity.ai](https://helicity.ai) is my Game Engine. 

Here is the source [😺github](https://github.com/lil-shake-code/helicity.ai)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rxbzcgmu6wi0hrgadawn.png)



#Step by Step Guide
##Step 1: Importing the Necessary Modules 📚

```
// Import modules
import { GameObject } from "./Gameobject.js";
import { Input } from "./Input.js";
import { Physics } from "./Physics.js";
import { Renderer } from "./Renderer.js";
import { Game } from "./Engine.js";
```
First things first, we need to import our modules! They're the backbone of our game and do a ton of heavy lifting for us. 🏋️‍♀️
You can see what every module does on the github link. But they handle specific sections of the game.

##Step 2: Setting Up the Bird 🐤


```
var score = 0;
// Create Bird class that extends GameObject
class Bird extends GameObject {
  constructor(x, y, width, height, imageSrc) {
    super(x, y, width, height, "bird", imageSrc);
    this.velocityY = 0;
    this.gravity = 0.3;
  }

    // Check for input to control the bird
    if (Input.getState().keys["space"] || Input.getState().mouseLeftDown) {
      this.velocityY = -7;
    }

    //draw score 
    Renderer.drawText("Score: "+score,30,30,25,"black","Arial")
  }
}
```
The **GameObject** is a Class which takes in constructor **(x, y, width, height, some-type-tag, image-source)**  The game engine is build around playing with these instances and their update() methods, that have the frame wise logic.

Here, we're creating a Bird class that extends our GameObject. 
The bird is the main object of our game! 🌟 We're giving it a velocity and gravity property to handle its movement. 🌍
Also I'm drawing the score property.

_We don't REALLLY need a class for the Bird because it will only have 1 instance but I guess that's good practice?_

##Step 3: Moving the Bird 🕹
Inside our Bird class, we also have an update function. This is where all the magic happens - we update the bird's position, check for collisions, and handle user input. 🎮
Basic rectangular collisions are handled by **Physics.checkCollision(gameobject1 , gameobject2)**

```
class Bird extends GameObject {
  constructor(x, y, width, height, imageSrc) {
    super(x, y, width, height, "bird", imageSrc);
    this.velocityY = 0;
    this.gravity = 0.3;
  }

  update() {
    // Apply gravity
    this.velocityY += this.gravity;
    this.y += this.velocityY;

    // Check for collision with pipes
    for (const pipe of Game.gameObjects) {
      if (pipe.type === "pipe" && Physics.checkCollision(this, pipe)) {
        Game.stop();
        Renderer.drawText("Game Over", 100, 100, 30, "black", "Arial");
      }
    }

    // Check for input to control the bird
    if (Input.getState().keys["space"] || Input.getState().mouseLeftDown) {
      this.velocityY = -7;
    }

    //draw score 
    Renderer.drawText("Score: "+score,30,30,25,"black","Arial")
  }
}
```

##Step 4: Creating the Pipes 🌆

```
// Create Pipe class that extends GameObject
class Pipe extends GameObject {
  constructor(x, y, width, height, imageSrc) {
    super(x, y, width, height, "pipe", imageSrc);
    this.velocityX = -2;
  }

  update() {
    this.x += this.velocityX;

    // Remove pipe when it goes off the screen
    if (this.x + this.width < 0) {
      Game.gameObjects.splice(Game.gameObjects.indexOf(this), 1);
    }
  }
}
```
Next up are our infamous pipes! Just like our bird, we create a Pipe class that extends GameObject. We're giving each pipe a constant velocity to make it move. 🏙

##Step 5: Adding Our Bird 🎲
After creating our classes, it's time to instantiate our bird or any other game objects and add them to our game 🧩. I just picked up some png from Google.

```
const bird = new Bird(100, 200, 50, 50, "https://freepngimg.com/thumb/logo/109941-logo-bird-flappy-free-transparent-image-hq.png");

```

##Step 6: Spawning the Pipes ⏱
We're using a setInterval function to spawn our pipes every two seconds. Every time a new set of pipes is spawned, our score increases. 📈

```
// Create pipes every second
setInterval(() => {
  if(Game.isRunning){
    score++;
  }
  const pipeTop = new Pipe(Renderer.canvas.width, 0, 100, Math.random() * 200 + 100, "https://upload.wikimedia.org/wikipedia/commons/9/93/Mario_pipe.png");
  const pipeBottom = new Pipe(Renderer.canvas.width, pipeTop.height + 300, 100, 600 - pipeTop.height - 200, "https://upload.wikimedia.org/wikipedia/commons/9/93/Mario_pipe.png");
  Game.gameObjects.push(pipeTop, pipeBottom);
}, 2000);
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcf3onb0o0e6d9t3x3ls.png)




**This is when I realised I need xscale and yscale properties ASAP in my game object, I mean look at how the pipes are spawning!**

#Conclusions
Finally, we start our game with `Game.start()`. **Now, I can tell people I made flappy bird in my own engine! 🎉**

**But honestly its more about improving the engine and what this taught me. If I need to make this a real thing, it needs to be usable. Also we need a background component.**


So that's it! Creating a Flappy Bird clone in my game engine turned out to be a fun and enlightening experience! 🎈🎊 I hope you found this post helpful and inspiring. Don't hesitate to reach out if you have any questions or comments. Happy coding! 🚀🚀🚀

## Discord link - Support Development

[Discord](https://discord.com/invite/RkH98RgVDr)