Public Group

# Problem with inheritance in SDL class

This topic is 3931 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi. I've created and SDL application that creates an object which moves around in a circle. I'm making use of inheritance and am now trying to get the object to fire a bullet. I've used the Entity class shown below as the base class for the player and the bullet.
//Entity header file

class Entity
{
public:

int create(SDL_Surface* dest);
int setSize(int);
Uint8 setColour(Uint8, Uint8, Uint8, Uint8);
int setPosition(int,int);
int getPosition();

protected:

float angle;

private:

int size;
Uint8 r,g,b,a;

};

//Entity implementation file entity.cpp
int Entity::create(SDL_Surface* dest)
{
filledCircleRGBA( dest,  xPos,  yPos,  size, r, g, b, a);
}

int Entity::setPosition(int centreX,int centreY)
{

}

int Entity::getPosition()
{
return xPos;
return yPos;
}

{
}

int Entity::setSize(int _size)
{
size = _size;
}

Uint8 Entity::setColour(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a)
{
r=_r;
g=_g;
b=_b;
a=_a;
}

Below is the Bullet header & implementation files

class Bullet : public Entity
{
public:
void move();

};

//Implementation file
void Bullet::move()
{

}

This is how i've tried to implement it in main()
if(bulletCreated == true)
{
bullet.setSize(2);
bullet.setColour(10,150,50,255);
bullet.setPosition(centreX,centreY)==player.setPosition(centreX,centreY);
bullet.getPosition()==player.getPosition();
bullet.create(screen);
bullet.move();

}

centreX, centreY and rad are global variables. rad has been set using the setRadius function. I've used spacebar to indicate bulletCreated=true. The player moves whenever i press left or right. I've tried a few variations but can't seem to get the bullet to fire from the position that the player is in. Every time i hit spacebar the bullet just fires from the initial starting position of the player. How can i get it to fire from wherever the player's position is? Thanks [Edited by - recon6 on October 13, 2007 4:11:00 PM]

##### Share on other sites
Please use the edit button in the top right corner of your post to edit your message and give it a title.

Thanks!

##### Share on other sites
You have several errors in your source, it should compile, let alone run.

Here is the source I used to compile (the same, just with dummy variable declarations):
int centreX, centreY, rad;class Entity{    public:        int create(SDL_Surface* dest);        int setSize(int);        int setRadius(int);        Uint8 setColour(Uint8, Uint8, Uint8, Uint8);        int setPosition(int,int);        int getPosition();    protected:        float angle;        int xPos, yPos,rad;    private:        int size;        Uint8 r,g,b,a;};//Entity implementation file entity.cppint Entity::create(SDL_Surface* dest){    //filledCircleRGBA( dest,  xPos,  yPos,  size, r, g, b, a);}int Entity::setPosition(int centreX,int centreY){     xPos = rad*cos(angle) + centreX;     yPos = rad*sin(angle) + centreY;}int Entity::getPosition(){    return xPos;    return yPos;}int Entity::setRadius(int _rad){    rad = _rad;}int Entity::setSize(int _size){    size = _size;}Uint8 Entity::setColour(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a){    r=_r;    g=_g;    b=_b;    a=_a;}//Header fileclass Bullet : public Entity{    public:        void move();};//Implementation filevoid Bullet::move(){    rad-=2;}void foo(){    // dummy variables so code compiles    bool bulletCreated = true;    Bullet bullet;    SDL_Surface *screen = 0;    Entity player;    if(bulletCreated == true)    {        bullet.setSize(2);        bullet.setColour(10,150,50,255);        bullet.setPosition(centreX,centreY)=player.setPosition(centreX,centreY);        bullet.getPosition()=player.getPosition();        bullet.create(screen);        bullet.move();    }}

Here are the errors GCC gave me at a reasonably high warning level:
main_sdl.cpp: In member function int Entity::create(SDL_Surface*)':main_sdl.cpp:47: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setPosition(int, int)':main_sdl.cpp:52: warning: converting to int' from double'main_sdl.cpp:53: warning: converting to int' from double'main_sdl.cpp:54: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setRadius(int)':main_sdl.cpp:66: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setSize(int)':main_sdl.cpp:73: warning: control reaches end of non-void functionmain_sdl.cpp: In member function Uint8 Entity::setColour(Uint8, Uint8, Uint8, Uint8)':main_sdl.cpp:81: warning: control reaches end of non-void functionmain_sdl.cpp: In function void foo()':main_sdl.cpp:108: error: non-lvalue in assignmentmain_sdl.cpp:109: error: non-lvalue in assignment

##### Share on other sites
My code does run,it doesn't give any errors at all. The problem is i don't know how to get the bullet to fire from the position that the player is in.

Here is the code to move the player:

//H fileclass Player : public Entity{ public: void moveLeft(); void moveRight(); };//Player.cpp filevoid Player::moveLeft(){ angle +=0.01;}void Player::moveRight(){ angle -=0.01;}//Implementation in main() Player player; player.setSize(10); player.setColour(100,50,100,255); player.setPosition(centreX,centreY); player.getPosition(); player.create(screen); 
 0 
 Share this post Link to post Share on other sites 
 
 
 darookie    1441 darookie Member 1441 Posted October 13, 2007 Quote:Original post by recon6My code does run,it doesn't give any errors at all.Set your compiler to treat warnings as errors and try to compile. You'll be surprised...Seriously, a lot of your code is not only wrong (though the compiler will onlywarn), but also doesn't make sense.Just a few examples:// why does the method return an int?int Entity::setPosition(int centreX,int centreY){ xPos = rad*cos(angle) + centreX; yPos = rad*sin(angle) + centreY; // you fail to return an "int" here}// you return a *single* int value hereint Entity::getPosition(){ return xPos; // unreachable statement - the return above will cause the method to leave return yPos;}// in C++ a simple solution for the problem above is to separate the method// into two methods:// return xPos. he const only hints the compiler that the method does// not modify any class membersint Entity::getPositionX() const{ return xPos;}// same as above for yPosint Entity::getPositionY(){ return yPos;} // now what is that supposed to mean? bullet.setPosition(centreX,centreY)==player.setPosition(centreX,centreY); bullet.getPosition()==player.getPosition(); // correction: bullet.setPosition(player.getPositionX(), player.getPositionY());I hope this is enough to get you started with fixing your code. Please have another look at your favourite C++ book, too. 0 Share this post Link to post Share on other sites recon6    112 recon6 Member 112 Posted October 13, 2007 Thanks.I've corrected the errors.But i still can't wrap my head around as to how i can get the bullet firing from the players position.I've made this correction:bullet.setPosition(player.getPositionX(), player.getPositionY());Now, when you press space, the bullet starts at the extreme right of the screen and moves from right to left. The bullet also moves about when i press the left and right keys. How can i fix the angle at which it's fired from and just decrease the radius?I don't know how else to go about getting the bullet to fire. 0 Share this post Link to post Share on other sites Zahlman    1682 Zahlman GDNet Emeritus 1682 Posted October 13, 2007 A class is not simply some storage space for code and related data. It represents a data type. Except, of course, for containers - but the standard library already provides all the kinds of containers you're likely to need.Consequently, it doesn't make sense to think in terms of instantiating one Bullet somewhere and a separate "bullet created" flag, because as soon as you instantiate the Bullet, it IS created.What you want to do is store Bullets in a container, and when you update, draw "each bullet in the container". A std::vector is appropriate for this.Consequently, you want the bullet to be "valid" for its entire lifetime. In C++, we use constructors to construct objects - i.e., set the initial values of all data. We don't set things one piece at a time. So in general, writing a bunch of accessor/mutator pairs like that is a big red warning flag, because it provides an interface for treating the class like a storage space for data, instead of the new data type that it's supposed to be.What we are trying to do is to "encapsulate" the data, which is why we make things 'private'. When you write an accessor and also a mutator for the same data, and neither do any checks, your code is lying to you about this data being encapsulated. It is not.So, what do we do?First off, we can organize related components of the data into other classes or structs. In many of these cases, there's no need for encapsulation, but the added struct-wrapping is a powerful way to indicate "these values are related", and it also lets you simplify your function interfaces (for example, instead of taking a bunch of arguments to represent a colour, you just take a Colour object).Next, we give the class a constructor which replaces the work of the mutators. After all, a Bullet's colour isn't going to change while in mid-air, right? So, we can set it at the beginning, and forget about it. We also don't need to "set" its position; that's made redundant by the ability to "move".Then, we make the behaviour of functions match their names. Another word for behaviour is functionality, oddly enough :) For example, that "creation" function doesn't really create a bullet (that's what a constructor does); it draws the bullet. So, we should name it that way - i.e. draw().Similarly, When a bullet "move"s, what changes? Its radius? No, its position. So, we update the bullet's postion in there, according to its speed. Hold on - it doesn't have a speed? Oh, we need to think more about how we model the object, then. The Entity setPosition allows for - oh, I get it now; 'rad' is not an object radius but a turning radius. That's another point: use meaningful names; it doesn't cost you anything to lengthen them except your own typing effort, because they "don't exist" in the compiled version.Anyway, bullets don't turn about some circle while they move, do they? So, that stuff doesn't belong in the Entity class, because it isn't stuff that makes sense for every Entity.That follows from the Liskov substitution principle (google it). What we want is to make sure that a derived object (Bullet) could be used anywhere a base object (Entity) could. Consequently, the Entity should not "be able to do" things that a Bullet can't.So, we take the angle and turning radius out of the Entity, and move it to the Player (which is the thing that can move in a circle) and give the Bullet additionally a 'velocity'.Finally, we can clean up that accessor, by thinking about responsibility. You must be wondering how we're going to construct a Bullet, since we have to set its starting location in the constructor... we want to use the player's location, and now I'm telling you you can't "ask" the player for its location? Yep, that's right. Because we aren't going to construct the Bullet - the player is. After all, if you were describing what happens in natural language, you wouldn't say that a bullet comes into existence at the player's location - you'd say the player fires a bullet. So that's exactly what we'll do.I'll write only the declarations; if you've been following the discussion, you should be able to implement the classes and make use of them.// First, some structures for wrapping up related data together.// For now, we will let these be containers, since they don't have obvious// functionality of their own.struct Position { int x, y; };struct Velocity { int dx, dy; };// Yes, it's basically the same structure - right now - but there are benefits// to this kind of duplication: we get more type information. We know that // adding Position + Velocity or Velocity + Position or Velocity + Velocity // makes sense, but Position + Position doesn't. That helps us avoid logical // errors when we write the code, by looking at the data types. Later, we'll // use better techniques, but I don't want to show too much at once.struct Colour { Uint8 r, g, b, a; };// Now, our classes look like:class Entity { public: void draw(SDL_Surface* dest); // I *will* implement the constructor, because the above discussion doesn't // explain enough about what to do... Entity(const Position& p, int size, const Colour& colour) : position(p), size(size), colour(colour) {} protected: Position position; private: int size; Colour colour;};class Player : public Entity { public: // We'll need to "forward" the constructor - i.e. explain how to construct the // "entity part of" a Player for a given Player object. Player(const Position& p, int size, const Colour& colour, int radius, int angle): Entity(p, size, colour), turning_radius(radius), angle(angle) {} // The Player's position will change iteratively (i.e. once per game loop) // just as any Bullet's position does. void move(); // Think *carefully* about how you are going to implement move() for this // class. You can't *just* add the vector specified by the turning radius // and angle, because that just gives a straight line motion in that // direction. You'll want to *change* the angle over time, and also... well, // I'll give you some room for trial and error :) // Also, the player needs to be able to fire a bullet: Bullet fire(); // Think about how you are going to decide what you pass to the Bullet // constructor. You have access to the needed position (i.e. the current // position of 'this' object). Size and colour will presumably always be some // constant "bullet" values. What about the velocity? private: int turning_radius; float angle;};class Bullet : public Entity { public: // This should look familiar... Player(const Position& p, int size, const Colour& colour, const Velocity& v): Entity(p, size, colour), velocity(v) {} void move(); // This version of move() should be a lot easier to implement: just "add" the // velocity to the position. private: Velocity velocity;};// Above, I said:// Think about how you are going to decide what you pass to the Bullet// constructor.... Size and colour will presumably always be some// constant "bullet" values.// Think MORE about that. Do we *need* to specify a size and colour when we make// the Bullet? Why not just let the Bullet specify them? We can pass a constant// value in the initializer list; it doesn't have to come from a constructor// parameter. Similarly for the player.// Our main code will do someting like this:#include <vector>#include <algorithm>int main() { std::vector<Bullet> bullets; Player p(/* args */); // If the player wants to fire a bullet, we add it to the bullets like this: bullets.push_back(p.fire()); // We update the player's position like this: p.move(); // We update all the bullet positions like this: std::for_each(bullets.begin(), bullets.end(), std::mem_fun_ref(&Bullet::move)); // We draw the player like this: p.draw(); // We draw all the bullets like this: std::for_each(bullets.begin(), bullets.end(), std::mem_fun_ref(&Bullet::draw)); // We DON'T mess around with the bullet's internal data each time around in // order to "move" it. We certainly don't re-set its colour to the same thing // every time ;)} 0 Share this post Link to post Share on other sites recon6    112 recon6 Member 112 Posted October 13, 2007 Thanks a lot, much appreciated.I'll give it a shot. 0 Share this post Link to post Share on other sites Chad Smith    1344 Chad Smith Member 1344 Posted October 13, 2007 Quote:Original post by ZahlmanA class is not simply some storage space for code and related data. It represents a data type. Except, of course, for containers - but the standard library already provides all the kinds of containers you're likely to need.Consequently, it doesn't make sense to think in terms of instantiating one Bullet somewhere and a separate "bullet created" flag, because as soon as you instantiate the Bullet, it IS created.What you want to do is store Bullets in a container, and when you update, draw "each bullet in the container". A std::vector is appropriate for this.Consequently, you want the bullet to be "valid" for its entire lifetime. In C++, we use constructors to construct objects - i.e., set the initial values of all data. We don't set things one piece at a time. So in general, writing a bunch of accessor/mutator pairs like that is a big red warning flag, because it provides an interface for treating the class like a storage space for data, instead of the new data type that it's supposed to be.What we are trying to do is to "encapsulate" the data, which is why we make things 'private'. When you write an accessor and also a mutator for the same data, and neither do any checks, your code is lying to you about this data being encapsulated. It is not.So, what do we do?First off, we can organize related components of the data into other classes or structs. In many of these cases, there's no need for encapsulation, but the added struct-wrapping is a powerful way to indicate "these values are related", and it also lets you simplify your function interfaces (for example, instead of taking a bunch of arguments to represent a colour, you just take a Colour object).Next, we give the class a constructor which replaces the work of the mutators. After all, a Bullet's colour isn't going to change while in mid-air, right? So, we can set it at the beginning, and forget about it. We also don't need to "set" its position; that's made redundant by the ability to "move".Then, we make the behaviour of functions match their names. Another word for behaviour is functionality, oddly enough :) For example, that "creation" function doesn't really create a bullet (that's what a constructor does); it draws the bullet. So, we should name it that way - i.e. draw().Similarly, When a bullet "move"s, what changes? Its radius? No, its position. So, we update the bullet's postion in there, according to its speed. Hold on - it doesn't have a speed? Oh, we need to think more about how we model the object, then. The Entity setPosition allows for - oh, I get it now; 'rad' is not an object radius but a turning radius. That's another point: use meaningful names; it doesn't cost you anything to lengthen them except your own typing effort, because they "don't exist" in the compiled version.Anyway, bullets don't turn about some circle while they move, do they? So, that stuff doesn't belong in the Entity class, because it isn't stuff that makes sense for every Entity.That follows from the Liskov substitution principle (google it). What we want is to make sure that a derived object (Bullet) could be used anywhere a base object (Entity) could. Consequently, the Entity should not "be able to do" things that a Bullet can't.So, we take the angle and turning radius out of the Entity, and move it to the Player (which is the thing that can move in a circle) and give the Bullet additionally a 'velocity'.Finally, we can clean up that accessor, by thinking about responsibility. You must be wondering how we're going to construct a Bullet, since we have to set its starting location in the constructor... we want to use the player's location, and now I'm telling you you can't "ask" the player for its location? Yep, that's right. Because we aren't going to construct the Bullet - the player is. After all, if you were describing what happens in natural language, you wouldn't say that a bullet comes into existence at the player's location - you'd say the player fires a bullet. So that's exactly what we'll do.I'll write only the declarations; if you've been following the discussion, you should be able to implement the classes and make use of them.*** Source Snippet Removed ***Wow...yet another very nice post from you. Simply amazing. 0 Share this post Link to post Share on other sites cNoob    295 cNoob Member 295 Posted October 13, 2007 Quote:Original post by Chad SmithWow...yet another very nice post from you. Simply amazing.Agreed, Great post Zahlman. 0 Share this post Link to post Share on other sites 
 Sign in to follow this   Followers 0 
 Go To Topic Listing Forum 
 Advertisement 
 Advertisement Popular Tags 2D 3D Advice Algorithm Animation C# C++ Character Design DX11 Education GameMaker Gameplay General HTML5 Javascript Learning Marketing Mobile Music OpenGL Optimization PC Unity Unreal Popular Contributors Week Month Year All Time 1 Rutin 24 2 Hodgman 21 3 JoeJ 20 4 Scouting Ninja 17 5 lawnjelly 14 Show More Advertisement Popular Now 9 Hard sell and coercive tactics from Unity By jbadamsStarted 23 hours ago 46 C++ Where can I find the source code for "Programming a Multiplayer FPS in DirectX"? By rjhwinner03Started Monday at 12:52 PM 41 How to react when people say my game looks like shit? By EddieKStarted Sunday at 04:30 PM 23 Combine 2 Physics objects By CacksStarted Saturday at 02:35 PM 13 C++ Simple trig problem driving me crazy By Guy Leonard ThomasStarted Friday at 08:46 PM Forum Statistics Total Topics 631749 Total Posts 3002040 GameDev.net GameDev.net Articles GameDev.net Event Coverage GameDev.net Forums GameDev.net Blogs GameDev.net Gallery GameDev.net News GameDev.net Projects GDNet Chat All Activity Search In Everywhere This Forum This Topic More options... Find results that contain... All of my search term words Any of my search term words Find results in... Content titles and body Content titles only Home Groups For Beginners Forum Problem with inheritance in SDL class 
 
 
 × Existing user? Sign In Sign Up Browse Back Articles & Tutorials Back All Categories Audio Business Game Design Industry Programming Visual Arts Columns Back GameDev Unboxed Event Coverage Back All Events Game Developers Conference Power Up Digital Games Conference GameDev.Market Links News Podcasts Back All Podcasts Game Dev Loadout Archive Community Back Beginners Back Beginners Group Beginners Forum Beginners Resources Blogs Calendar Chat Forums Back All Forums Audio Business Game Design Programming Visual Arts Community GameDev Challenges Affiliates Topical Workshops Gallery Groups Back For Beginners GameDev Challenges All Groups Projects Back All Projects Games Game Assets Game Mods Developer Tools Store Careers Back Contractors Hobby Projects Game Jobs Back Browse on GameDev.Jobs Post a Job Members Back Chat GDNet+ Membership Guidelines Leaderboard Online Users Awards Search Back All Activity My Activity Streams Back Latest Topics Featured Blogs Search var ipsDebug=false;var CKEDITOR_BASEPATH='//www.gamedev.net/applications/core/interface/ckeditor/ckeditor/';var ipsSettings={cookie_path:"/",cookie_prefix:"ips4_",cookie_ssl:true,upload_imgURL:"",message_imgURL:"",notification_imgURL:"",baseURL:"//www.gamedev.net/",jsURL:"//www.gamedev.net/applications/core/interface/js/js.php",csrfKey:"e3c14e0ea339d28a952fd62bb4e51d52",antiCache:"2a361a8a02",disableNotificationSounds:false,useCompiledFiles:true,links_external:true,memberID:0,analyticsProvider:"ga",viewProfiles:true,mapProvider:'google',mapApiKey:"AIzaSyAeT7tk3vnWWmbgVISkLpbhkQvekG19rHM",}; ips.setSetting('date_format',jQuery.parseJSON('"mm\/dd\/yy"'));ips.setSetting('date_first_day',jQuery.parseJSON('0'));ips.setSetting('remote_image_proxy',jQuery.parseJSON('1'));ips.setSetting('ipb_url_filter_option',jQuery.parseJSON('"none"'));ips.setSetting('url_filter_any_action',jQuery.parseJSON('"allow"'));ips.setSetting('bypass_profanity',jQuery.parseJSON('0'));ips.setSetting('emoji_style',jQuery.parseJSON('"native"'));ips.setSetting('emoji_shortcodes',jQuery.parseJSON('"1"'));ips.setSetting('emoji_ascii',jQuery.parseJSON('"1"'));ips.setSetting('emoji_cache',jQuery.parseJSON('"1"'));ips.setSetting('quickSearchDefault',jQuery.parseJSON('"all"'));ips.setSetting('quickSearchMinimum',jQuery.parseJSON('3'));ips.setSetting('quickSearchShowAdv',jQuery.parseJSON('true'));ips.setSetting('quickSearchIn',jQuery.parseJSON('"title"')); { "@context": "http://schema.org", "@type": "DiscussionForumPosting", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/", "discussionUrl": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/", "name": "Problem with inheritance in SDL class", "headline": "Problem with inheritance in SDL class", "text": "Hi. I\u0027ve created and SDL application that creates an object which moves around in a circle. I\u0027m making use of inheritance and am now trying to get the object to fire a bullet.\n\nI\u0027ve used the Entity class shown below as the base class for the player and the bullet.\n\n\n\n//Entity header file\n\nclass Entity\n{\n public:\n\n int create(SDL_Surface* dest);\n int setSize(int);\n int setRadius(int);\n Uint8 setColour(Uint8, Uint8, Uint8, Uint8);\n int setPosition(int,int);\n int getPosition();\n\n\n protected:\n\n float angle;\n int xPos, yPos,rad;\n\n\n private:\n\n int size;\n Uint8 r,g,b,a;\n\n\n};\n\n//Entity implementation file entity.cpp\nint Entity::create(SDL_Surface* dest)\n{\n filledCircleRGBA( dest, xPos, yPos, size, r, g, b, a);\n}\n\nint Entity::setPosition(int centreX,int centreY)\n{\n\n xPos = rad*cos(angle) + centreX;\n yPos = rad*sin(angle) + centreY;\n}\n\n\nint Entity::getPosition()\n{\n return xPos;\n return yPos;\n}\n\nint Entity::setRadius(int _rad)\n{\n rad = _rad;\n}\n\n\n\nint Entity::setSize(int _size)\n{\n size = _size;\n}\n\nUint8 Entity::setColour(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a)\n{\n r=_r;\n g=_g;\n b=_b;\n a=_a;\n}\n\n\nBelow is the Bullet header \u0026amp; implementation files\n\n\n\n//Header file\nclass Bullet : public Entity\n{\n public:\n void move();\n\n};\n\n//Implementation file\nvoid Bullet::move()\n{\n\n rad-=2;\n}\n\n\nThis is how i\u0027ve tried to implement it in main()\n\n\nif(bulletCreated == true)\n {\n bullet.setSize(2);\n bullet.setColour(10,150,50,255);\n bullet.setPosition(centreX,centreY)==player.setPosition(centreX,centreY);\n bullet.getPosition()==player.getPosition();\n bullet.create(screen);\n bullet.move();\n\n }\n\n\ncentreX, centreY and rad are global variables. rad has been set using the setRadius function. I\u0027ve used spacebar to indicate bulletCreated=true. The player moves whenever i press left or right.\n\nI\u0027ve tried a few variations but can\u0027t seem to get the bullet to fire from the position that the player is in. Every time i hit spacebar the bullet just fires from the initial starting position of the player. How can i get it to fire from wherever the player\u0027s position is?\n\nThanks\n\n[Edited by - recon6 on October 13, 2007 4:11:00 PM]\n", "dateCreated": "2007-10-13T10:13:33+0000", "datePublished": "2007-10-13T10:13:33+0000", "pageStart": 1, "pageEnd": 1, "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "author": { "@type": "Person", "name": "recon6", "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "url": "https://www.gamedev.net/profile/128857-recon6/" }, "interactionStatistic": [ { "@type": "InteractionCounter", "interactionType": "http://schema.org/ViewAction", "userInteractionCount": 1203 }, { "@type": "InteractionCounter", "interactionType": "http://schema.org/CommentAction", "userInteractionCount": 9 }, { "@type": "InteractionCounter", "interactionType": "http://schema.org/FollowAction", "userInteractionCount": 39 } ], "comment": [ { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=468260", "author": { "@type": "Person", "name": "recon6", "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "url": "https://www.gamedev.net/profile/128857-recon6/" }, "dateCreated": "2007-10-13T10:13:33+0000", "text": "Hi. I\u0027ve created and SDL application that creates an object which moves around in a circle. I\u0027m making use of inheritance and am now trying to get the object to fire a bullet.\n\nI\u0027ve used the Entity class shown below as the base class for the player and the bullet.\n\n\n\n//Entity header file\n\nclass Entity\n{\n public:\n\n int create(SDL_Surface* dest);\n int setSize(int);\n int setRadius(int);\n Uint8 setColour(Uint8, Uint8, Uint8, Uint8);\n int setPosition(int,int);\n int getPosition();\n\n\n protected:\n\n float angle;\n int xPos, yPos,rad;\n\n\n private:\n\n int size;\n Uint8 r,g,b,a;\n\n\n};\n\n//Entity implementation file entity.cpp\nint Entity::create(SDL_Surface* dest)\n{\n filledCircleRGBA( dest, xPos, yPos, size, r, g, b, a);\n}\n\nint Entity::setPosition(int centreX,int centreY)\n{\n\n xPos = rad*cos(angle) + centreX;\n yPos = rad*sin(angle) + centreY;\n}\n\n\nint Entity::getPosition()\n{\n return xPos;\n return yPos;\n}\n\nint Entity::setRadius(int _rad)\n{\n rad = _rad;\n}\n\n\n\nint Entity::setSize(int _size)\n{\n size = _size;\n}\n\nUint8 Entity::setColour(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a)\n{\n r=_r;\n g=_g;\n b=_b;\n a=_a;\n}\n\n\nBelow is the Bullet header \u0026amp; implementation files\n\n\n\n//Header file\nclass Bullet : public Entity\n{\n public:\n void move();\n\n};\n\n//Implementation file\nvoid Bullet::move()\n{\n\n rad-=2;\n}\n\n\nThis is how i\u0027ve tried to implement it in main()\n\n\nif(bulletCreated == true)\n {\n bullet.setSize(2);\n bullet.setColour(10,150,50,255);\n bullet.setPosition(centreX,centreY)==player.setPosition(centreX,centreY);\n bullet.getPosition()==player.getPosition();\n bullet.create(screen);\n bullet.move();\n\n }\n\n\ncentreX, centreY and rad are global variables. rad has been set using the setRadius function. I\u0027ve used spacebar to indicate bulletCreated=true. The player moves whenever i press left or right.\n\nI\u0027ve tried a few variations but can\u0027t seem to get the bullet to fire from the position that the player is in. Every time i hit spacebar the bullet just fires from the initial starting position of the player. How can i get it to fire from wherever the player\u0027s position is?\n\nThanks\n\n[Edited by - recon6 on October 13, 2007 4:11:00 PM]\n", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079605", "author": { "@type": "Person", "name": "JWalsh", "image": "https://www.gamedev.net/uploads/profile/photo-thumb-26952.png", "url": "https://www.gamedev.net/profile/26952-jwalsh/" }, "dateCreated": "2007-10-13T10:15:30+0000", "text": "Please use the edit button in the top right corner of your post to edit your message and give it a title.Thanks!", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079618", "author": { "@type": "Person", "name": "rip-off", "image": "https://www.gamedev.net/uploads/profile/photo-thumb-78572.jpg", "url": "https://www.gamedev.net/profile/78572-rip-off/" }, "dateCreated": "2007-10-13T10:43:58+0000", "text": "You have several errors in your source, it should compile, let alone run.Here is the source I used to compile (the same, just with dummy variable declarations):\nint centreX, centreY, rad;class Entity{public:int create(SDL_Surface* dest);int setSize(int);int setRadius(int); Uint8 setColour(Uint8, Uint8, Uint8, Uint8);int setPosition(int,int);int getPosition();protected:float angle;int xPos, yPos,rad;private:int size; Uint8 r,g,b,a;};//Entity implementation file entity.cppint Entity::create(SDL_Surface* dest){//filledCircleRGBA( dest, xPos, yPos, size, r, g, b, a);}int Entity::setPosition(int centreX,int centreY){ xPos = rad*cos(angle) + centreX; yPos = rad*sin(angle) + centreY;}int Entity::getPosition(){return xPos;return yPos;}int Entity::setRadius(int _rad){ rad = _rad;}int Entity::setSize(int _size){ size = _size;}Uint8 Entity::setColour(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a){ r=_r; g=_g; b=_b; a=_a;}//Header fileclass Bullet : public Entity{public:void move();};//Implementation filevoid Bullet::move(){ rad-=2;}void foo(){// dummy variables so code compilesbool bulletCreated = true; Bullet bullet; SDL_Surface *screen = 0; Entity player;if(bulletCreated == true) { bullet.setSize(2); bullet.setColour(10,150,50,255); bullet.setPosition(centreX,centreY)=player.setPosition(centreX,centreY); bullet.getPosition()=player.getPosition(); bullet.create(screen); bullet.move(); }}\nHere are the errors GCC gave me at a reasonably high warning level:main_sdl.cpp: In member function int Entity::create(SDL_Surface*)\u0027:main_sdl.cpp:47: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setPosition(int, int)\u0027:main_sdl.cpp:52: warning: converting to int\u0027 from double\u0027main_sdl.cpp:53: warning: converting to int\u0027 from double\u0027main_sdl.cpp:54: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setRadius(int)\u0027:main_sdl.cpp:66: warning: control reaches end of non-void functionmain_sdl.cpp: In member function int Entity::setSize(int)\u0027:main_sdl.cpp:73: warning: control reaches end of non-void functionmain_sdl.cpp: In member function Uint8 Entity::setColour(Uint8, Uint8, Uint8, Uint8)\u0027:main_sdl.cpp:81: warning: control reaches end of non-void functionmain_sdl.cpp: In function void foo()\u0027:main_sdl.cpp:108: error: non-lvalue in assignmentmain_sdl.cpp:109: error: non-lvalue in assignment\n", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079632", "author": { "@type": "Person", "name": "recon6", "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "url": "https://www.gamedev.net/profile/128857-recon6/" }, "dateCreated": "2007-10-13T11:07:00+0000", "text": "My code does run,it doesn\u0027t give any errors at all. The problem is i don\u0027t know how to get the bullet to fire from the position that the player is in.Here is the code to move the player://H fileclass Player : public Entity{ public: void moveLeft(); void moveRight();};//Player.cpp filevoid Player::moveLeft(){ angle +=0.01;}void Player::moveRight(){ angle -=0.01;}//Implementation in main() Player player; player.setSize(10); player.setColour(100,50,100,255); player.setPosition(centreX,centreY); player.getPosition(); player.create(screen);", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079656", "author": { "@type": "Person", "name": "darookie", "image": "https://www.gamedev.net/uploads/profile/photo-thumb-21386.jpg", "url": "https://www.gamedev.net/profile/21386-darookie/" }, "dateCreated": "2007-10-13T11:49:01+0000", "text": "Set your compiler to treat warnings as errors and try to compile. You\u0027ll be surprised...Seriously, a lot of your code is not only wrong (though the compiler will onlywarn), but also doesn\u0027t make sense.Just a few examples:// why does the method return an int?int Entity::setPosition(int centreX,int centreY){ xPos = rad*cos(angle) + centreX; yPos = rad*sin(angle) + centreY;// you fail to return an \"int\" here}\n// you return a *single* int value hereint Entity::getPosition(){return xPos;// unreachable statement - the return above will cause the method to leavereturn yPos;}// in C++ a simple solution for the problem above is to separate the method// into two methods:// return xPos. he const only hints the compiler that the method does// not modify any class membersint Entity::getPositionX() const{return xPos;}// same as above for yPosint Entity::getPositionY(){return yPos;}\n// now what is that supposed to mean? bullet.setPosition(centreX,centreY)==player.setPosition(centreX,centreY); bullet.getPosition()==player.getPosition();// correction: bullet.setPosition(player.getPositionX(), player.getPositionY());\nI hope this is enough to get you started with fixing your code. Please have another look at your favourite C++ book, too.\n", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079682", "author": { "@type": "Person", "name": "recon6", "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "url": "https://www.gamedev.net/profile/128857-recon6/" }, "dateCreated": "2007-10-13T12:32:19+0000", "text": "Thanks.I\u0027ve corrected the errors.But i still can\u0027t wrap my head around as to how i can get the bullet firing from the players position.I\u0027ve made this correction:bullet.setPosition(player.getPositionX(), player.getPositionY());Now, when you press space, the bullet starts at the extreme right of the screen and moves from right to left. The bullet also moves about when i press the left and right keys. How can i fix the angle at which it\u0027s fired from and just decrease the radius?I don\u0027t know how else to go about getting the bullet to fire.", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079758", "author": { "@type": "Person", "name": "Zahlman", "image": "https://secure.gravatar.com/avatar/44ea316b22132c4804bd6ecdca7e1278?d=https://www.gamedev.net/uploads/monthly_2017_08/Z.png.8080448ae4b95f1e392d4ec3616c7992.png", "url": "https://www.gamedev.net/profile/53889-zahlman/" }, "dateCreated": "2007-10-13T15:18:13+0000", "text": "A class is not simply some storage space for code and related data. It represents a data type. Except, of course, for containers - but the standard library already provides all the kinds of containers you\u0027re likely to need.Consequently, it doesn\u0027t make sense to think in terms of instantiating one Bullet somewhere and a separate \"bullet created\" flag, because as soon as you instantiate the Bullet, it IS created.What you want to do is store Bullets in a container, and when you update, draw \"each bullet in the container\". A std::vector is appropriate for this.Consequently, you want the bullet to be \"valid\" for its entire lifetime. In C++, we use constructors to construct objects - i.e., set the initial values of all data. We don\u0027t set things one piece at a time. So in general, writing a bunch of accessor/mutator pairs like that is a big red warning flag, because it provides an interface for treating the class like a storage space for data, instead of the new data type that it\u0027s supposed to be.What we are trying to do is to \"encapsulate\" the data, which is why we make things \u0027private\u0027. When you write an accessor and also a mutator for the same data, and neither do any checks, your code is lying to you about this data being encapsulated. It is not.So, what do we do?First off, we can organize related components of the data into other classes or structs. In many of these cases, there\u0027s no need for encapsulation, but the added struct-wrapping is a powerful way to indicate \"these values are related\", and it also lets you simplify your function interfaces (for example, instead of taking a bunch of arguments to represent a colour, you just take a Colour object).Next, we give the class a constructor which replaces the work of the mutators. After all, a Bullet\u0027s colour isn\u0027t going to change while in mid-air, right? So, we can set it at the beginning, and forget about it. We also don\u0027t need to \"set\" its position; that\u0027s made redundant by the ability to \"move\".Then, we make the behaviour of functions match their names. Another word for behaviour is functionality, oddly enough :) For example, that \"creation\" function doesn\u0027t really create a bullet (that\u0027s what a constructor does); it draws the bullet. So, we should name it that way - i.e. draw().Similarly, When a bullet \"move\"s, what changes? Its radius? No, its position. So, we update the bullet\u0027s postion in there, according to its speed. Hold on - it doesn\u0027t have a speed? Oh, we need to think more about how we model the object, then. The Entity setPosition allows for - oh, I get it now; \u0027rad\u0027 is not an object radius but a turning radius. That\u0027s another point: use meaningful names; it doesn\u0027t cost you anything to lengthen them except your own typing effort, because they \"don\u0027t exist\" in the compiled version.Anyway, bullets don\u0027t turn about some circle while they move, do they? So, that stuff doesn\u0027t belong in the Entity class, because it isn\u0027t stuff that makes sense for every Entity.That follows from the Liskov substitution principle (google it). What we want is to make sure that a derived object (Bullet) could be used anywhere a base object (Entity) could. Consequently, the Entity should not \"be able to do\" things that a Bullet can\u0027t.So, we take the angle and turning radius out of the Entity, and move it to the Player (which is the thing that can move in a circle) and give the Bullet additionally a \u0027velocity\u0027.Finally, we can clean up that accessor, by thinking about responsibility. You must be wondering how we\u0027re going to construct a Bullet, since we have to set its starting location in the constructor... we want to use the player\u0027s location, and now I\u0027m telling you you can\u0027t \"ask\" the player for its location? Yep, that\u0027s right. Because we aren\u0027t going to construct the Bullet - the player is. After all, if you were describing what happens in natural language, you wouldn\u0027t say that a bullet comes into existence at the player\u0027s location - you\u0027d say the player fires a bullet. So that\u0027s exactly what we\u0027ll do.I\u0027ll write only the declarations; if you\u0027ve been following the discussion, you should be able to implement the classes and make use of them.// First, some structures for wrapping up related data together.// For now, we will let these be containers, since they don\u0027t have obvious// functionality of their own.struct Position { int x, y; };struct Velocity { int dx, dy; };// Yes, it\u0027s basically the same structure - right now - but there are benefits// to this kind of duplication: we get more type information. We know that // adding Position + Velocity or Velocity + Position or Velocity + Velocity // makes sense, but Position + Position doesn\u0027t. That helps us avoid logical // errors when we write the code, by looking at the data types. Later, we\u0027ll // use better techniques, but I don\u0027t want to show too much at once.struct Colour { Uint8 r, g, b, a; };// Now, our classes look like:class Entity {public:void draw(SDL_Surface* dest);// I *will* implement the constructor, because the above discussion doesn\u0027t// explain enough about what to do... Entity(const Position\u0026amp; p, int size, const Colour\u0026amp; colour) : position(p), size(size), colour(colour) {}protected: Position position;private:int size; Colour colour;};class Player : public Entity {public:// We\u0027ll need to \"forward\" the constructor - i.e. explain how to construct the// \"entity part of\" a Player for a given Player object. Player(const Position\u0026amp; p, int size, const Colour\u0026amp; colour, int radius, int angle): Entity(p, size, colour), turning_radius(radius), angle(angle) {}// The Player\u0027s position will change iteratively (i.e. once per game loop)// just as any Bullet\u0027s position does.void move();// Think *carefully* about how you are going to implement move() for this// class. You can\u0027t *just* add the vector specified by the turning radius// and angle, because that just gives a straight line motion in that// direction. You\u0027ll want to *change* the angle over time, and also... well,// I\u0027ll give you some room for trial and error :)// Also, the player needs to be able to fire a bullet: Bullet fire();// Think about how you are going to decide what you pass to the Bullet// constructor. You have access to the needed position (i.e. the current// position of \u0027this\u0027 object). Size and colour will presumably always be some// constant \"bullet\" values. What about the velocity?private:int turning_radius;float angle;};class Bullet : public Entity {public:// This should look familiar... Player(const Position\u0026amp; p, int size, const Colour\u0026amp; colour, const Velocity\u0026amp; v): Entity(p, size, colour), velocity(v) {}void move();// This version of move() should be a lot easier to implement: just \"add\" the// velocity to the position.private: Velocity velocity;};// Above, I said:// Think about how you are going to decide what you pass to the Bullet// constructor.... Size and colour will presumably always be some// constant \"bullet\" values.// Think MORE about that. Do we *need* to specify a size and colour when we make// the Bullet? Why not just let the Bullet specify them? We can pass a constant// value in the initializer list; it doesn\u0027t have to come from a constructor// parameter. Similarly for the player.// Our main code will do someting like this:#include \u0026lt;vector\u0026gt;#include \u0026lt;algorithm\u0026gt;int main() { std::vector\u0026lt;Bullet\u0026gt; bullets; Player p(/* args */);// If the player wants to fire a bullet, we add it to the bullets like this: bullets.push_back(p.fire());// We update the player\u0027s position like this: p.move();// We update all the bullet positions like this: std::for_each(bullets.begin(), bullets.end(), std::mem_fun_ref(\u0026amp;Bullet::move));// We draw the player like this: p.draw();// We draw all the bullets like this: std::for_each(bullets.begin(), bullets.end(), std::mem_fun_ref(\u0026amp;Bullet::draw));// We DON\u0027T mess around with the bullet\u0027s internal data each time around in// order to \"move\" it. We certainly don\u0027t re-set its colour to the same thing// every time ;)}\n", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079773", "author": { "@type": "Person", "name": "recon6", "image": "https://secure.gravatar.com/avatar/2d870c140d00c6915464dbfeceb4cd86?d=https://www.gamedev.net/uploads/monthly_2017_08/R.png.2dd6229bd11d8f65933307e64c42b961.png", "url": "https://www.gamedev.net/profile/128857-recon6/" }, "dateCreated": "2007-10-13T15:33:21+0000", "text": "Thanks a lot, much appreciated.I\u0027ll give it a shot.", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079895", "author": { "@type": "Person", "name": "Chad Smith", "image": "https://www.gamedev.net/uploads/monthly_2017_12/C_member_84174.png", "url": "https://www.gamedev.net/profile/84174-chad-smith/" }, "dateCreated": "2007-10-13T20:05:53+0000", "text": "Wow...yet another very nice post from you. Simply amazing.\n", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" }, { "@type": "Comment", "url": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/?do=findComment\u0026comment=4079948", "author": { "@type": "Person", "name": "cNoob", "image": "https://secure.gravatar.com/avatar/6898a11e5a77d7a64b68abe36b13ef9e?d=https://www.gamedev.net/uploads/monthly_2017_08/C.png.0a0e9aa0c0f82d612883ccbe5d381beb.png", "url": "https://www.gamedev.net/profile/84130-cnoob/" }, "dateCreated": "2007-10-13T22:16:14+0000", "text": "Agreed, Great post Zahlman.", "mainEntityOfPage": "https://www.gamedev.net/forums/topic/468260-problem-with-inheritance-in-sdl-class/" } ] } { "@context": "http://www.schema.org", "@type": "WebSite", "name": "GameDev.net", "url": "https://www.gamedev.net/", "potentialAction": { "type": "SearchAction", "query-input": "required name=query", "target": "https://www.gamedev.net/search/?q={query}" }, "inLanguage": [ { "@type": "Language", "name": "English (USA)", "alternateName": "en-US" } ] } { "@context": "http://www.schema.org", "@type": "Organization", "name": "GameDev.net", "url": "https://www.gamedev.net/", "logo": "https://www.gamedev.net/uploads/themes/monthly_2017_04/gamedev-logo-2017-368x76.png.e986e41d566ff6c90485a5304985ed5f.png", "address": { "@type": "PostalAddress", "streetAddress": "", "addressLocality": null, "addressRegion": null, "postalCode": null, "addressCountry": null } } { "@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@id": "https://www.gamedev.net/groups/", "name": "Groups" } }, { "@type": "ListItem", "position": 2, "item": { "@id": "https://www.gamedev.net/groups/2-for-beginners/", "name": "For Beginners" } }, { "@type": "ListItem", "position": 3, "item": { "@id": "https://www.gamedev.net/forums/forum/71-for-beginners/", "name": "Forum" } } ] } { "@context": "http://schema.org", "@type": "ContactPage", "url": "https://www.gamedev.net/contact/" } Important Information By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.   I accept We are the game development community. Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up! Sign me up!