Services [Services][1].
Pass an object via a constructor, property, or method.
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/