Я создаю проект для университетского задания и наткнулся на небольшую загвоздку. Проблема незначительна и, скорее всего, может быть выдана незамеченной, но меня она все еще беспокоит, и, будучи процедурным человеком с точки зрения выполнения работы, я не могу перейти ни к чему другому, пока она не будет решена.
У меня есть код ракетки и мяча, работающий нормально, а также простая угловая скорость, основанная на том, где мяч ударяется о ракетку, однако моя проблема заключается в том, когда мяч ударяется о кирпичи. Код в основном работает и кажется безупречным, однако это меняется, когда мяч выполняет одно из этих двух действий:
- Попадание кирпича в один из углов может изменить неверную ось скорости мяча.
- Удар по двум кирпичам одновременно (по их углам) заставит мяч пройти через них и удалит их; даже если у них полное здоровье.
Код, который я использую, находится здесь (Ball.cs):
ИЗМЕНИТЬ (обновленный код):
public bool Touching(Brick brick)
{
var position = Position + Velocity;
return position.Y + Size.Y >= brick.Position.Y &&
position.Y <= brick.Position.Y + brick.Size.Y &&
position.X + Size.X >= brick.Position.X &&
position.X <= 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;
}
Эти методы вызываются из метода Update Level.cs:
public override void Update(GameTime gameTime)
{
player.Update(gameTime);
balls.ForEach(ball => 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 > 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()) < Vector2.Distance(ball.GetCenterpoint(closestBrick), ball.GetCenterpoint()))
{
closestBrick = brick;
}else
{
brick.Health--;
if (brick.Health > 0) brick.Texture = Assets.GetBrick(brick.TextureName, brick.Health);
}
}
if (ball.Collide(closestBrick))
{
closestBrick.Health--;
if (closestBrick.Health > 0) closestBrick.Texture = Assets.GetBrick(closestBrick.TextureName, closestBrick.Health);
}
}
collidingBricks = new List<Brick>();
}
bricks.RemoveAll(brick => brick.Health <= 0);
base.Update(gameTime);
}
Метод столкновения мяча - это то, что определяет новые значения скорости мяча. Как видите, это полностью зависит от того, где будет находиться мяч, а не от того, где он находится. Кроме того, я запускаю проверку столкновений для ближайшего кирпича, с которым сталкивается мяч, но уменьшаю здоровье всех кирпичей, которых касается мяч (поэтому скорость будет обновляться только на основе только ближайший кирпич, а не все сталкивающиеся кирпичи).
Я понимаю, почему это вызывает у меня проблемы, и что это может быть из-за того, что мяч одновременно ударяет по двум сторонам (при попадании в угол).
Как я уже сказал, это незначительная проблема, но она все равно может повлиять на игровой процесс, особенно если вы ожидаете, что мяч будет двигаться в одном направлении, но только в противоположном.
return true;
после проверки столкновения Y, разве вы не отдаете предпочтение этому направлению в случае, если оно столкнется по обеим осям? - person Cyral   schedule 20.11.2013