문제

So, again, making a pong clone, and run into a bump. I'm creating the game class gamestate for my state machine and in the definition, I instantiate two classes of the class I've created for the the different player paddles and I give them two different arguments that will decide if the class becomes the player one or player two object.

But it seems like the program won't allow me to pass an argument in the class definition. I've tried to put the class instantiation in the game class constructor but then the events/logic/render functions don't have access to the paddle classes. That leads me to think it has to be in the game class definition. Here's the code presenting the problem.

class Ball
{
public:
    void events();
    void logic();
    void render();
    Ball(int server);
    ~Ball();
};

class Paddle
{
private:
    SDL_Rect Paddle_Bound;
    int yVel;
    SDL_Rect *clip;
    int player_key;
public:
    void events();
    void logic();
    void render();
    Paddle(int player);
    ~Paddle();
};

class Game : public GameState
{
private:
    int server;
    TTF_Font *score = NULL;
    Paddle PlayerOne(1);
    Paddle Playertwo(2);
    Ball Ball(2);
public:
    void events();
    void logic();
    void render();
    Game();
    ~Game();
};

The lines that say

Paddle PlayerOne(1);
Paddle Playertwo(2);
Ball Ball(2);

Are the ones raising errors that say "expected a type specifier". Now I know that means it wants something like int player but I need to pass a number so that the constructor can decide which player it'll be, which ultimately decides what keys move the class up and down the screen. So to be perfectly clear, I want to be able to pass an argument to a class instantiation so that the class constructor can turn the class into the left OR the right paddle. So how do I go about instantiating a class, inside another class, using arguments?

Thanks!

EDIT: For the constructor problem I have another example that is fully coded where I can't put the class initializer in the constructor. So basically in the title screen there is one button, and it has properties stored in a Button class that I create to manage buttons.

class GameState
{
public:
    virtual void events() = 0;
    virtual void logic() = 0;
    virtual void render() = 0;
    virtual ~GameState(){};
};

class Button
{
public:
    SDL_Rect button_clip[2];
    SDL_Rect button;
    SDL_Surface *button_sprite = NULL;
    Button();
};

class Title : public GameState
{
private:
    SDL_Surface *Title_Message = NULL;
    SDL_Rect *clip;
    // THIS IS WHERE I HAVE TO PLACE THIS LINE 
    //Button Title_Button;
public:
    void events();
    void logic();
    void render();
    Title();
    ~Title();
};

Title::Title()
{
    //THIS IS WHERE IT SHOULD BE ACCORDING TO WHAT YOU'RE TELLING ME
    Button Title_Message;
    //text/sprites
    Title_Message = TTF_RenderText_Solid(font, "PONG", color);
    Title_Button.button_sprite = load_image("Start.png");
    //region for button
    Title_Button.button.x = 200;
    Title_Button.button.y = 350;
    Title_Button.button.w = 100;
    Title_Button.button.h = 50;
    //clips not hover
    Title_Button.button_clip[0].x = 0;
    Title_Button.button_clip[0].y = 0;
    Title_Button.button_clip[0].w = 100;
    Title_Button.button_clip[0].h = 50;
    //clips hover
    Title_Button.button_clip[1].x = 0;
    Title_Button.button_clip[1].y = 50;
    Title_Button.button_clip[1].w = 100;
    Title_Button.button_clip[1].h = 50;
}

Title::~Title()
{
    SDL_FreeSurface(Title_Message);
    SDL_FreeSurface(Title_Button.button_sprite);
}

void Title::events()
{
    int x = 0;
    int y = 0;
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_MOUSEMOTION)
        {
            x = event.motion.x;
            y = event.motion.y;
            if ((x > Title_Button.button.x) && (x < (Title_Button.button.x + Title_Button.button.w)) && (y > Title_Button.button.y) && (y < (Title_Button.button.y + Title_Button.button.h)))
            {
                clip = &Title_Button.button_clip[1];
            }
            else
            {
                clip = &Title_Button.button_clip[0];
            }
        }
        if (event.type == SDL_QUIT)
        {
            quit = true;
        }
        if (event.type == SDL_MOUSEBUTTONDOWN)
        {
            if (event.button.button == SDL_BUTTON_LEFT)
            {
                if ((x > Title_Button.button.x) && (x < (Title_Button.button.x + Title_Button.button.w)) && (y > Title_Button.button.y) && (y < (Title_Button.button.y + Title_Button.button.h)))
                {
                    set_next_state(GAME);
                }
            }
        }
    }
}

void Title::logic()
{

}

void Title::render()
{
    apply_surface(Title_Button.button.x, Title_Button.button.y, Title_Button.button_sprite, screen, clip);
    apply_surface((SCREEN_WIDTH - Title_Message->w) / 2, 100, Title_Message, screen);
}

The problem here is that the events/logic/render functions have no clue that Title_Message exists when I put it in the void Title::Title() constructor. But when I put it in the class definition, I can't pass an argument through it.

도움이 되었습니까?

해결책

The values should be initialized in the constructor definiton: not in the class definition.

class Game : public GameState
{
private:
    int server;
    TTF_Font *score;
    Paddle PlayerOne;
    Paddle Playertwo;
    Ball ball;  // same class name and variable name won't work
public:
    void events();
    void logic();
    void render();
    Game();
    ~Game();
};
...
Game::Game()
:   score(NULL)
,   PlayerOne(1)
,   PlayerTwo(2)
,   ball(2)
{
...
}

EDIT: For the Title message stuff

class Title : public GameState
{
private:
    SDL_Surface *Title_Message = NULL;
    SDL_Rect *clip;
    // THIS IS WHERE I HAVE TO PLACE THIS LINE 
    Button Title_Button;
    Button Title_Message;
public:
    void events();
    void logic();
    void render();
    Title();
    ~Title();
};

Title::Title()
{
    //text/sprites
    Title_Message = TTF_RenderText_Solid(font, "PONG", color);
    Title_Button.button_sprite = load_image("Start.png");

다른 팁

You can't do that outside of a method. Do that in the constructor

class Game : public GameState
{
    private:
      int server;
      TTF_Font *score;
      Paddle PlayerOne(1);
      Paddle Playertwo(2);
      Ball ballObject(2);
    public:
      void events();
      void logic();
      void render();
      Game(): PlayerOne(1), Playertwo(2), ballObject(2){};
      ~Game();

};

Edit : An answer has already been posted, I apologize for posting the same answer. I am new at using the interface. So it took time to figure out the code block generation.

Edit 2: Repsonding to your edit. You have to declare the object in the class itself. It's just you can't instantiate it in the declaration. You need to study about how c++ classes and classes in general work.

class class1
{
     private:
        class class2Obj(args);
     public:
        class1();
        ~class1();
}

The above example is wrong. To make this work you should do it like this

class class1
{
     private:
        class2 class2Obj;
     public:
        class1();
        ~class1();
}

 class1::class1()
 {
     class2Obj(args);
 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top