not a class?

Hello, i'm trying to build a partial program i wrote.

Error: request for member 'Move' in 'obj_bat', which is of non-class type 'cls_bat()'

How can I get rid of it?

There are probably loads of other errors, but i'm focusing on this one for now.

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

//forward declarations
class cls_bat;


//Main program

int main()
{
    // Load the sprite image from a file
    sf::Image Image;
    if (!Image.LoadFromFile("sprite.tga"))
        return EXIT_FAILURE; // check if loading is successful, if not, abort

    cls_bat obj_bat();


    // Create the main rendering window
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Breaker Balls");

    // Start game loop
        while (App.IsOpened())
        {
            sf::Event Event;
            while (App.GetEvent(Event))
            {
                // Window closed
                if (Event.Type == sf::Event::Closed)
                    App.Close();

                // Escape key pressed
                if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
                    App.Close();

                // Mouse moved
                if (Event.Type == sf::Event::MouseMoved)
                    obj_bat.Move(Event.MouseMove.X); //Move the bat

            }

            //draw everything
            obj_bat.draw();
        }



        // Clear the screen (fill it with black color)
        App.Clear();

        // Display window contents on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}


classes.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
////////////////////////////////////////////////////////////////////////////
// bat class
////////////////////////////////////////////////////////////////////////////
class cls_bat
{
    public

    float x = 200;
    int y = 512
    int width = 256;

    //Initialise the bat
    void cls_bat()
    {
    // Create the sprite
    sf::Sprite Sprite(Image);

    // Change its properties
    Sprite.SetColor(sf::Color(255, 255, 255, 255));

    Sprite.SetScale(1, 1);
    }

    //Move the bat upon mouse movement
    void Move(float mouse_x)
    {
        x = mouse_x;
    }

    //Draw the bat
    void draw()
    {
    Sprite.SetPosition(x,y);
    }
}
Make classes.cpp a header instead ( so it becomes classes.h ), add #include "classes.h" in Main.cpp and delete the forward declaration. See if it works.

Also, App.Clear() and App.Display() should be in the game loop if you want continuous movement, as the screen needs to be cleared and displayed several times every second. Right now what you are doing is that you get the MouseX when the App opens and draw the bat there, but without displaying anything. Notice that App.Clear() and App.Display() are not in the game loop, so they will never be executed, since the App will be closed when you get to that part of the code.
Here's how a game loop should work:
1
2
3
4
5
6
7
8
9
10
11
12
13
While (app.IsOpened() )
{
    Clear();

    Get Input();
    
    Process Input ();
    
    Draw Objects ();

    Display();
        
}


What happens is that every second, the game executes these operations many times, but the application appears fluent because we cannot see more than about 20 frames per second. That's why games look bad with low FPS, you can actually notice the objects being drawn.
Also, it is better to have variables in a class as private, and write a method if you want to operate with them.
Last edited on
@cristi121.AnswerToTopic.VeryUseful = true

I've moved the classes.cpp code to the classes.h file (see below) and included it.

All errors are gone except for this one:

classes.h|7|error: expected unqualified-id before ')' token.

How can i also get rid of this one?

classes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifndef CLASSES_H
#define CLASSES_H

////////////////////////////////////////////////////////////////////////////
// bat class
////////////////////////////////////////////////////////////////////////////
class cls_bat()
{
    public:

    float x = 200;
    int y = 512
    int width = 256;

    //Initialise the bat
    void cls_bat()
    {
    // Create the sprite
    sf::Sprite Sprite(Image);

    // Change its properties
    Sprite.SetColor(sf::Color(255, 255, 255, 255));

    Sprite.SetScale(1, 1);
    }

    //Move the bat upon mouse movement
    void Move(float mouse_x)
    {
        x = mouse_x;
    }

    //Draw the bat
    void draw()
    {
    Sprite.SetPosition(x,y);
    }
}

#endif // CLASSES_H 
Last edited on
That is usually a syntax error, could you point out on which line it appears?

Also, you're not allowed to initialize variables inside the class ( do it inside the contructor ), and you shouldn't put paranthesis after declaring a class ( class cls_bat instead of class cls_bat() ).

Here, I've rewritten your class and explained why:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
////////////////////////////////////////////////////////////////////////////
// bat class
////////////////////////////////////////////////////////////////////////////
class cls_bat
{
    public:

            cls_bat();   // The constructor has no type

            void init(sf::RenderWindow *newApp);

            void Move(float mouse_x) ;

            void draw();


    private:       // Keep things other classes shouln't touch private

            float x;   // You're not allowed to initialize here
            int y;
            int width ;
            sf::Sprite Sprite;
            sf::Image Image;
            sf::RenderWindow *app;
}



void cls_bat::cls_bat() // This is the constructor
                        // When you define a class method outside of the class
                        // This is the syntax:
                        // *function type* *class to which function belongs* :: *function_name*
                        // The constructor is called whenever you create a new instance of a class
{
    Image.LoadFromFile ("YourImageHere.png");

    Sprite.SetImage (Image);

    Sprite.SetColor(sf::Color(255, 255, 255, 255));  // Why do you do this?

    Sprite.SetScale(1, 1);      // No need for this, as SetScale (1, 1) doesn't do anything, obviously

    x = 200;
    y = 512
    width = 256;      // What is this supposed to be?
}


void cls_bat::init (sf::RenderWindow *newApp)
{
    // Get a pointer to the window you want to draw in

    app = newApp; // now app points to the same thing newApp points, and that should be your RenderWindow
                  // When you call this function, you should call it like this:
                  // yourBat.init ( &app); - the reference is so that you pass an adress to a RenderWindow
                  // A reference is to a pointer just like 5 is to int value and that is:
                  // A pointer stores an adress, whereas a reference is an actual adress
}


void cls_bat::Move(float mouse_x)
{
    x = mouse_x;
}


void draw()
{
    Sprite.SetPosition(x,y);     // This just sets the position, it doesn't draw it;
                                             // The Sprite class has private variables x and y
                                             // And this is how you modify them

    app->Draw (Sprite)           // And this puts Sprite in the list of stuff to show 
                                             // When you call app.Display();   
}
        


I haven't compiled this, so I don't actually know if it works, but it shows the basic ideas you should keep in mind.

By the way, you made another mistake in your class. You declared the Sprite inside a function. This is no good, because the scope of the Sprite will be the function, and as soon as the function ends, the Sprite is destroyed. You should declare everything you want to use several times inside the class as a private variable.
Last edited on
It now tells me this error again:
main.cpp|line 23|error: request for member 'init' in 'obj_bat', which is of non-class type 'cls_bat()'|


here's a slightly modified (syntax errors etc...) version of your classes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

#ifndef CLASSES_H
#define CLASSES_H

////////////////////////////////////////////////////////////////////////////
// bat class
////////////////////////////////////////////////////////////////////////////
class cls_bat
{
    public:

            cls_bat();   // The constructor has no type

            void init(sf::RenderWindow *newApp);

            void Move(float mouse_x) ;

            void draw();


    private:       // Keep things other classes shouln't touch private

            float x;   // You're not allowed to initialize here
            int y;
            int width ;
            sf::Sprite Sprite;
            sf::Image Image;
            sf::RenderWindow *app;
};



cls_bat::cls_bat() // This is the constructor
                        // When you define a class method outside of the class
                        // This is the syntax:
                        // *function type* *class to which function belongs* :: *function_name*
                        // The constructor is called whenever you create a new instance of a class
{
    Image.LoadFromFile ("YourImageHere.png");

    Sprite.SetImage (Image);

    Sprite.SetScale(1, 1);      // No need for this, as SetScale (1, 1) doesn't do anything, obviously

    x = 200;
    y = 512;
    width = 256;      // The bat can be resized
}


void cls_bat::init (sf::RenderWindow *newApp)
{
    // Get a pointer to the window you want to draw in

    app = newApp; // now app points to the same thing newApp points, and that should be your RenderWindow
                  // When you call this function, you should call it like this:
                  // yourBat.init ( &app); - the reference is so that you pass an adress to a RenderWindow
                  // A reference is to a pointer just like 5 is to int value and that is:
                  // A pointer stores an adress, whereas a reference is an actual adress
}


void cls_bat::Move(float mouse_x)
{
    x = mouse_x;
}


void cls_bat::draw()
{
    Sprite.SetPosition(x,y);     // This just sets the position, it doesn't draw it;
                                             // The Sprite class has private variables x and y
                                             // And this is how you modify them

    app->Draw (Sprite);           // And this puts Sprite in the list of stuff to show
                                             // When you call app.Display();
}

#endif // CLASSES_H 


the current main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//Headers

#include <iostream>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "classes.h"

//Main program

int main()
{
    // Create the main rendering window
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Breaker Balls");

    // Load the sprite image from a file
    sf::Image Image;
    if (!Image.LoadFromFile("sprite.tga"))
        return EXIT_FAILURE; // check if loading is successful, if not, abort

    cls_bat obj_bat(); //make an instance of cls_bat

    obj_bat.init(&App); //initialise it

    // Start game loop
        while (App.IsOpened())
        {
            sf::Event Event;
            while (App.GetEvent(Event))
            {
                // Window closed
                if (Event.Type == sf::Event::Closed)
                    App.Close();

                // Escape key pressed
                if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
                    App.Close();

                // Mouse moved
                if (Event.Type == sf::Event::MouseMoved)
                    obj_bat.Move(Event.MouseMove.X); //Move the bat

            }

            // Clear the screen (fill it with black color)
            App.Clear();

            // Display window contents on screen
            App.Display();

            //draw everything
            obj_bat.draw();
        }

    }

    return EXIT_SUCCESS;
}
Last edited on
cls_bat obj_bat(); //make an instance of cls_bat

This is a very common mistake.
The () cannot be used when making an object using the default constructor, becasue
the () make it look like a function declaration .

So what you have wriiten is a function declaration called obj_bat that take no parameters and
returns an object of type cls_bat.

You should just write:
cls_bat obj_bat; //create an instance of cls_bat using default constructor.
Ah, my program finally compiles! And it does what it's upposed to do!

Thanks a lot!
Topic archived. No new replies allowed.