我正在打一场乒乓球比赛.在我调试的时候,我一直在使用一个简单的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,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,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); ;
- }
- }
解决方法
除非您不想绘制整个图像,否则不应在绘图调用中将任何内容作为SourceRect参数传递.
你现在设置它的方式是你在尝试绘制球时传递’ballRect’作为你的SourceRect,并且ballRect参数正在根据球的位置进行更新,所以你试图绘制一部分图像这超出了纹理的大小.
如果你想画整个球,只需使用:
- spriteBatch.Draw(texture,null,0);
如果您只想绘制球的左上象限,可以将以下矩形作为SourceRect传递:
- Rectangle sourceRect = new Rectangle(0,texture.Height / 2);
然后你可以在你的Draw调用中使用它:
- spriteBatch.Draw(texture,sourceRect,0);
编辑:你也传递.0f作为你的“比例”参数所以当它确实绘制你的球时,它将是0像素的大小,我猜这不是预期的行为.使用1f作为您的比例将以它的默认大小绘制它.