Setting up buttons with enums and classes

Started by
1 comment, last by Alberth 2 years, 10 months ago

I'm trying to set up everything I need to render all my buttons using enums and a button class in SDL2/C++ so that the class variables adapt depending on the enum element changes. Each button shape is a different size, individual button presence and position changes depending on game state, and all the image files have a "Button::name_Button::ButtonState" naming convention.

I'm new to C++, so having trouble translating this idea into working code. Does anyone have any ideas on how to make this more elegant?

    class Game
    {
    public:

        enum class GameState
        {
            PLAY, MENU, SETTINGS, EXIT
        };

        enum class ButtonShape
        {
           LONG, SHORT, ROUND
        };

        enum class ButtonState
        {
            DEFAULT, HOVER, INACTIVE, PRESSED
        };

        int ButtonShape::LONG::H = 128;
        int ButtonShape::LONG::W = 256;
        int ButtonShape::SHORT::H = 64;
        int ButtonShape::SHORT::W = 64;
        int ButtonShape::ROUND::H = 256;
        int ButtonShape::ROUND::W = 256;

        class Button
        {
        public:
            char name;
            ButtonShape _buttonShape;
            ButtonState _buttonState;
            GameState _gameState;
            int x = _gameState x;
            int x = _gameState y;
            int h = _buttonShape::H;
            int w = _buttonShape::W;
            string imagefile = "%c_%s.png" name, _buttonState;
        };

private:
        ButtonState _buttonState;
        ButtonShape _buttonShape;
        GameState _gameState;
};
Advertisement

jhbardwell said:
I'm new to C++, so having trouble translating this idea into working code.

A common trick is to reduce the scope of the first version a lot (as much as possible, usually). Start with 1 button, hard-coded state, hard-coded size, hard-coded position. Make it work. That gives a lot of scaffolding for translating buttons to rendered pictures.

Next, expand the scope with the smallest addition you can think of (and preferably even smaller), for example add a second button. Make it work. Next, expand the scope with the smallest addition you can think of, for example make a button 2 possible sizes. Make it work. Next, expand …. , and so on until you have everything you need.

As for code, your “Game” class is much too wide compared with “Button”. The former is just about everything, the latter is just a small area at one of the screens. Your Game class is probably closer to a View class (a layout of displayed items to allow the user to do something, like select a level, view high scores, or interact with a game level aka 'play the game'). I don't like my “View” name though hopefully you can think of a better name for it.

While you defined a Button, there is no room for storing Button instances currently. (If a View has 5 buttons, you need to store those 5 Button instances somewhere.)

Also, you shouldn't nest the above classes. A nested class is typically for handling internal details of its parent class, where that inner class is totally utterly completely useless at any other place. A Button class however can be useful outside this game. Thinking of it in another way, if you nest all your classes like this, your overall GameApplication class would become thousands of lines long. That is likely not what you want to aim for!

What you currently don't have is a Screen or Display class that displays a View.

After you got the simplest possible thing running, stuff below may become relevant:

I don't know what this is supposed to do.

int ButtonShape::LONG::H = 128;
int ButtonShape::LONG::W = 256;

An enumeration is a set of names, and each enumeration is independent, you cannot concatenate them like you do here as far as I know (unless this is a new feature beyond C++11 but I doubt that).

A better structure is a class or struct with a width and height field in it.

struct Shape {
  Shape(int w, int h) : width(w), height(h) { }
  
  int width;
  int height;
};

Shape long_shape(256, 128);

This topic is closed to new replies.

Advertisement