我正在做一个乒乓球游戏。在调试时,我一直在使用一个简单的 44 x 44 .png 红色正方形作为我的球。游戏在这个方块上运行良好。
当我尝试用正方形以外的任何东西替换纹理时,我看不到屏幕上绘制的球,我不知道为什么。我在 Photoshop 中使我的图像大小完全相同,并使用 .PNG 或 .JPG 并获得相同的结果,但我一生都无法弄清楚。你认为什么可能导致这个问题?
我在下面的文字中留下了我的球的代码。GameplayScreen 正在调用我的球的更新和绘制方法(使用 MS 的 GSM 示例)。
public class Ball : IGameEntity
{
#region Fields
private Random rand; // Random var
private Texture2D texture; // Texture for the ball
private double direction; // Directon the ball is traveling in
private bool isVisible;
private bool hasHitLeftBat; // Checked to see if the ball and bat have just collided
private bool hasHitRightBat; // Checked to see if the ball and bat have just collided
private Vector2 ballPosition, resetBallPos, oldBallPos;
private Rectangle ballRect;
public float Speed;
private SpriteBatch spriteBatch; // Spritebatch
private bool isBallStopped;
private Vector2 origin; // Locate the mid-point of the ball
public float RotationAngle;
private AIBat rightBat; // Player's Bad
private Bat leftBat; // AI Bat
private float ballRelativePos;
private Rectangle rectangle3; // Used to draw the collison rectangle
private Texture2D blank; // Texture to be drawn on the collision rectangle
GameplayScreen gameplayScreen; // Creates an instance of the GameplayScreen
Game1 gameInstance; // Creates an instance of the Game1 class
int selectedStage; // Pass this into GameplayScreen for selecting easy, medium, or hard
#endregion
#region Constructors and Destructors
/// <summary>
/// Constructor for the ball
/// </summary>
public Ball(ContentManager contentManager, Vector2 ScreenSize, Bat bat, AIBat aiBat)
{
Speed = 15f;
texture = contentManager.Load<Texture2D>(@"gfx/balls/redBall");
direction = 0;
ballRect = new Rectangle(0, 0, texture.Width /2, texture.Height /2);
resetBallPos = new Vector2(ScreenSize.X / 2 + origin.X, ScreenSize.Y / 2 + origin.Y);
ballPosition = resetBallPos;
rand = new Random();
isVisible = true;
origin = new Vector2(texture.Width / 2, texture.Height / 2);
leftBat = bat; // Creates a new instance of leftBat so that I can access Position.X/Y for LeftBatPatcicles()
rightBat = aiBat;// Creates a new instance of leftBat so that can access Position.X/Y for RightBatPatcicles()
gameplayScreen = new GameplayScreen(null, selectedStage);
gameInstance = new Game1();
Rectangle rectangle3 = new Rectangle();
blank = contentManager.Load<Texture2D>(@"gfx/blank");
// pes = new ParticleEmitterService(game);
}
public Ball(Bat myBat)
{
leftBat = myBat; // this assigns and instantiates the member bat
// with myBat which was passed from the constructor
}
#endregion
#region Methods
/// <summary>
/// Draws the ball on the screen
/// </summary>
public void Draw(SpriteBatch spriteBatch)
{
if (isVisible)
{
// Draws the rotaing ball
spriteBatch.Draw(texture, ballPosition, ballRect, Color.White,
RotationAngle, origin, .0f, SpriteEffects.None, 0);
spriteBatch.Draw(blank, rectangle3, Color.LightCoral);
}
}
/// <summary>
/// Updates position of the ball. Used in Update() for GameplayScreen.
/// </summary>
public void UpdatePosition(GameTime gameTime)
{
ballRect.X = (int)ballPosition.X;
ballRect.Y = (int)ballPosition.Y;
oldBallPos.X = ballPosition.X;
oldBallPos.Y = ballPosition.Y;
ballPosition.X += Speed * ((float)Math.Cos(direction));
ballPosition.Y += Speed * ((float)Math.Sin(direction));
bool collided = CheckWallHit();
// Stops the issue where ball was oscillating on the ceiling or floor
if (collided)
{
ballPosition.X = oldBallPos.X + Speed * (float)1.5 * (float)Math.Cos(direction);
ballPosition.Y = oldBallPos.Y + Speed * (float)Math.Sin(direction);
}
// As long as the ball is to the right of the back, check for an update
if (ballPosition.X > leftBat.BatPosition.X)
{
// When the ball and bat collide, draw the rectangle where they intersect
BatCollisionRectLeft();
}
// As longas the ball is to the left of the back, check for an update
if (ballPosition.X < rightBat.BatPosition.X)
{ // When the ball and bat collide, draw the rectangle where they intersec
BatCollisionRectRight();
}
// The time since Update was called last.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// Rotation for the ball
RotationAngle += elapsed;
float circle = MathHelper.Pi * 2;
RotationAngle = RotationAngle % circle;
// base.Update(gameTime);
gameInstance.update();
}
/// <summary>
/// Checks for the current direction of the ball
/// </summary>
public double GetDirection()
{
return direction;
}
/// <summary>
/// Checks for the current position of the ball
/// </summary>
public Vector2 GetPosition()
{
return ballPosition;
}
/// <summary>
/// Checks for the current size of the ball (for the powerups)
/// </summary>
public Rectangle GetSize()
{
return ballRect;
}
/// <summary>
/// Checks to see if ball went out of bounds, and triggers warp sfx. Used in GameplayScreen.
/// </summary>
public void OutOfBounds()
{
AudioManager.Instance.PlaySoundEffect("Muzzle_shot");
}
/// <summary>
/// Speed for the ball when Speedball powerup is activated
/// </summary>
public void PowerupSpeed()
{
Speed += 20.0f;
}
/// <summary>
/// Check for where to reset the ball after each point is scored
/// </summary>
public void Reset(bool left)
{
if (left)
{
direction = 0;
}
else
{
direction = Math.PI;
}
ballPosition = resetBallPos; // Resets the ball to the center of the screen
isVisible = true;
Speed = 15f; // Returns the ball back to the default speed, in case the speedBall was active
if (rand.Next(2) == 0)
{
direction += MathHelper.ToRadians(rand.Next(30));
}
else
{
direction -= MathHelper.ToRadians(rand.Next(30));
}
}
/// <summary>
/// Shrinks the ball when the ShrinkBall powerup is activated
/// </summary>
public void ShrinkBall()
{
ballRect = new Rectangle(0, 0, texture.Width / 2, texture.Height / 2);
}
/// <summary>
/// Stops the ball each time it is reset. Ex: Between points / rounds
/// </summary>
public void Stop()
{
isVisible = true;
Speed = 0;
isBallStopped = true;
}
/// <summary>
/// Checks for collision with the ceiling or floor. 2*Math.pi = 360 degrees
/// </summary>
private bool CheckWallHit()
{
while (direction > 2 * Math.PI)
{
direction -= 2 * Math.PI;
return true;
}
while (direction < 0)
{
direction += 2 * Math.PI;
return true;
}
if (ballPosition.Y <= 0 || (ballPosition.Y > resetBallPos.Y * 2 - ballRect.Height))
{
direction = 2 * Math.PI - direction;
return true;
}
return true;
}
/// <summary>
/// Used to determine the location where the particles will initialize when the ball and bat collide
/// </summary>
private void BatCollisionRectLeft()
{
// For the left bat
if (ballRect.Intersects(leftBat.batRect))
{
rectangle3 = Rectangle.Intersect(ballRect, leftBat.batRect);
}
}
/// <summary>
///Checks for collision of Right Bat
/// </summary>
private void BatCollisionRectRight()
{
// for the right bat
if (ballRect.Intersects(rightBat.batRect))
{
rectangle3 = Rectangle.Intersect(ballRect, rightBat.batRect); ;
}
}