2013-11-04 72 views
0

使用Tululoo Game Maker API編程遊戲時,我準確計算碰撞時存在問題,因爲x和y是從弧度計算出來的。使用Radians遞增來計算碰撞

以下x和y的計算產生大量的小數點,我發現難以檢查碰撞。

image_angle是最初使用子彈的手槍的最終角度。

在設置:

x = instance_list(pistol)[0].x; 
y = instance_list(pistol)[0].y; 
startAng = instance_list(pistol)[0].image_angle; 

this.travelX = cos(degtorad(instance_list(pistol)[0].image_angle)) * 5; 
this.travelY = sin(degtorad(instance_list(pistol)[0].image_angle)) * 5; 

在更新幀:

x+=this.travelX; 
y+=this.travelY; 

計算角度,球會在反彈的牆壁,凌亂的我知道:

for(var i = 0; i < instance_number(bounce_barrier);i++){ 

    if(place_meeting(x,y,instance_list(bounce_barrier)[i])){ 

      if(Math.round(x*10)/10 > instance_list(bounce_barrier)[i].x){ 
       newAng = 180 - startAng; 
       this.travelX = +cos(degtorad(newAng)) * 15; 
       this.travelY = +sin(degtorad(newAng)) * 15; 
       startAng = newAng; 
      } 

      else if(y > instance_list(bounce_barrier)[i].y - 5 && y <= instance_list(bounce_barrier)[i].y + 10){ 

       newAng = 180 - startAng; 
       this.travelX = -cos(degtorad(newAng)) * 15; 
       this.travelY = -sin(degtorad(newAng)) * 15; 
       startAng = newAng; 
      } 

      else if(y <= instance_list(bounce_barrier)[i].y - 5 + bounce_spr.height && y >= instance_list(bounce_barrier)[i].y + bounce_spr.height - 10){ 

       newAng = 180 - startAng; 
       this.travelX = -cos(degtorad(newAng)) * 15; 
       this.travelY = -sin(degtorad(newAng)) * 15; 
       startAng = newAng; 
      } 

      else if(x < instance_list(bounce_barrier)[i].x){ 

       newAng = 180 - startAng; 
       this.travelX = +cos(degtorad(newAng)) * 15; 
       this.travelY = +sin(degtorad(newAng)) * 15; 
       startAng = newAng; 
      } 
        else{} 

    } 

} 

place_meeting是Tululoo Game API的一部分:

function __place_meeting__(nx, ny, what, many) { 
     this.other = null; 
     var i, l, 
      // sprite, scale: 
      ts = this.sprite_index, 
      tsx, tsy, tfx, tfy, tst, 
      // circle: 
      tcx, tcy, tcr, 
      // bbox: 
      tbl, tbr, tbt, tbb, 
      // instances, multiple, output, types: 
      tz, tm, ct, ch, ra, 
      // other: 
      o, ox, oy, os, ost, osx, osy, ofx, ofy, ofr; 
     if (ts == null) return false; 
     tfx = ts.xoffset; 
     tfy = ts.yoffset; 
     tsx = this.image_xscale; 
     tsy = this.image_yscale; 
     tst = ts.collision_shape; 
     // bbox: 
     if (tst == 2) { 
      tbl = nx + tsx * (ts.collision_left - tfx); 
      tbr = nx + tsx * (ts.collision_right - tfx); 
      tbt = ny + tsy * (ts.collision_top - tfy); 
      tbb = ny + tsy * (ts.collision_bottom - tfy); 
     } 
     // circle: 
     if (tst == 3) { 
      tcr = ts.collision_radius * (tsx > tsy ? tsx : tsy); 
      tcx = nx + tsx * (ts.width/2 - tfx); 
      tcy = ny + tsy * (ts.height/2 - tfy); 
     } 
     // 
     tz = (what.__instance ? [what] : instance_list(what)); 
     tm = many ? true : false; 
     if (tm) ra = []; 
     l = tz.length; 
     for (i = 0; i < l; i++) { 
      o = tz[i]; 
      if (!o.collision_checking) continue; 
      os = o.sprite_index; 
      if (os == null) continue; 
      ox = o.x; osx = o.image_xscale; 
      oy = o.y; osy = o.image_yscale; 
      ost = os.collision_shape; 
      ct = (tst << 4) | ost; 
      ch = false; 
      switch(ct) { 
      case 0x22: 
       if (osx == 1 && osy == 1) { 
        ofx = os.xoffset; ofy = os.yoffset; 
        if (!collide_bbox_bbox(tbl, tbt, tbr, tbb, 
        ox + os.collision_left - ofx, oy + os.collision_top - ofy, 
        ox + os.collision_right - ofx, oy + os.collision_bottom - ofy)) break; 
       } else if (!collide_bbox_sbox(tbl, tbt, tbr, tbb, ox, oy, osx, osy, os)) break; 
       ch = true; 
       break; 
      case 0x23: 
       ofr = os.collision_radius * (osx > osy ? osx : osy); 
       ofx = ox + osx * (os.width/2 - os.xoffset); 
       ofy = oy + osy * (os.height/2 - os.yoffset); 
       if (!collide_bbox_circle(tbl, tbt, tbr, tbb, ofx, ofy, ofr)) break; 
       ch = true; 
       break; 
      case 0x32: 
       if (osx == 1 && osy == 1) { 
        ofx = os.xoffset; ofy = os.yoffset; 
        if (!collide_bbox_circle(
        ox + os.collision_left - ofx, oy + os.collision_top - ofy, 
        ox + os.collision_right - ofx, oy + os.collision_bottom - ofy, 
        tcx, tcy, tcr)) break; 
       } else if (!collide_sbox_circle(ox, oy, osx, osy, os, tcx, tcy, tcr)) break; 
       ch = true; 
       break; 
      case 0x33: 
       ofr = os.collision_radius * (osx > osy ? osx : osy); 
       ofx = ox + osx * (os.width/2 - os.xoffset); 
       ofy = oy + osy * (os.height/2 - os.yoffset); 
       if (!collide_circle_circle(tcx, tcy, tcr, ofx, ofy, ofr)) break; 
       ch = true; 
       break; 
      } if (!ch) continue; 
      this.other = o; 
      o.other = this; 
      if (!tm) return (o); 
      ra.push(o); 
     } return ra; 
    } 

我已經設法讓一顆子彈彈出一個與它被射出的角度成正比的角度,但碰撞檢測非常糟糕,因爲它會彈出一些子彈但不是全部,有些只是直接穿過壁。

剛剛添加的行碰撞檢測,香港專業教育學院發子彈線,所以我可以看到

this.oldTravelX,this.oldTravelY到this.travelX,this.travelY。它已經明顯改善,但一些子彈仍在經歷。

有些子彈似乎粘在彈跳塊內,或向下滑動彈跳塊的左側,然後決定是向左還是向右。

Added Line Collision Detection

更新的代碼:

​​

在此先感謝。

+0

我們需要更多的信息,比如'image_angle'是什麼,或者您的遊戲循環中存在'travelX'計算的位置。 – Dai

+0

感謝您的回覆,增加了一些更多的細節希望有所幫助。問候 – user997101

+0

看來'place_meeting'負責確定是否發生了碰撞,所以你的問題可能應該包括/專注於該函數中的代碼。 – Dave

回答

1

它看起來像place_meeting函數應該確定是否有子彈和障礙之間的碰撞。但是,這個函數只是採用子彈的新位置。鑑於子彈每次更新移動5個單位,子彈可能會在一個框架內從障礙物的一側移動到另一側。例如:

 | 
    . | 
    \| barrier 
    \ 
    |\_______ 
     \ 
     . 

place_meeting應該採取兩個子彈的舊的和新的位置,使得其能夠確定任何中間位置是否與阻擋(例如,通過幹交線測試與子彈的路徑和碰撞障礙物的邊緣;它應該也可能返回碰撞點)。


編輯

你更新的代碼看起來像它的目的是檢查一些沿着子彈的路徑點的碰撞。有更快的方法來做到這一點,但你的方法可能足夠快,並且很容易理解。在你如何計算要檢查的點上似乎存在一個錯誤。

手動逐步通過代碼在紙上:

pntdis = 5 // assume point_distance returns 5 
noPoints = 5/0.01 = 500 
i = 0 
pointsArrX[0] = this.travelX 
pointsArrY[0] = this.travelY 
i = i + noPoints = 500 
500 < 5: false, for loop ends 

其他的事情要考慮:

  • 你可能需要一個break聲明你已經檢測到碰撞後,所以不要將你的測試進一步點。
  • 您可以將兩個for循環組合爲一個,因爲您不重複使用數組中的值。只需計算您的測試點,然後立即進行測試。
  • 嘗試使用console.log在程序運行時輸出調試信息,以便您可以更好地瞭解發生了什麼。
  • 在變量之前使用var(例如pntdisnoPoints)以避免意外創建全局變量。
+0

剛剛添加了線碰撞檢測,它已經明顯改善,但一些子彈仍在經歷。 有些子彈似乎粘在彈跳塊內或沿着彈跳塊的左側滑落,然後決定是向左還是向右,然後向那個方向飛去。我已經添加了一個圖像來說明。謝謝。 – user997101