0
\$\begingroup\$

I'm making a simple Pong clone game and have been having an issue deciding on how my classes should handle the initial placement of an object.

For instance, my Ball class's constructor is:

Ball (std::string imageName, float screenWidth, float screenHeight)

The constructor then automatically centers the ball in the middle of the screen, since it knows the ball's width and height the dimensions the image it loads, and the screen width and height by the arguments it is passed.

I would rather be able to place the ball manually, and just take the exact x and y locations in the constructor:

Ball (std::string imageName, float x, float y)

But that would require the calling function to already know the ball's width and height in order to center the ball and when it creates a ball it'd have to write something like:

Ball ball("ball.png", ((SCREEN_WIDTH / 2) - (BALL_WIDTH / 2)),
((SCREEN_HEIGHT / 2) - (BALL_HEIGHT / 2)))

I know this may be personal preference, but I'm trying to figure out which way is generally accepted.

A similar issue occurs with my Paddle class. Its constructor argument list looks like this:

Paddle (std::string imageName, float screenWidth, float screenHeight, int player)

Since I set the location inside of the constructor, it's forced me to have a player flag so I know if the paddle is supposed to line up with the left or right hand side of the screen. If I took the exact x and y location in the constructor's argument list, I could figure out which player is which internally using math.

I'm thinking that if the calling function kept consts of all of their objects' widths and heights they could use those in all of their objects' constructors in order to manually set their starting position... but is this the best way to do this?

EDIT:

Now I'm thinking that it would be realistic to expect the calling function to know the center x and center y that it wants the object at, and the object itself can use those x and y coordinates to center itself using its own width and height.

I'm starting to think this may have been a silly question since it really depends on the type of game you're making and how you're using the specific classes. I appreciate any input!

\$\endgroup\$
1
  • \$\begingroup\$ N.B. you should pass the std::string by const reference (unless you are using C++11 and have access to move semantics, in which case you might not want to, but it generally will not hurt). \$\endgroup\$ – user1430 Feb 11 '14 at 16:37
1
\$\begingroup\$

I would assert that your first ball constructor, which takes the width and height of the screen, is not a good idea. The ball should not need to know about the boundaries of the screen; that encroaches upon a violation of the single responsibility principle for the ball object. A ball should be a ball, and store only information directly pertinent to it:

  • its position in the world
  • its size
  • its sprite (I actually think this should go elsewhere as well, but that is a different topic)

A ball should have methods to query the size and bounds and a higher level interface (for example, a Playfield class) should be the one that determines if the ball is in within the boundaries of the playing field.

This allows you to, with no loss of generality:

  • move the ball outside the play field if you need to (for some kind of special "exit the screen" transition effect, perhaps).
  • move the ball between two different playing fields of different sizes (perhaps you have a split-screen two-player mode where you can "teleport" a ball into your opponent's field, for example).

If you define the ball's position as it's center, and the ball exposes its position and size information, you can easily compute the appropriate place to draw the ball's sprite from the code that does the rendering (which is partly why I feel like the sprite itself need not be part of the ball object).

(In other words, use your second constructor, the one that takes the position of the ball and not the screen size.)


Similarly with your Paddle class, I'd do the same. Just pass the position; the Paddle itself need not know which player it belongs to, that can also be handled by an external, higher level interface.

The basic idea I am advocating here is to keep individual interfaces as simple as possible, and compose the intended gameplay functionality by building up layers of increasingly higher-level interfaces that make use of lower-level ones. Like an onion, sort of.

You may also find the SOLID principles of object oriented design an interesting collection of reading.

\$\endgroup\$
0
\$\begingroup\$

This may add a little complication to your scenario but typically in games we use positions in 3D space even when working in 2D by using a transform.

Every object should have a local transform and is a child of the world transform, these transforms represent "model space" and "world space".

When determining an objects position the hardware needs to determine its location in world space by performing the translations in the "transform tree".

With 2D positioning typically we use a ray to determine a location of something by firing a ray from our camera we can determine a relationship between a pixel and an object in 3D space.

If you think about how your game will be rendered, you are sending information about a camera, its location, rotation, and the point it is looking at, you then define the object you want to place in your scene position it anywhere you want, it might be in front of the camera it might not, the hardware is really only concerned about what colour each pixel should be, how it determines that is based on a lot of information.

However ... All that said and done i am making a lot of assumptions here that basically depend on you taking a typical game engine and trying to implement something rather than say trying to place something on a windows form which is in fact based on a 2D coordinate system.

\$\endgroup\$
2
  • \$\begingroup\$ Hmm I think I understand what you're saying. I understand I send information to the renderer, such as the positions and rotations of a given object, and it draws the image on the screen based on that information. The main issue I'm confused about is if the calling function should already know the width and the height of the object it's creating, before it creates it, in order to decide the object's starting position. I'm sorry if your explanation went right over my head I'm trying to grasp what you're saying. \$\endgroup\$ – lightningblah Feb 11 '14 at 15:22
  • \$\begingroup\$ what i mean is that if i render something at position (0,0,0) do I draw it or not? well that's based on what the camera for your scene is currently looking at, if its looking in the direction of (0,0,0) and relatively close you probably do want to render it so the problem is twofold ... what's my object position, and whats my camera looking at. The width and height may be determined in the same way, by the size of the object and the distance to the camera. \$\endgroup\$ – War Feb 11 '14 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.