c# – 无法在XNA中绘制超过正方形的图像

前端之家收集整理的这篇文章主要介绍了c# – 无法在XNA中绘制超过正方形的图像前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在打一场乒乓球比赛.在我调试的时候,我一直在使用一个简单的44 x 44 .png的红色方块作为我的球.这个广场上的游戏很好用.

当我尝试用方形以外的任何东西替换纹理时,我看不到屏幕上绘制的球,我无法弄清楚原因.我在photoshop中使我的图像尺寸完全相同,并且使用.PNG或.JPG并且具有相同的结果,但我无法弄明白我的生活.您认为可能导致此问题的原因是什么?

我在下面的文字中留下了我的球的代码.我的球的更新和绘制方法由GameplayScreen调用(使用MS’GSM示例).

  1. public class Ball : IGameEntity
  2. {
  3. #region Fields
  4.  
  5. private Random rand; // Random var
  6. private Texture2D texture; // Texture for the ball
  7. private double direction; // Directon the ball is traveling in
  8. private bool isVisible;
  9. private bool hasHitLeftBat; // Checked to see if the ball and bat have just collided
  10. private bool hasHitRightBat; // Checked to see if the ball and bat have just collided
  11. private Vector2 ballPosition,resetBallPos,oldBallPos;
  12. private Rectangle ballRect;
  13. public float Speed;
  14. private SpriteBatch spriteBatch; // Spritebatch
  15. private bool isBallStopped;
  16. private Vector2 origin; // Locate the mid-point of the ball
  17. public float RotationAngle;
  18. private AIBat rightBat; // Player's Bad
  19. private Bat leftBat; // AI Bat
  20. private float ballRelativePos;
  21. private Rectangle rectangle3; // Used to draw the collison rectangle
  22. private Texture2D blank; // Texture to be drawn on the collision rectangle
  23.  
  24. GameplayScreen gameplayScreen; // Creates an instance of the GameplayScreen
  25. Game1 gameInstance; // Creates an instance of the Game1 class
  26. int selectedStage; // Pass this into GameplayScreen for selecting easy,medium,or hard
  27.  
  28.  
  29. #endregion
  30.  
  31. #region Constructors and Destructors
  32.  
  33. /// <summary>
  34. /// Constructor for the ball
  35. /// </summary>
  36. public Ball(ContentManager contentManager,Vector2 ScreenSize,Bat bat,AIBat aiBat)
  37. {
  38. Speed = 15f;
  39. texture = contentManager.Load<Texture2D>(@"gfx/balls/redBall");
  40. direction = 0;
  41. ballRect = new Rectangle(0,texture.Width /2,texture.Height /2);
  42. resetBallPos = new Vector2(ScreenSize.X / 2 + origin.X,ScreenSize.Y / 2 + origin.Y);
  43. ballPosition = resetBallPos;
  44. rand = new Random();
  45. isVisible = true;
  46. origin = new Vector2(texture.Width / 2,texture.Height / 2);
  47. leftBat = bat; // Creates a new instance of leftBat so that I can access Position.X/Y for LeftBatPatcicles()
  48. rightBat = aiBat;// Creates a new instance of leftBat so that can access Position.X/Y for RightBatPatcicles()
  49. gameplayScreen = new GameplayScreen(null,selectedStage);
  50. gameInstance = new Game1();
  51. Rectangle rectangle3 = new Rectangle();
  52. blank = contentManager.Load<Texture2D>(@"gfx/blank");
  53.  
  54. // pes = new ParticleEmitterService(game);
  55. }
  56.  
  57. public Ball(Bat myBat)
  58. {
  59. leftBat = myBat; // this assigns and instantiates the member bat
  60. // with myBat which was passed from the constructor
  61. }
  62.  
  63. #endregion
  64.  
  65. #region Methods
  66.  
  67. /// <summary>
  68. /// Draws the ball on the screen
  69. /// </summary>
  70. public void Draw(SpriteBatch spriteBatch)
  71. {
  72. if (isVisible)
  73. {
  74. // Draws the rotaing ball
  75. spriteBatch.Draw(texture,ballPosition,ballRect,Color.White,RotationAngle,origin,.0f,SpriteEffects.None,0);
  76.  
  77. spriteBatch.Draw(blank,rectangle3,Color.LightCoral);
  78. }
  79. }
  80.  
  81. /// <summary>
  82. /// Updates position of the ball. Used in Update() for GameplayScreen.
  83. /// </summary>
  84. public void UpdatePosition(GameTime gameTime)
  85. {
  86. ballRect.X = (int)ballPosition.X;
  87. ballRect.Y = (int)ballPosition.Y;
  88. oldBallPos.X = ballPosition.X;
  89. oldBallPos.Y = ballPosition.Y;
  90.  
  91. ballPosition.X += Speed * ((float)Math.Cos(direction));
  92.  
  93. ballPosition.Y += Speed * ((float)Math.Sin(direction));
  94. bool collided = CheckWallHit();
  95.  
  96.  
  97. // Stops the issue where ball was oscillating on the ceiling or floor
  98. if (collided)
  99. {
  100. ballPosition.X = oldBallPos.X + Speed * (float)1.5 * (float)Math.Cos(direction);
  101. ballPosition.Y = oldBallPos.Y + Speed * (float)Math.Sin(direction);
  102. }
  103.  
  104. // As long as the ball is to the right of the back,check for an update
  105. if (ballPosition.X > leftBat.BatPosition.X)
  106. {
  107. // When the ball and bat collide,draw the rectangle where they intersect
  108. BatCollisionRectLeft();
  109. }
  110.  
  111. // As longas the ball is to the left of the back,check for an update
  112. if (ballPosition.X < rightBat.BatPosition.X)
  113. { // When the ball and bat collide,draw the rectangle where they intersec
  114. BatCollisionRectRight();
  115. }
  116.  
  117. // The time since Update was called last.
  118. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  119.  
  120. // Rotation for the ball
  121. RotationAngle += elapsed;
  122. float circle = MathHelper.Pi * 2;
  123. RotationAngle = RotationAngle % circle;
  124.  
  125. // base.Update(gameTime);
  126. gameInstance.update();
  127.  
  128. }
  129.  
  130.  
  131. /// <summary>
  132. /// Checks for the current direction of the ball
  133. /// </summary>
  134. public double GetDirection()
  135. {
  136. return direction;
  137. }
  138.  
  139. /// <summary>
  140. /// Checks for the current position of the ball
  141. /// </summary>
  142. public Vector2 GetPosition()
  143. {
  144. return ballPosition;
  145. }
  146.  
  147. /// <summary>
  148. /// Checks for the current size of the ball (for the powerups)
  149. /// </summary>
  150. public Rectangle GetSize()
  151. {
  152. return ballRect;
  153. }
  154.  
  155.  
  156.  
  157. /// <summary>
  158. /// Checks to see if ball went out of bounds,and triggers warp sfx. Used in GameplayScreen.
  159. /// </summary>
  160. public void OutOfBounds()
  161. {
  162. AudioManager.Instance.PlaySoundEffect("Muzzle_shot");
  163. }
  164.  
  165. /// <summary>
  166. /// Speed for the ball when Speedball powerup is activated
  167. /// </summary>
  168. public void PowerupSpeed()
  169. {
  170. Speed += 20.0f;
  171. }
  172.  
  173. /// <summary>
  174. /// Check for where to reset the ball after each point is scored
  175. /// </summary>
  176. public void Reset(bool left)
  177. {
  178. if (left)
  179. {
  180. direction = 0;
  181. }
  182. else
  183. {
  184. direction = Math.PI;
  185. }
  186.  
  187. ballPosition = resetBallPos; // Resets the ball to the center of the screen
  188. isVisible = true;
  189. Speed = 15f; // Returns the ball back to the default speed,in case the speedBall was active
  190. if (rand.Next(2) == 0)
  191. {
  192. direction += MathHelper.ToRadians(rand.Next(30));
  193. }
  194. else
  195. {
  196. direction -= MathHelper.ToRadians(rand.Next(30));
  197. }
  198. }
  199.  
  200. /// <summary>
  201. /// Shrinks the ball when the ShrinkBall powerup is activated
  202. /// </summary>
  203. public void ShrinkBall()
  204. {
  205. ballRect = new Rectangle(0,texture.Width / 2,texture.Height / 2);
  206. }
  207.  
  208. /// <summary>
  209. /// Stops the ball each time it is reset. Ex: Between points / rounds
  210. /// </summary>
  211. public void Stop()
  212. {
  213. isVisible = true;
  214. Speed = 0;
  215. isBallStopped = true;
  216. }
  217.  
  218. /// <summary>
  219. /// Checks for collision with the ceiling or floor. 2*Math.pi = 360 degrees
  220. /// </summary>
  221. private bool CheckWallHit()
  222. {
  223. while (direction > 2 * Math.PI)
  224. {
  225. direction -= 2 * Math.PI;
  226. return true;
  227. }
  228.  
  229. while (direction < 0)
  230. {
  231. direction += 2 * Math.PI;
  232. return true;
  233. }
  234.  
  235. if (ballPosition.Y <= 0 || (ballPosition.Y > resetBallPos.Y * 2 - ballRect.Height))
  236. {
  237. direction = 2 * Math.PI - direction;
  238. return true;
  239. }
  240. return true;
  241. }
  242.  
  243. /// <summary>
  244. /// Used to determine the location where the particles will initialize when the ball and bat collide
  245. /// </summary>
  246. private void BatCollisionRectLeft()
  247. {
  248. // For the left bat
  249. if (ballRect.Intersects(leftBat.batRect))
  250. {
  251. rectangle3 = Rectangle.Intersect(ballRect,leftBat.batRect);
  252. }
  253. }
  254.  
  255. /// <summary>
  256. ///Checks for collision of Right Bat
  257. /// </summary>
  258. private void BatCollisionRectRight()
  259. {
  260. // for the right bat
  261. if (ballRect.Intersects(rightBat.batRect))
  262. {
  263. rectangle3 = Rectangle.Intersect(ballRect,rightBat.batRect); ;
  264. }
  265. }

解决方法

除非您不想绘制整个图像,否则不应在绘图调用中将任何内容作为SourceRect参数传递.

你现在设置它的方式是你在尝试绘制球时传递’ballRect’作为你的SourceRect,并且ballRect参数正在根据球的位置进行更新,所以你试图绘制一部分图像这超出了纹理的大小.

如果你想画整个球,只需使用:

  1. spriteBatch.Draw(texture,null,0);

如果您只想绘制球的左上象限,可以将以下矩形作为SourceRect传递:

  1. Rectangle sourceRect = new Rectangle(0,texture.Height / 2);

然后你可以在你的Draw调用中使用它:

  1. spriteBatch.Draw(texture,sourceRect,0);

编辑:你也传递.0f作为你的“比例”参数所以当它确实绘制你的球时,它将是0像素的大小,我猜这不是预期的行为.使用1f作为您的比例将以它的默认大小绘制它.

猜你在找的C#相关文章