0

ボール(楕円)と4つの長方形(それぞれウィンドウの端)があるアプリケーションがあります。ボールが移動して端から跳ね返るアプリを作成しようとしています。衝突が true のときにボールが方向を変えるメソッドの作成方法がわかりません。

XAML:

<Window x:Class="naszybkodlatestu.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="320" Width="640">
<Canvas>
    <Rectangle Name="boardTop"
               Height="2"
               Fill="Black"
               Width="609" Canvas.Left="7" Canvas.Top="10"/>
    <Rectangle Name="boardLeft"
               Height="270"
               Fill="Black"
               Width="2" Canvas.Left="614" Canvas.Top="10"/>
    <Rectangle Name="boardRight"
               Height="269"
               Fill="Black"
               Width="2" Canvas.Left="7" Canvas.Top="12"/>
    <Rectangle Name="boardBot"
               Height="2"
               Fill="Black"
               Width="609" Canvas.Left="7" Canvas.Top="278" />
    <Ellipse Name="ball"
             Width="15"
             Height="15"
             Fill="Red" 
             Canvas.Left="303" 
             Canvas.Top="107"/>
</Canvas>
</Window>

C#:

DispatcherTimer dTimer;
private void InitTimer()
{
    dTimer = new DispatcherTimer();
    dTimer.Tick += new EventHandler(TickdTimer);
    dTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);
    dTimer.Start();
}
public MainWindow()
{
    InitializeComponent();
    InitTimer();
    InitMove();

}

private bool isMovingUp = false;
private bool isMovingDown = false;
private bool isMovingLeft = true;
private bool isMovingRight = false;

private double ballDirectionX = 0;
private double ballDirectionY = 0;

private double ballSpeed = 1;

private bool CollisionDetection()
{
    if (CheckCollision(ball, boardBot) || CheckCollision(ball, boardRight) ||
        CheckCollision(ball, boardTop) || CheckCollision(ball, boardLeft))

    {
        return true;
    }
    else return false;
}

public static bool CheckCollision(FrameworkElement a, FrameworkElement b)
{
    Rect rect1 = new Rect((double)a.GetValue(Canvas.LeftProperty), (double)a.GetValue(Canvas.TopProperty), a.Width, a.Height);
    Rect rect2 = new Rect((double)b.GetValue(Canvas.LeftProperty), (double)b.GetValue(Canvas.TopProperty), b.Width, b.Height);

    if (rect1.IntersectsWith(rect2))
    {
        return true;
    }
        else return false;
}

private void InitMove()
{

    if (isMovingDown)
    {
        ballDirectionY += ballSpeed;
    }
    if (isMovingUp)
    {
        ballDirectionY -= ballSpeed;
    }
    if (isMovingLeft)
    {
        ballDirectionX -= ballSpeed;
    }
    if (isMovingRight)
    {
        ballDirectionX += ballSpeed;
    }
    ball.SetValue(Canvas.TopProperty, ballDirectionY);
    ball.SetValue(Canvas.LeftProperty, ballDirectionX);
}

だから私はInitMove()でそのようなものを試してみました。何が問題なのかを示すための単なるテスト コードです。

private void InitMove()
{
    .......
    if (CollisionDetection())
    {
        if (isMovingLeft)
        {
            isMovingLeft = false;
            isMovingRight = true;
        }
    }

そのため、ボールは左から右に方向を変えました。わかりました。

次の「if」を入れたいときに問題が始まります。

private void InitMove()
{
    .......
    if (CollisionDetection())
    {
        if (isMovingLeft)
        {
            isMovingLeft = false;
            isMovingRight = true;
        }
        if (isMovingRight)
        {
            isMovingRight = false;
            isMovingLeft = true;
        }
    }

これで、ボールは長方形の端を通過し、跳ね返りはありません。だからここに私の問題があります。

それを正しくする方法は?

//編集

私がelseを追加したとき

if (isMovingLeft)
{
    isMovingLeft = false;
    isMovingRight = true;
}
else if (isMovingRight)
{
    isMovingRight = false;
    isMovingLeft = true;
}

ボールが窓の端に止まった。

//EDIT2

わかりましたので、私はあなたにこのthxを行う方法を知っていると思います

if (isMovingLeft)
{
    isMovingLeft = false;
    isMovingRight = true;
    ballDirectionX += 2;
}
else if (isMovingRight)
{
    isMovingRight = false;
    isMovingLeft = true;
    ballDirectionX -= 2;
}

そこで、このボールを壁の衝突から押し出す動きを追加しました。今のところ別の方法はありません。

4

2 に答える 2

1

ボールが左に動いているとき、あなたの 2 つのifステートメントは互いに打ち消し合っています。最初に左に移動しているかどうかを確認し、右に移動するように設定します。次に、次のifステートメントがすぐに評価され、再び左に移動するように変更されます。これは、コードが実行されるたびに発生します。

2 番目の if ステートメントを に変更する必要があるelse ifため、同じフレームで両方を実行することはありません。また、バウンスは、壁に入ったのと同じ量だけ壁から押し戻さない限り、おそらく少し奇妙に見えるでしょうが、それは別の問題です.

于 2013-05-07T21:25:57.090 に答える