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

Author Topic: Drag and Drop - Code Review  (Read 2311 times)

0 Members and 1 Guest are viewing this topic.

Jycerian

  • Newbie
  • *
  • Posts: 49
  • Weakness of attitude becomes weakness of character
    • View Profile
Drag and Drop - Code Review
« on: October 12, 2014, 07:13:14 pm »
Hey guys, I have basically finished my first game named Gravity Surge (http://en.sfml-dev.org/forums/index.php?topic=15512.0) and now I am busy with my next game and learning more about programming.

My new game will be some sort of level editor/game combo and this is my first attempt for a drag and drop but I have no clue if my code is any good or not because I am not that advanced yet, I would really like to know what your opinions are!

Note : I intentionally made this one file just to learn.



Code :
(click to show/hide)
« Last Edit: October 12, 2014, 07:15:22 pm by Jycerian »

dabbertorres

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
    • website/blog
Re: Drag and Drop - Code Review
« Reply #1 on: October 12, 2014, 07:36:28 pm »
First thing I noticed is that you're using some C-style headers and some C-style code.

For the headers:
#include <cstdio>
#include <cstdlib>
#include <ctime>
 

is the more C++ way of doing it.

Second, in modern C++, you don't use NULL, srand, rand, and time.
You use nullptr, <random>, and <chrono> (respectively).
Just google those two headers for guides to using them.

Those are the first things I noticed in my quick look over.

Xornand

  • Jr. Member
  • **
  • Posts: 78
  • C++ / Python
    • View Profile
Re: Drag and Drop - Code Review
« Reply #2 on: October 12, 2014, 07:56:25 pm »
If I could suggest something, calling draw() every time you render a rectangle isn't the most efficient way to do it - that approach just doesn't scale well and could be a major bottleneck if you were drawing hundreds of rectangles every frame.

The approach I would suggest instead, would be to externally create and then load the texture of the rectangle as sf::Texture - or, you could create sf::RenderTexture and draw sf::RectangleShape (filled with the color of your choice) to it only once, upon initialization. The next step would be to create a custom Rectangle class, which would store sf::VertexArray, representing four corners. All the Rectangle instances would be then stored in some sort of container, so on each update you would be iterating over all the rectangles and copying their vertices onto one sf::VertexArray. After copying all the vertices, you could then just make one draw call, passing the sf::VertexArray and sf::RenderStates (with the texture parameter set to the texture of your rectangles).

The code would look something like that:
struct Rectangle
{
        sf::VertexArray vertexArray;
};

void render()
{
        sf::VertexArray vertexArray(sf::Quads);

    // let's assume that Rectangle instances are stored in std::vector<Rectangle>
        std::for_each(rectangles.begin(), rectangles.end(),
                [&](Rectangle& rectangle)
                {
                        for (auto i = 0; i < 4; ++i)
                        {
                                vertexArray.append(rectangle.vertexArray[i]);
                        }
                }
        );

        sf::RenderStates states;
        states.texture = texture.get(); // "texture" is std::shared_ptr<sf::Texture> stored somewhere else

    window.clear();
        window.draw(vertexArray, states); // only one draw call for all the rectangles
        window.display();
}
« Last Edit: October 12, 2014, 08:05:50 pm by Xornand »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10835
    • View Profile
    • development blog
    • Email
Re: Drag and Drop - Code Review
« Reply #3 on: October 13, 2014, 01:34:05 pm »
As dabbertorres said:
  • Use C++ headers
  • Use the <random> header (C++11) for random numbers.
  • Use the <chrono> header (C++11) for time related stuff.

Furter more:
  • Don't use #define for constants, instead use an actual constant const unsigned int WIDTH = 10
  • Use a loop for adding blocks, instead of c&p the same line n times.
  • Use std::swap instead of std::iter_swap (see here).
  • If you use a class, you could write functions for the event handling, making the event handling block a lot easier to read.
  • If you just iterate over all the elements, you could use the range for loop (C++11).
  • You'd probably be better of by having a class for the blocks, so you could add properties etc. to it.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/