Note that there are some explanatory texts on larger screens.

plurals
  1. POC# XNA - Breakout-style ball physics
    primarykey
    data
    text
    <p>I am creating a project for a university assignment, and I have hit a bit of a snag. The problem is minor and can most likely be passed off as unnoticed, but it still bothers me and, being a procedural person in terms of completing work, I can't move on to anything else until it is solved.</p> <p>I have the paddle and ball code working fine, as well as a simple angular velocity based on where the ball hits the paddle, however my issue is when the ball hits the bricks. The code mostly works and it seems flawless, however this changes when the ball does one of these two things:</p> <ul> <li>Hitting a brick on one of its corners may incorrectly reverse the wrong axis of the ball's velocity</li> <li>Hitting two bricks at the same time (in their corners) will cause the ball to pass through them and remove them; even if they have full health.</li> </ul> <p>The code I am using is here (Ball.cs):</p> <p><em><strong>EDIT (Updated Code):</em></strong></p> <pre><code>public bool Touching(Brick brick) { var position = Position + Velocity; return position.Y + Size.Y &gt;= brick.Position.Y &amp;&amp; position.Y &lt;= brick.Position.Y + brick.Size.Y &amp;&amp; position.X + Size.X &gt;= brick.Position.X &amp;&amp; position.X &lt;= brick.Position.X + brick.Size.X; } public bool Collide(Brick brick) { //Secondary precaution check if (!Touching(brick)) return false; //Find out where the ball will be var position = Position + Velocity; //Get the bounds of the ball based on where it will be var bounds = new Rectangle((int)position.X, (int)position.Y, Texture.Width, Texture.Height); //Stop the ball from moving here, so that changes to velocity will occur afterwards. Position = Position - Velocity; //If the ball hits the top or bottom of the brick if (bounds.Intersects(brick.Top) || bounds.Intersects(brick.Bottom)) { Velocity = new Vector2(Velocity.X, -Velocity.Y); //Reverse the Y axe of the Velocity } //If the ball hits the left or right of the brick if (bounds.Intersects(brick.Left) || bounds.Intersects(brick.Right)) { Velocity = new Vector2(-Velocity.X, Velocity.Y); //Reverse the X axe of the Velocity } return true; } </code></pre> <p>These methods are being called from Level.cs' Update method:</p> <pre><code>public override void Update(GameTime gameTime) { player.Update(gameTime); balls.ForEach(ball =&gt; ball.Update(gameTime)); foreach (var brick in bricks) { foreach (var ball in balls) { if (ball.Touching(brick)) { if (!collidingBricks.Contains(brick)) collidingBricks.Add(brick); } } brick.Update(gameTime); } if (collidingBricks.Count &gt; 0) { foreach (var ball in balls) { Brick closestBrick = null; foreach (var brick in collidingBricks) { if (closestBrick == null) { closestBrick = brick; continue; } if (Vector2.Distance(ball.GetCenterpoint(brick), ball.GetCenterpoint()) &lt; Vector2.Distance(ball.GetCenterpoint(closestBrick), ball.GetCenterpoint())) { closestBrick = brick; }else { brick.Health--; if (brick.Health &gt; 0) brick.Texture = Assets.GetBrick(brick.TextureName, brick.Health); } } if (ball.Collide(closestBrick)) { closestBrick.Health--; if (closestBrick.Health &gt; 0) closestBrick.Texture = Assets.GetBrick(closestBrick.TextureName, closestBrick.Health); } } collidingBricks = new List&lt;Brick&gt;(); } bricks.RemoveAll(brick =&gt; brick.Health &lt;= 0); base.Update(gameTime); } </code></pre> <p>The ball's Collide method is what determines the new velocity values of the ball. As you can see, it is entirely based on where the ball <em>will</em> be, not where the ball is. Additionally, I run the collision check for the closest brick that the ball is colliding with, but I reduce the health of all bricks that the ball is touching (so, the velocity will only update based on <em>just</em> the closest brick, not <em>all</em> colliding bricks).</p> <p>I understand why it is causing me problems, and that it may be because of the fact that the ball is hitting two sides at the same time (as it hits the corner.)</p> <p>Like I said, it's a minor issue, but can even still impact on the game experience, especially when you expect the ball to logically go in one direction only for it to travel in the opposite.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload