2011-12-23 3 views
2

나는 여기에 비슷한 질문을 여러 번 읽었지만, 불행히도 그 중 아무도 정확한 답을주지 못하는 것 같아요. 아니면 수학이 저를 넘어 설 수도 있습니다!AS3으로 마우스 x, y에 호에서 발사체를 이동하는 방법은 무엇입니까?

화면의 왼쪽 가장자리에 대포가있는 게임을 만들고 있습니다. 대포에서 대포를 발사하여 원위치에서 마우스 포인터가 화면 위를 가로 지르는 것을 원합니다.

나는 지점에서 B 지점으로 호에 발사체를 이동,하지만 내가 필요로하는 대포 자체의 축을 따라 첫 번째 이동에 가로 질러위한 몇 가지 예를 본 적이 그것을 볼 경우 더 좋은 없습니다 대포가 가리키는 다른 각도에서 대포의 끝을 남긴다.

볼에 작용하는 힘은 중력이며 시작 속도입니다.

또한 문제가 복잡해지기 때문에 마우스 포인터가 대포 끝에서 얼마나 멀리 떨어져 있는지에 따라 대포 각도를 변경해야합니다. 포인터가 대포보다 멀리 있으면 대각선을 향하여 위쪽으로 향하게됩니다. 45도이지만 포인터가 대포의 끝과 매우 가까운 경우 대포는 포인터를 직접 가리키고 있습니다.이 숫자는 이미 거리를 구해서 번호로 나눔으로써 더 많거나 적게 이미 작동합니다. 그리고 그것을 대포의 회전 값에서 뺀 것이지만 약간의 거친 방법입니다. 나는 아래의 스크린 샷에서 라인 관리했습니다 아래

편집 코드를 사용. 당신이 내가 필요로하는 궤적이 아니다 볼 수 있습니다하지만, 난에 입력 한 빨간 선처럼 뭔가 더 필요합니다. 여기

line

와 나는 (아마 잘못)

코드를 구현 한 방법 마우스를 이동할 수 있도록
public class GameTurretLine2 
    { 
     var rt:Object = null; 
     var lineMc:MovieClip = new MovieClip(); 

     var myTurret:GameMainGun = null; 

     var pta:Point = new Point(0,0); 
     var ptb:Point = new Point(0,0); 
     var ptc:Point = new Point(0,0); 
     var ptd:Point = new Point(0,0); 

     public function GameTurretLine2(rt2,turret) 
     { 
      rt = rt2; 
      myTurret = turret; 

      lineMc.graphics.lineStyle(2, 0x55aa00); 

      mainLoop(); 

      rt.rt.GameLayers.turretLineMc.addChild(lineMc); 

     } 
     function mainLoop() 
     { 

      lineMc.graphics.clear(); 

      //get points 
      var turretEnd:Object = myTurret.rt.Useful.localToGlobalXY(myTurret.mC.turret.firePoint); 
      var turretStart:Object = myTurret.rt.Useful.localToGlobalXY(myTurret.mC.turret); 
      var mousePos:Point = new Point(myTurret.rt.rt.mouseX,myTurret.rt.rt.mouseY); 
      var inbetween:Point = new Point(0,0); 

      //start 
      pta.x = turretStart.newX; 
      pta.y = turretStart.newY; 

      //mouse end 
      ptd.x = mousePos.x; 
      ptd.y = mousePos.y; 

      // The cannon's angle: 
      // make the cannon's angle some inverse factor 
      // of the distance between the mouse and cannon tip 

      var dist:Number = myTurret.rt.Useful.getDistance(turretEnd.newX, turretEnd.newY, mousePos.x, mousePos.y); 
      var cAng:Number = dist * (180/Math.PI); 

      var ptbc:Point = new Point((ptd.x - pta.x) *.5,0); 
      ptbc.y = Math.tan(cAng) * ptbc.x; 

      //ptb = new Point(ptbc.x - ptbc.x * .15, ptbc.y); 
      ptb = new Point(turretEnd.newX, turretEnd.newY); 
      ptc = new Point(ptbc.x + ptbc.x * .5, ptbc.y); 

      // create the Bezier: 
      var bz:BezierSegment = new BezierSegment(pta,ptb,ptc,ptd); 
      trace(bz); 

      // define the distance between points that you want to draw 
      // has to be between 0 and 1. 
      var stepVal:Number = .1; 
      var curPt:Point = pta; 

      //draw circles 

      lineMc.graphics.drawCircle(pta.x, pta.y, 4); 
      lineMc.graphics.drawCircle(ptb.x, ptb.y, 4); 
      lineMc.graphics.drawCircle(ptc.x, ptc.y, 4); 
      lineMc.graphics.drawCircle(ptd.x, ptd.y, 4); 

      lineMc.graphics.lineStyle(2, 0x0000ff); 

      //step along the curve to draw it 
      for(var t:Number = 0;t < 1;t+=stepVal){ 
       lineMc.graphics.moveTo(curPt.x, curPt.y); 
       curPt = bz.getValue(t); 
       trace("curPt = " + curPt.x + "," + curPt.y); 
       lineMc.graphics.lineTo(curPt.x, curPt.y); 
      } 

      trace("pta = " + pta.x + "," + pta.y); 
      trace("ptb = " + ptb.x + "," + ptb.y); 
      trace("ptc = " + ptc.x + "," + ptc.y); 
      trace("ptd = " + ptd.x + "," + ptd.y); 


     } 
    } 

또한 어떤 이상한 이유로, 코드에 의해 생성 된 라인은 들여 쓰기 코드로 스크린 샷에 얼마나에서, 플립, 단지 마우스를 작은 금액을 이동하여 (y를 넘김) 선은 도처에 뛰어 오른다.

답변

2

하나의 방법은 베 지어 곡선을 만드는 것입니다.

기본적으로 커브가 항상 일부 삼각형 아래에 들어 있기를 원하기 때문에이 방법은 실행 가능한 솔루션처럼 들립니다. 이 삼각형이 베 지어 곡선의 제어점을 정의하면 중력에 따라 포탄의 호를 아주 가깝게 만들 수 있습니다 (중력의 완벽한 표현은 아닙니다). 이 방법의 한 가지 부작용은 (반전 된) 높이가 포탄의 힘을 정의 할 수 있다는 것입니다.

fl.motion.BezierSegment을 사용하면 커브를 만들고 따라갈 수 있습니다. FLA에이 코드를 붙여 넣기 :이 코드를 실행하기 위해 MouseEvent 자신과 AdjustCannonEvent을 사용해야합니다 그래서있는 그대로,이 코드는 마우스에 직접 부착되지

import fl.motion.BezierSegment; 

var mySprite:Sprite = new Sprite(); 
addChild(mySprite); 
mySprite.graphics.lineStyle(2, 0x55aa00); 

// End point of the cannon: 
var pta:Point = new Point(0, 100); 
mySprite.graphics.drawCircle(pta.x, pta.y, 4); 
trace("pta = " + pta.x + "," + pta.y); 

// mouse point 
// var ptd:Point = new Point(mouseX, mouseY); 
// for testing: 
var ptd:Point = new Point(200,100); 
mySprite.graphics.drawCircle(ptd.x, ptd.y, 4); 
trace("ptd = " + ptd.x + "," + ptd.y); 

// The cannon's angle: 
// make the cannon's angle some inverse factor 
// of the distance between the mouse and cannon tip 
// var dx:Number = ptd.x-pta.x; 
// var dy:Number = ptd.y-pta.y; 
// var dist:Number = Math.sqrt(dx * dx + dy * dy); 
var cAng:Number = 30 * /(180/Math.PI); 

// point the cannon in the correct direction here, however you are intending to do that. 

// triangulate the cannon pt and mouse pt assuming the cannon's angle for both: 
// *** NOTE: for simplicity, this assumes a straight line on the x-plane. *** 
var ptbc:Point = new Point((ptd.x - pta.x) *.5,0); 
ptbc.y = Math.tan(cAng) * ptbc.x; 
trace("ptbc = " + ptbc.x + "," + ptbc.y); 

// to adjust the curve: 
var ptb:Point = new Point(ptbc.x - ptbc.x * .15, ptbc.y); 
var ptc:Point = new Point(ptbc.x + ptbc.x * .5, ptbc.y); 
mySprite.graphics.drawCircle(ptb.x, ptb.y, 4); 
mySprite.graphics.drawCircle(ptc.x, ptc.y, 4); 

// create the Bezier: 
var bz:BezierSegment = new BezierSegment(pta,ptb,ptc,ptd); 
trace(bz); 

// define the distance between points that you want to draw 
// has to be between 0 and 1. 
var stepVal:Number = .1; 
var curPt:Point = pta; 

mySprite.graphics.lineStyle(2, 0x0000ff); 

//step along the curve to draw it 
for(var t:Number = 0;t < 1;t+=stepVal){ 
    mySprite.graphics.moveTo(curPt.x, curPt.y); 
    curPt = bz.getValue(t); 
    trace("curPt = " + curPt.x + "," + curPt.y); 
    mySprite.graphics.lineTo(curPt.x, curPt.y); 
} 

mySprite.x = stage.stageWidth/2-mySprite.width/2; 
mySprite.y = stage.stageHeight/2-mySprite.height/2; 

. (코드의 메모를 확인하십시오.)

+0

도움을 주셔서 감사합니다. 이 비트를 이해하지 못합니다. var ptbc : Point = new Point ((ptd.x - pta.x) * .5,0); ptbc.y = Math.tan (cAng) * ptbc.x 당신은 직선이라고 가정하지만 마우스 포인터는 화면의 아무 곳에 나있을 수 있으므로, 최종 대포 점과 마우스 포인터 사이에는 각도가 없습니다. x ,와이? – Phil

+0

예.그러나 제 대답은 커브 배치와 커브 높이 조정에 대한 기본적인 아이디어를 제시하는 것이 었습니다. x-linear가 아닌 각도를 정의하는 것은 훨씬 더 복잡합니다. 거기에 몇 가지 일반적인 솔루션이 있다고 생각합니다. – iND

+0

또한 발사체는 대포의 회전 지점이 아닌 대포 끝에서 시작해야합니다. 대포를 돌려서 끝 부분을 선택하고 localToGlobal()을 사용하여 마우스를 사용 가능한 위치로 변환 할 수 있습니다. – iND

관련 문제