0

私は非常に長い間この問題に悩まされてきました。たくさん検索して試してみましたが、何も機能しません。いくつかの説明は、私がプログラミング全体にかなり慣れていないため、理解するのが非常に難しく、学ぶことがたくさんあります。

2つの問題があります

1: 速度が速すぎると、ボールがブロックに衝突しないことがあります。

2: ボールはレンガ 2 個を打つことができます。両方の問題は、私のタイプの衝突検出が適切に機能するには 60 fps では不十分であるという事実に関連しています。

これが起こらないようにする衝突検出を行うために必要なことを、できるだけ簡単な方法で誰かに説明してもらいたいだけです。

これが私の現在の衝突コードです:

private function checkCollision(): void {
  grdx = Math.floor((ball.x) / 28);
  grdy = Math.floor((ball.y) / 14);
  ngrdx = Math.floor((ball.x + dx) / 28);
  ngrdy = Math.floor((ball.y + dy) / 14);
  var flipX: Boolean = false;
  var flipY: Boolean = false;
  if ((grdy <= level.length - 1) && 
      (ngrdy <= level.length - 1) && 
      (grdy >= 0 && ngrdy >= 0)) {
    if (testBlock(grdx, ngrdy)) {
      flipY = true;
      paddleFlag = 1;
    }
    if (testBlock(ngrdx, grdy)) {
      flipX = true;
      paddleFlag = 1;
    }
    if (testBlock(ngrdx, ngrdy)) {
      flipX = true;
      flipY = true;
      paddleFlag = 1;
    }
    dx *= flipX ? -1 : 1;
    dy *= flipY ? -1 : 1;
  }
}
private function testBlock(xPos: int, yPos: int): Boolean {
  if (level[yPos][xPos] > 0 && level[yPos][xPos] != 13) {
    trace("hit on X,Y");
    level[yPos][xPos] = 0;
    breakBlock("Block_" + yPos + "_" + xPos);
    trace("Block: " + totalBreaks + " / " + totalBlocks);
    return true;
  }
  return false;
}
private function breakBlock(blockName: String): void {
  if (this.getChildByName(blockName)) {
    this.removeChild(this.getChildByName(blockName));
    totalBreaks++;
  }
}

母国語ではない下手な英語で申し訳ありません。

4

2 に答える 2

1

1 つの解決策は、特定のフレーム内で複数回、より小さな反復でボールを移動することです。

たとえば、最後のフレームからの経過時間に基づいてボールを動かしていると仮定して、このソリューションを提供しています。

最後のフレーム更新から 30 ミリ秒が経過したとします。その場合、経過時間として 15 ミリ秒を使用して、そのフレームで動き/衝突を 2 回更新します。

必要な衝突の解像度が高いほど、反復回数が多くなります。

例を次に示します。

 // class declarations
 var lastFrame:Number;
 var iterationsPerFrame:int;

function startGame():void
{
     // lets specify 3 updates per frame
     iterationsPerFrame = 3;

     // save initial time
     lastFrame = getTimer();

     // create your listener
     addEventListener(Event.ENTER_FRAME, update);
}

function update(e:Event):void
{
     var currentFrame:Number = getTimer();
     var deltaTime:Number = (currentFrame - lastFrame)/1000;

     var iterationDelta:Number = deltaTime/iterationsPerFrame;

     for (var index:int = 0;index < iterationsPerFrame;index++)
     {
          // I'm assuming dx,dy are the velocity of the ball, in pixels per second
          ball.x += dx * iterationDelta;
          ball.y += dy * iterationDelta;
         // check collision
     }


     // set lastFrame to the currentFrame time, preparing for next frame
     lastFrame = currentFrame;

     // after this, your frame is going to render
}
于 2013-04-25T17:10:42.383 に答える
0

ボールが各フレームで移動する距離 ( )、ボールがパドルからどれだけ離れているか ( )、およびそのフレームで衝突を手動でトリガーする場合Aに基づいて計算できます。BA > B

基本的にすべてのレンガとボールと座標をチェックXYXいるYので、レンガが配列に格納されている場合、これは次のようになります。 Sqrt( Sqrd(p2.x - p1.x) + Sqrd(p2.y - p1.y) )

for(var i=0; i<brickArray.length; i++)
{
    var distance:Number = Math.sqrt((brickArray[i].x - ball.x) * (brickArray[i].x - ball.x) +
                                    (brickArray[i].y - ball.y) * (brickArray[i].y - ball.y));
}

これは、高速衝突検出に関する非常に優れたチュートリアルです: http://www.newgrounds.com/bbs/topic/1072673

于 2013-04-25T16:59:40.970 に答える