我正在打一场乒乓球比赛.在我调试的时候,我一直在使用一个简单的44 x 44 .png的红色方块作为我的球.这个广场上的游戏很好用.
@H_403_9@解决方法
当我尝试用方形以外的任何东西替换纹理时,我看不到屏幕上绘制的球,我无法弄清楚原因.我在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作为您的比例将以它的默认大小绘制它.