2016-09-15 3 views
1

私は追跡ゲームを作りたいです。ユーザーが手紙(手紙のパス)をたどると、私の円がその道をたどるようにしたい。ユーザーが戻って、私はパスをトレースすると、既に定義済みのパスに沿ってマウスフォロワのスムーズな動きを作成する方法は?

import flash.events.Event; 
    import flash.geom.Point; 

    var i: Number; 
    var size: int = 80; 
    var down: Boolean = false; 
    var up: Boolean = true; 
    var inside: Boolean = true; 
    var outside: Boolean = true; 
    var circle: Shape = new Shape(); 

    stage.addEventListener(Event.ENTER_FRAME, loop); 
    stage.addEventListener(MouseEvent.MOUSE_UP, mouseup); 
    char.addEventListener(MouseEvent.MOUSE_DOWN, mousedown); 

    function loop(e: Event) { 
if (down == true) { 
    // Checks if mouse pointer is on path i.e 'S' alphabet 
    if (s.hitTestPoint(stage.mouseX, stage.mouseY, true)) { 
     inside = true; 
     outside = true; 

     var point: Point = maskobj.globalToLocal(new Point(stage.mouseX, stage.mouseY)); 
     var point2: Point = new Point(); 

     //Checks if mouse pointer is completely outside of drawn area 
     for (i = 0; i < 2 * Math.PI; i += (2 * Math.PI)/10) { 
      point2.x = stage.mouseX + (size/3) * Math.cos(i); 
      point2.y = stage.mouseY + (size/3) * Math.sin(i); 
      if ((maskobj.hitTestPoint(point2.x, point2.y, true))) { 
       outside = false; 
       break; 
      } 
     } 

     //Checks if mouse pointer is completely inside drawn area 
     for (i = 0; i < 2 * Math.PI; i += (2 * Math.PI)/10) { 
      point2.x = stage.mouseX + (size/3) * Math.cos(i); 
      point2.y = stage.mouseY + (size/3) * Math.sin(i); 

      if (!(maskobj.hitTestPoint(point2.x, point2.y, true))) { 
       inside = false; 
       break; 
      } 
     } 

     //Character will be moved only if mouse position not to far from current position 
     if (outside == false) { 
      if (inside == false) { 
       //Increases drawn area by drawing a circle shape in 'maskobj' MovieClip 

       circle.graphics.beginFill(0x0000ff); 
       circle.graphics.drawCircle(point.x, point.y, size); 
       circle.graphics.endFill(); 
       maskobj.addChild(circle); 

       //Moves character to new position 
       char.x = stage.mouseX; 
       char.y = stage.mouseY; 
      } 
     } 
    } 
} 
    } 

    function mouseup(e: MouseEvent): void { 
up = true; 
down = false; 
    } 

    function mousedown(e: MouseEvent): void { 
down = true; 
up = false; 
    } 

enter image description here enter image description here

をトレースしているエリアに行くことができない、動きがスムーズではありません。誰かが動きをスムーズにする方法を提案しても、それを達成する別の方法を提案することはできますか?前もって感謝します。

+0

私がそれをよく理解していれば、赤い円が何らかの形で振動して滑らかではないという問題があります。パス上のドット数をトゥイーンに設定することができます。振動が少なくなるはずです。それがうまくいかない場合は、より良い方法でそれを解決する必要があります。 – HITMAN

+0

それがうまくいかない場合は、おそらくドット間の滑らかな方法を使用する数学を使用する必要があります。ペンツールのように。 – HITMAN

答えて

-1

は、ユーザーがパスを描画することができ前に、あなたは現在 修正>ドキュメント...>フレームレート

1

を持っているもの、私は抽選ゲームを作成した少なくとも二重に文書でFPSを増やしてみてください。

Wickedの答えがダウン投票された理由はわかりません。最初にする必要があるのは、離れていくことができる最も高いフレームレートを使用することです。フレームレートが高いほど、カーブはスムーズになります。

条件が満たされていれば、コードは現在の位置に円を描くことがわかります。最後のpoint.x/point.yから単なる円ではなく現在の線に線を引いて、あなたのパスに穴がないようにする方が良いかもしれません。

私が描いていたようにラインがギザギザしていたという事実を回避することはできませんでしたが、ユーザが指を離すとすぐに、ラインに沿ってポイントを取ることができました描画して、スムーズなベジエパス(一連の単純なベジエ曲線)に置き換え、うまくいきました。あなたは3点を持っていればオンザフライでこれを行うこともできます(曲線を描くには3点が必要です)。

Here is a good reference理論とコードサンプルを使用してこれを達成する方法について説明します。ベジェパスについては、ページの下部を参照してください。 AS3に変換する必要がありますが、それは難しいことではありません。

もう1つのヒントは、ENTER_FRAME内でできるだけ少ない計算を行うことです。これらは定数であるため、ループ(2 * Math.PI)と((2 * Math.PI)/ 10)で使用される2つの値を事前に計算できます。関数の先頭で(size/3)を1回計算し、特にMath.sin(i)とMath.cos(i)の10個の値をあらかじめ計算してArray(基本的にはLUT-ルックアップテーブル)は、あなたがやっている最も重大な数学操作です。

私の最後のヒントは、描画されているポイントが描画された最後のポイントに非常に近いかどうかをチェックしないことです。私はあなたがこれを行うことをお勧めし、マウスが最小距離(例えば2ピクセル)移動した後にポイントを描くだけです。さもなければ、あなたはマウスを1つの場所に座らせ、あなたのコードは円の上に不必要に上に円を描いています。

+0

あなたはこれがパフォーマンス上の問題だと思いますか?これがパフォーマンス上の問題であることをプロファイラーで確認しましたか?ルックアップテーブルを使用すると動きが滑らかになります。 – null

+0

私の答えの主な部分はパフォーマンスに関連していません(点を線に変換し、直線を曲線に変換することに関する)。パフォーマンスを向上させるためのヒントがいくつかありますが、パフォーマンスの向上とスムーズなラインの実現に役立ちます。 – Projectitis

関連する問題