2D 타워 방어-적의 총알


14

총알이 적을 때릴 수있는 좋은 해결책을 찾으려고합니다. 게임은 2D 타워 방어이며, 타워는 총알을 쏘고 적을 보장해야합니다.

이 솔루션을 시도했습니다 -http : //blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

총알의 원점과 적도 빼기 위해 언급 된 링크 (벡터 빼기) 나는 그것을 시도했지만 총알이 적 주위를 따라갑니다.

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

나는 벡터에 익숙하지만이 솔루션을 작동시키기 위해 어떤 단계 (벡터 수학 연산)를 수행 해야하는지 잘 모르겠습니다.


답변:


11

당신의 추론은 완벽했습니다 : 벡터를 사용하여 내 위치에서 목표로 이동하십시오. 이것이 벡터 의 목적입니다 . 당신은 단순히 속도 를 잊었다 !

속도는 속도와 방향의 벡터입니다. 그러나 차이 벡터를 정규화하는 것을 잊어 버린 경우 총알 속도 (스칼라)를 곱 하면 목표에 가까이 있으면 (차이 벡터가 작을 경우) 불릿이 느려집니다 . 멀리 있으면 총알 속도가 더 큽니다.

이것은 근본적인 문제 입니다. 벡터 의 방향 크기를 모두 계산해야합니다 .


도와 줘서 고맙다. 차이 벡터를 계산 한 후 스칼라를 사용하려고 시도했지만 제대로 작동하지만 보이지 않습니다. 차이 벡터를 계산하고 정규화 한 다음 속도를 스칼라하는지 확인하려고했습니다. 지금은 더 좋아 보인다. 네, 나중에이 게임에서 귀환 미사일이 필요하다고 생각합니다. 다시 감사합니다.
Tashu

1
이 답변은 다른 사람에게는 이해가되지 않습니까?
BlueRaja-대니 Pflughoeft

@ Fxlll : 좋아, 나는 당신이 말하려는 것을 본 것 같아요. 시작 / 끝의 대답과 관련이없는 많은 보풀이 있으며, 나는 또한 당신의 영어에 혼란 스러웠습니다 (아마도 당신의 잘못이 아니라는 것을 알고 있습니다) . 이 답변을 정리하기 위해 수정 제안을 제출했습니다.
BlueRaja-대니 Pflughoeft

@BlueRaja-Danny Pflughoeft의 노력에 감사드립니다!
FxIII

7

대상이 일정한 속도로 꾸준한 방향으로 움직이고 총알 경로가 일정한 속도로 직선 인 경우 2 차 방정식을 사용하여 그들이 교차하는 정확한 지점을 예측하고 타워의 총을 해당 지점에 조준 할 수 있습니다 .

총알이 자국에 닿는 것이 확실하기 때문에 발사에서 충격을받는 데 걸리는 정확한 시간을 계산할 수 있으므로 충돌 감지가 필요하지 않으며 단순히 총을 발사하고 계산 된 시간 범위를 기다린 후 적중을 등록하십시오.

다음은 이차 방정식에 대한 의사 코드입니다.

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

의사 코드에 감사드립니다.이 상황에서 2 차 방정식이 어떻게 작동하는지 확인합니다. 다시 감사합니다.
Tashu

문제는 사용자가 총알을 향해 움직일 수 있고 타격 직전에 총알의 흔적에서 벗어날 수 있다는 것입니다. 이 경우이 솔루션이 충분할까요?
마틴.

아니요, 첫 번째 문장에서 자격이 부여되었습니다. 이것은 모든 게임이 아니라 목표가 일정한 속도로만 움직이는 게임을위한 것입니다. 등속은 방향과 속도를 모두 의미합니다. 예를 들어 Defense Grid 스타일의 게임 게임에서이 방법을 사용할 수 있습니다.
Steve H

3

총알이 도달 할 때까지 객체 위치를 '예측'해야합니다. 객체 속도 / 속도 (바람직하게는 일정합니다.)와 방향 벡터를 사용 하여이 작업을 수행 할 수 있습니다.

정확한 공식이 내 머리 꼭대기에 있는지 확실하지 않지만 다음과 같이 생각합니다.

NewPosition = OldPosition + (속도 * 방향 벡터);

경로가 설정되어 있으면 객체의 방향이 바뀔 때 다시 계산해야합니다. 이 NewPosition을 적이 위치 벡터로 사용하면 총알이 '호밍 효과'없이 오브젝트에 부딪치게됩니다. 원점 복귀는 원래 벡터가 계산 된 이후로 적의 물체가 움직 였기 때문에 발생하며, 물체가 한 방향으로 충분히 이동할 때만 따라 잡을 수 있습니다.

도움이 되었기를 바랍니다 :)


3
또는 속임수와 자동 타격을 수행 한 다음 움직이는 스프라이트를 시각적 피드백으로 사용할 수 있습니다. 또는 50000²mph로 총알을 발사하십시오.
Jonathan Connell

1

제곱근과 2의 거듭 제곱을 사용하지 않아도됩니다.

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

모두 메모리에서 작성되었습니다. 그건 그렇고, 작동하는 요소를 사용하십시오-처음 접하는 경우 한 줄씩 테스트하십시오. Float는 AS3에서 숫자입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.