2016-05-13 1 views
0

私はWPFを使用してコンピュータサイエンスプロジェクトのリズムゲームを作成しています(ギターヒーローのような落ちないゲームですが、矢印付き)。私はDispatcherTimersをたくさん使ってアプリケーションを遅くし、フリーズアップさせました。これを修正するために、私はanswerを見つけました。これはSystem.Threading.Timersを使うことを勧めました。Dispatcherがクラスに表示されない - System.Threading.Timerを使用

私はこれを使って、これらのタイマー用に新しいスレッドを作成することを理解しています。これは、アプリケーションをひどく高速化することなく、それらをすべて同時に実行できるようにします。私はプログラムを実行した、古いダニからすべての私の方法を変更した後は

private void SetTimers() 
    { 
     _arrowKeytimer = new Timer(new TimerCallback(Timer_ArrowTick), null, 0, 775); 
     //_timerHealth = new Timer(new TimerCallback(Timer_HealthTick), null, 0, 775); 
     _MediaTimer = new Timer(new TimerCallback(Timer_MediaTick), null, 0, 775); 
     _leftFall = new Timer(new TimerCallback(LeftArrowFall), null, 0, 775); 
     _rightFall = new Timer(new TimerCallback(RightArrowFall), null, 0, 775); 
     _upFall = new Timer(new TimerCallback(UpArrowFall), null, 0, 775); 
     _downFall = new Timer(new TimerCallback(DownArrowFall), null, 0, 775); 
     _spawner = new Timer(new TimerCallback(Timer_SpawnTick), null, 0, 775); 
    } 

私のタイマーは、メソッドを作成するには、このです。即座に「別のスレッドからオブジェクトにアクセスできません」というメッセージが表示されます。例外。私はプログラムを再度実行し、それが私のdrawメソッドで同じ例外を投げ終わった

private void DownArrowFall(object state) 
    { 
     this.Dispatcher.Invoke((Action)(() => //Added the Invoke thing that the answer said to do 
     { 
     double y; 
     for (int z = 0; z < TheDirector.DownArrowList.Count; z++) // Before I would get the exception on this line 
     { 
      if ((string)TheDirector.DownArrowList[z].Tag == "Spawned") 
      { 
       y = Canvas.GetTop(TheDirector.DownArrowList[z]); 
       y += FallSpan; 
       Canvas.SetTop(TheDirector.DownArrowList[z], y); 
      } 
     } 
     double position = Canvas.GetTop(TheDirector.DownArrowList[0]); 
     if (position >= 700) 
     { 
      TheDirector.RemoveDownArrow(); 
     } 
     })); 
    } 

:このanswerを見て

は、私は例外を発生させたダニにDispatcher.Invokeメソッドを使用しました私のLeftArrowクラス(画面上に左下の矢印が描画されます)にあります。しかし、それはdidntは仕事を呼び出す追加:

public void Draw() 
    {   
     this.Dispatcher.Invoke((Action)(() => //Apparently 'Dispatcher' doesn't exist 
     { 

      for (int x = 0; x < _arrows.Count; x++) 
      { 
       if ((string)_arrows[x].Tag == "NotSpawned") 
       { 
        _arrows[x].Tag = "Spawned"; 
        _canvas.Children.Add(_arrows[x]); 
        Canvas.SetLeft(_arrows[x], Coordinates.LeftArrowX); 
        Canvas.SetTop(_arrows[x], Coordinates.Y); 
        break; 
       } 
      } 
     })); 
    } 

私は私がやっている見当がつかない - 私はこの問題に関連するすべての他の回答を確認しています。私の_arrowsリストはメインスレッドによって作成されていることがわかっています。そのため、私はこれらの例外を取得していますが、私はそれらについて何をすべきか分かりません。

ありがとうございました。私のコードについて

詳細情報:

ArrowFallタイマーのそれぞれは、画面上の全ての矢印のリストを検索する(それが何であるかをリストに依存して、4人は右の矢印のための第二は、左の矢印のための1があります等)、キャンバスに新しい位置を設定する前にY座標に一定量を追加します。

基本的に、私は2つのオブジェクト、つまり追加するキャンバスとリストの1つを取っています。他のスレッドは自分のリストとキャンバスにアクセスする必要があります。

注:リストは、Directorと呼ばれるクラス(この場合はTheDirectorという名前のインスタンス)に格納され、長方形のリストがプロパティとして格納されます。これらのプロパティは、各矢印のクラスによって作成されたリストを返します。クラス 'RightArrow'、 'LeftArrow'など

+0

あなたのゲームロジックに8つの完全に同期化されていないスレッドがあっても解決しなければならない*本当の問題にはまだ程遠いです。このアプローチをスクラッチしてください。次のもののためのGoogle "wpfゲームループ"。 –

+0

これは、各自のスレッドを持つ各タイマーと関係があると思いますか? –

+0

私はゲームのループをチェックアウトしました - それは私が望むように動作しません。ゲームは以前よりもさらに遅くなります。時間の異なるタイマーがあれば助けてくれますか?そうでない場合は、上記の作業が必要です。私は常にスレッドを少なくするためにいくつかのタイマーを切ることができます。 –

答えて

0

最後に、私はいくつかのタイマーをオフにして、 ArrowFallのメソッドとそれらをすべて1つに入れます。それまでに、ディスパッチャは少ないタイマーで作業し、エラーは発生しませんでした。私は最初に問題の原因を正確には分からないので、何とか解決したと思います。

関連する問題