전 C#으로 내 탁구 게임을 쓰고 있어요. 내 공이 문제없이 올바르게 재설정되지 않습니다. 나는 좋은 시간이나 코드를 디버깅하는 데 썼다. 그러나 나는 그것을 이해할 수 없다. 일하기로했다 기본적으로 무엇을'탁구'공이 재설정되지 않습니다.
는 볼이 윈도우의 경계를 떠나 감지되면 다음 Center()
방법은 전화를받을 것입니다 및 Center()
후 직접 백업 필드에 액세스하여 볼 Point
을 재설정한다는 것입니다. 이제이 방법이 작동합니다. 코드를 단계별로 실행하여 작동하는지 확인했습니다.
이상한 일이 발생하면 Center()
이 호출되면 공의 위치가 이전의 중심으로 되돌아갑니다. 이상한 일은 Point
속성의 set
접근자가 호출되기도 전에이 재설정이 수행된다는 것입니다. 그리고 여기에 코드
namespace Pong
{
internal enum CollisionType
{
Paddle, Boundary
}
class Ball
{
private readonly IGameView view;
private readonly IGameController controller;
private int velocity = 10;
private double angle;
private event CollisionHandler Collision;
private Point _point;
public Point Point
{
get { return _point; }
set
{ // If UpdatePosition() tries to move the ball beyond the boundaries in one tick move the ball to the boundaries
if(value.Y > view.Boundaries.Height || value.Y < 0)
{
_point = new Point(value.X, view.Boundaries.Height);
Collision(CollisionType.Boundary); // Also raise the collision event
}
//If the ball is going to pass the X boundaries of the map then a player should score and the ball should reset
if (value.X > view.Boundaries.Width || value.X < 0)
{
if (angle > 90) // If the angle of the ball of the ball is above 90 degrees then the left paddle was the shooter
{ // So he should score
var scoringPlayer = Array.Find(controller.Players, player => player.Paddle.Orientation.Equals(Orientation.Left));
controller.PlayerScore(scoringPlayer);
Center(scoringPlayer);
}
else // If not, then it's the right paddle
{
var scoringPlayer = Array.Find(controller.Players, player => player.Paddle.Orientation.Equals(Orientation.Right));
controller.PlayerScore(scoringPlayer);
Center(scoringPlayer);
}
}
// If the ball will collide with a player paddle then raise collision event
if (controller.Players.Any(player => player.Paddle.Position.Equals(value)))
{
Collision(CollisionType.Paddle);
_point = value;
}
_point = value;
}
}
public Ball(IGameView view, IGameController controller)
{
this.view = view;
this.controller = controller;
}
public void Center(Player server)
{
//Center the ball, acccess the backing field directly to avoid all the conditional logic in the property
_point = new Point(view.Boundaries.Width/2, view.Boundaries.Height/2);
//The ball will start moving from the center Point towards one of the different sides
/*TODO: Apparently the ball moves sideways down towards one of the player paddles, so we must implement more complex
logic to calculate the starting angle of the ball */
angle = (server.Paddle.Orientation.Equals(Orientation.Left)) ? 0 : 180;
}
public void UpdatePosition()
{
//Called to update ball position based on velocity and angle of ball
//For now let's just implement a very primitive movement algorithm
if (angle < 90)
{
Point = new Point(Point.X + velocity, Point.Y);
}
else
{
Point = new Point(Point.X - velocity, Point.Y);
}
}
}
//TODO: Add collision detection through BallCollision Event and implement BallCollisionHandler(CollisionType as Object args)
답변을 측면 초래, 여전히 속성 setter 오용으로 나쁜 코드 장려하기. – Sayse
나는 setter가 결정 론적이어야 함을 동의한다. 아마도 나는 setter보다는 "update"루프에 넣을 것이지만, 나는 단지 질문에 답했다. – Charleh
그래, 그거야! 또한 속성에 관해서는 알지 못했지만 유효성 검사와 물건에만 사용해야한다고 생각합니다. 나는 BallController 클래스를 구현하여 코드를 수정했다. –