Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Flappy-Bird Clone Attempt  (Read 11960 times)

0 Members and 2 Guests are viewing this topic.

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Flappy-Bird Clone Attempt
« on: January 24, 2018, 09:13:55 pm »
Hello forums,
I created my first project using sfml but as an inexperienced programmer some constructive criticism, guidance and tips for my future projects would be good. If you like reading random code. Feel free to check it out :)

https://github.com/Powereleven/Flappy-Bird-Clone

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #1 on: January 24, 2018, 10:14:13 pm »
Just skipped through it a bit, looks interesting.

But just some tiny hint I immediately noticed for your code – and since you're asking:

If you want to convert a single digit number to a character representing that digit, you can just add it to '0'.
Basically this:
Code: [Select]
int digit1 = 5;
int digit2 = 9;

char char1 = '0' + digit1; // this is now '5'
char char2 = '0' + digit2; // this is now '9'

You should try to properly indent your code so it becomes more readable.

Since you're doing a classic entity based design, you should put the logic into your entities. For example,
 add the bird controls into the Bird class.

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #2 on: January 25, 2018, 12:23:14 am »
"Since you're doing a classic entity based design, you should put the logic into your entities. For example,
 add the bird controls into the Bird class."

@Mario what if the bird functions depend on objects of another class that are just created in main?
For example in:  if(bird.counter%3==0){current_obstacle_x = first->x; current_obstacle_y = first->y;} , where first is an object of another class which is just created in main and current_obstacle_x and current_obstacle_y are variables created in main.
« Last Edit: January 25, 2018, 12:40:33 am by Powereleven »

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #3 on: January 25, 2018, 02:54:14 am »
If an object needs to know some data of another object (that is very common), the only way (at least what my experience tells me) is to pass a reference of the 2nd to the 1st(*). Usually in my games, every enemy or animated object (such as blocks in Super Mario games) has a reference of the player (that is passed in its constructor) and so they are able to process both their atacks to the player and player's attacks to them.

If the bird is your game main character, I think it would be better that the other objects have a reference to it. In your game class you create a Bird object, and then when you create the enemies and other objects, you pass them a reference to the Bird. So they can read and modify the player's attributes, and theirs, in function of it. Because the bird's control depends on you (even if you crash against an enemy and die), not on the enemies, but what they do (attack you, die if you kill them, etc) does depend on the bird (and on other instruction set or behavior you program them to do that are independent of anything). That's why it is better to pass a reference of the player to the other objects and not on the contrary.

(*) Remember that in C++ the subject of references and pointers and all that stuff is not simple as it is in C#.

Hope this helps

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #4 on: January 25, 2018, 03:44:29 am »
@Tigre Pablito thanks for this explanation. But if it isn't asking too much, is it possible to give me a practical example with 2 classes so I can see exactly how it works?

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #5 on: January 25, 2018, 09:16:25 pm »
You can see the code below that shows how an object can access (read and write) another object.

You just need to add a class attribute of the type Bird in all the enemies and every class that needs to access it. In the constructor you add a parameter of that type, and when you create an enemy object you pass as last argument a reference to the Bird object. Then you can simply read from or write to that variable. You don't need to pass it to the enemy class internal methods because it is a class global variable, visible in all the class. The attributes of the Bird that need to be accessed have to be public or as a property (or the way that C++ implements for a variable to be accessed outside its class). Remember that in C++ the syntax for references and pointers is a bit complicated, it's not as in C#, so the code I write here is not C++, but the idea is OK. You should just change the syntax

You also can see this mechanism in this game, my smallest one (it's written in C#, but the concept is the same)

https://www.dropbox.com/s/qf5rpk4zlid8l6d/PAC-MAN%20Folder.rar?dl=0


class Enemy
{
    private Bird player;
    private int x, y;
    // other vars

    public Enemy(int x, int y, Bird player)
    {
        this.x = x;
        this.y = y;    
        this.player = player;

        // other vars
    }

    public void Draw()    // or Update()
    {
        if (this.y < player.y)  // read from the player's reference (or address)
            ;  // the bird is under the enemy

        if (Collision())  // define Collision()
            player.life = 0;   // write to the player through its address (then the Bird should know that to do)

        if (IsHitByBird())  // define IsHitByBird()
            this.life = 0;      // you killed the enemy

        // do other stuff ( like move )
    }
}

 

Please let me know if it works

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #6 on: January 26, 2018, 02:47:28 am »
@Tigre Pablito
I attempted to do what you suggested in the Collision.h file and it worked. I don't know if it is the only way to do it though. It was pretty meach trial and error until I got it right  :P 
Some critique about this second version would be great. By the way, I am also new to GitHub, so just a quick question: is it possible to download the sounds I upload there? Because I click to download them and it's not working lol. Sorry for my stupid questions.

https://github.com/Powereleven/Flappy-Bird---2nd-attempt

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #7 on: January 27, 2018, 01:20:45 am »
I was just seeing the main.cpp file. Actually, how much complicated is C++! How courageous have to be programmers who use it!

In a while I'll try to see all the project files in a C++ IDE when I'm at home. But a couple of things now:
1) the app object (of type RenderWindow) should also be passed as an argument to the constructors of all objects that need it instead of being passed to all functions. That would be better performance and tidier code.
2) I think it would be better to define a Game class which declares the bird and obstacle objects (and letters and all other stuff), with a RunGame() method (or function). That is, for the main() function isn't so untidy. You also could create a class for the group of Obstacles (with a List or Vector to store them), to make it more efficient, and check the collision bird-obstacle one by one (in a loop, not to pass the 3 obstacles and the bird to a same function).
Usually, while more you group the game components into objects, better and tidier will be the code.



Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #8 on: January 27, 2018, 02:29:10 am »
1) To be honest I don't know if I should call the app object (of type RenderWindow) on the function or the constructor. I still didn't learn to handle multiple views (intend to read that tutorial in the future, (it wasn't necessary for this project)), but I imagine that if the same object has to be used on two views, I should call it on the draw function so I can specify on which one right? (If that was a terrible assumption, sorry :P)
2) A Game Class is a good idea, but I thought this project was too small to deserve another class   ;D

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #9 on: January 27, 2018, 04:06:13 am »
Well, I didn't see (or realize) you were implementing 2 views. Anyway, as the RenderWindow object (app) is the same, independently of what function it is passed to, I think it would be better to pass it as a parameter in the constructor (the function that creates the object - I don't know exactly how it is in C++). That's because you just pass that var (app, bird, etc) ONCE, and then you can simply access it from anywhere in the class without extra parameter adding in every internal class function. But ... you don't call a var ... you call a function ... you pass the var as a parameter (in this case)  ;)

class Obstacle
{
    private int x, y;
    private Bird bird;
    private RenderWindow app;
    // other variables

    // pass the Bird and RenderWindow references so you can use them directly in the class
    public Obstacle(int x, int y, Bird bird, RenderWindow app)     
    {
        this.x = x; this.y = y;
        this.bird = bird;     // assign the Bird reference to a class var through you can access that object
        this.app = app;     // the same for the RenderWindow
        // other assignments
    }

    public void Draw()  // here you don't need to pass the bird, app, etc, as a parameter
    {
        if (Collision(this, this.bird) {    // this.bird contains the Bird object reference
            // do something ;

            // other stuff

            this.app.Draw(obstacleTexture);   // this.app contains the RenderWindow object reference
        }
    }
}

Regarding to the program model, I think that even the smallest ones would be more easier to make (read, understand, ...) if you try to organize it acording to the common practices ... it would be easier to develop for you, and easier to read and understand to other people

I'll try to see the entire code to give my view better  ;D

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #10 on: January 29, 2018, 04:05:30 am »
Could you tell me what version of VC++ and SFML should I use to run the Bird game? I really tried, downloaded Visual Studio 14 (C++) and SFML 2.4.2 and I can't build the app, there are linker errors, so it could be that is a wrong version. I think it would be interesting to run the game.
Thanks

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #11 on: January 29, 2018, 06:11:34 am »
I use CodeBlocks because it's free. I followed this video to set it up:

But if you use the codeblocks link he put in the description you will get errors because codeblocks is now in version 17.12 and for some reason the loadFromFile didn't work for me (that was a few weeks ago). So you have to download the 16.01 version:
https://sourceforge.net/projects/codeblocks/files/Binaries/16.01/Windows/
Using codeblocks 16.01, SFML 2.4.2 and following this tutorial it worked for me. Good luck, make sure to download the correct codeblocks (as I recall, the codeblocks-16.01mingw-setup.exe one)
PS: I am a newbie at settings up IDEs and libraries and there are definitely other ways, I am just saying how I got it working for me.


Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: Flappy-Bird Clone Attempt
« Reply #12 on: January 31, 2018, 04:26:38 pm »
Could you Powereleven or someone tell me what's the trick here? I attach the screenshot of the error window
Thanks in advance

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #13 on: January 31, 2018, 06:33:00 pm »
On the same folder where you have all the files (Bird.h, Bird.cpp for example) you have to create another folder called fonts and put there arial.ttf (that's because I called sf::Font font; font.loadFromFile("fonts/arial.ttf") . You can download this font from GitHub where you got the other files. Same thing for the images. I call t.loadFromFile("images/bird.png"); for example, so you have to have a folder "images" with all the 4 images in there. I also used a folder sounds, with all sounds in there, but I don't know how you download sounds from GitHub, so if you can't manage to download them, it should be fine, because they are not a must to run the program. If you don't have the sounds folder with the sounds in there, it should just pop up 3 error messages in the console"Failed to ... ". I attach the screenshots. Do you have all the .dll sfml files in the same folder as in the screenshot below?
« Last Edit: January 31, 2018, 06:39:05 pm by Powereleven »

Zinidane

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Flappy-Bird Clone Attempt
« Reply #14 on: January 31, 2018, 06:36:08 pm »
Those are linking problems. Could be multiple thing

1. Did you set the right library search path in your project ?
2. Did you set the right libraries in the compiler settings (sfml_xxxx_xx.lib and stuff)
3. Did you put the dlls in your project (if you did not use SFML_STATIC)

if there's something you don't understand in those 3 steps, read or watch the setup guide carefully. Good luck

 

anything