Skip to main content
fixed typo
Source Link
Cypher
  • 1.3k
  • 1
  • 10
  • 18
  1. Services [Services][1].

  2. Pass an object via a constructor, property, or method.

  3. Do neither. Instead, handle your collision detection and particle effects outside of both of these classes. (recommended)

The reason I would recommend this method is that it decouples your classes from each other making debugging simpler and your classes more re-usable. If you end up chaining your objects together, a simple modification of one class can have cascading effects on the rest of your code making what should be a simple change into a major code refactor.


Here's how you could modify your existing classes to pass your Bat object to your Ball object:

public class Ball
{
    ....
    private bool hasHitBat;
    private AIBat aiBat;
    private Bat bat;    // this will hold the reference to the player's bat
                        // that can be used throughout the rest of the class
    ....

    /// <summary>
    /// Constructor for the ball
    /// </summary>
    public Ball(ContentManager contentManager, Vector2 ScreenSize, Bat playerBat ) {
        bat = playerBat;
        ...
    }

Then in your GameplayScreen, you would have to flip some things around:

class GameplayScreen 
{

    private Ball ball;
    private Bat leftBat;

    protected void Initialize()
    {
        ...
        SetUpSingle(); // Sets up a single player game

        ball = new Ball(
                   contentManager, 
                   new Vector2(
                       ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea.Width,
                       ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea.Height),
                   leftBat, );
        ...
    }

Now as your GameplayScreen updates the leftBat object, you'll need to update the Ball object (to let it know about the changes to it's local bat object), and your ball will be able to react to the player's bat.

I still think it's easier to test for collisions inside your GameplayScreen.Update() method, but if you want to go down this route, that would be how you could do it. [1]: http://blog.nuclex-games.com/tutorials/xna/components-and-services/

  1. Services.

  2. Pass an object via a constructor, property, or method.

  3. Do neither. Instead, handle your collision detection and particle effects outside of both of these classes. (recommended)

The reason I would recommend this method is that it decouples your classes from each other making debugging simpler and your classes more re-usable. If you end up chaining your objects together, a simple modification of one class can have cascading effects on the rest of your code making what should be a simple change into a major code refactor.

  1. [Services][1].

  2. Pass an object via a constructor, property, or method.

  3. Do neither. Instead, handle your collision detection and particle effects outside of both of these classes. (recommended)

The reason I would recommend this method is that it decouples your classes from each other making debugging simpler and your classes more re-usable. If you end up chaining your objects together, a simple modification of one class can have cascading effects on the rest of your code making what should be a simple change into a major code refactor.


Here's how you could modify your existing classes to pass your Bat object to your Ball object:

public class Ball
{
    ....
    private bool hasHitBat;
    private AIBat aiBat;
    private Bat bat;    // this will hold the reference to the player's bat
                        // that can be used throughout the rest of the class
    ....

    /// <summary>
    /// Constructor for the ball
    /// </summary>
    public Ball(ContentManager contentManager, Vector2 ScreenSize, Bat playerBat ) {
        bat = playerBat;
        ...
    }

Then in your GameplayScreen, you would have to flip some things around:

class GameplayScreen 
{

    private Ball ball;
    private Bat leftBat;

    protected void Initialize()
    {
        ...
        SetUpSingle(); // Sets up a single player game

        ball = new Ball(
                   contentManager, 
                   new Vector2(
                       ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea.Width,
                       ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea.Height),
                   leftBat, );
        ...
    }

Now as your GameplayScreen updates the leftBat object, you'll need to update the Ball object (to let it know about the changes to it's local bat object), and your ball will be able to react to the player's bat.

I still think it's easier to test for collisions inside your GameplayScreen.Update() method, but if you want to go down this route, that would be how you could do it. [1]: http://blog.nuclex-games.com/tutorials/xna/components-and-services/

Source Link
Cypher
  • 1.3k
  • 1
  • 10
  • 18

It sounds like you have your game working, which means you have an instance of bat and ball somewhere in your code (Game1.cs or its equivalent), I assume.

If you need your ball object to react to the bat object's properties, then you need the ball class to have a reference to the bat instance. You can do this in two ways:

  1. Services.

  2. Pass an object via a constructor, property, or method.

  3. Do neither. Instead, handle your collision detection and particle effects outside of both of these classes. (recommended)

Here's an example of passing the already created bat object to the ball constructor, so that ball can then access bat's public properties and methods:

// Game1.cs

private Bat bat;
private Ball ball;

protected void LoadContent() {
    ...
    Bat bat = new Bat();          // create the bat
    Ball ball = new Ball( bat );  // create the ball, passing in the bat
    ...
}

Then in your Ball class:

// Ball.cs

private Bat bat;                  // this will hold the local reference to the bat

public Ball( Bat myBat ) {
    ...
    bat = myBat;                  // this assigns and instantiates the member bat
    ...                           // with myBat which was passed from the constructor
}

public override Update( GameTime gameTime ) {
    ...
    // now we can access the bat via the local private member, bat
    doSomethingWithBat( bat.Position );
    ...
}

Of course, I would recommend against having objects rely on each other. Instead, I would write another class or a few lines of code outside of those classes to detect the collision and play render your particle effect. Something like:

public override void Update( GameTime gameTime ) {
    ...
    if( Collision( ball, bat ) ) {
        ParticleManager.Play( Particle.BigBaddaBoom, ball.Position );
    }
    ...
}

The reason I would recommend this method is that it decouples your classes from each other making debugging simpler and your classes more re-usable. If you end up chaining your objects together, a simple modification of one class can have cascading effects on the rest of your code making what should be a simple change into a major code refactor.