2016-11-27 11 views
0

Я разрабатываю игру и получаю много ее работы. Моя единственная проблема заключается в том, что мой текущий метод перемещения спрайта из одной точки в другую хорошо работает ... но направление несколько неточно. Это было бы не так уж плохо, если бы спрайт не «встал» на место в конце своего пути.Почему мое направление настолько неточно для моего нормализованного вектора?

Есть ли предложение кто-то может сделать либо а) Помогите улучшить точность моего направления б) Помогите сделать спрайт прийти на место более мягко

Вот мой код для вычисления движения от точки А к B:

if (!mMoving) { 
     mMoving = true; 
     mVecStart = new Vec(mPos.getX(),mPos.getY()); 
     mVecEnd = new Vec(target.getX(), target.getY()); 

     mDistanceToDestination = Vec.distanceBetween(mVecEnd, mVecStart); 

     mDirection = mVecStart.directionTo(mVecEnd, mDistanceToDestination); 

     mVelocityX = mDirection.mDX * mSpeed; 
     mVelocityY = mDirection.mDY * mSpeed; 
    } 


    if (mMoving == true) { 
     // Move along the x and y axis at given velocity, scaled by deltaTime. 
     this.mPos.x += mVelocityX * deltaTime; 
     this.mPos.y += mVelocityY * deltaTime; 

     // If the distance traveled exceeds the original distance computed, snap the sprite 
     // into place immediately. 
     if (mMoving && Vec.distanceBetween(mVecStart, new Vec(this.mPos.x, this.mPos.y)) 
       >= mDistanceToDestination) { 
      this.mPos.x = (int) target.getX(); 
      this.mPos.y = (int) target.getY(); 
      mMoving = false; 
      mMoveComplete = true; 
     } 
    } 

Вот как направление вычисляется:

public Vec directionTo(Vec vecEnd, double distance) { 

    return new Vec((vecEnd.mDX - this.mDX)/distance, 
      ((vecEnd.mDY - this.mDY)/distance)); 
} 
+1

Ваша функция направления не имеет для меня никакого смысла. Он должен иметь либо аргументы начала и конца точки, либо один вектор. Нормализация не должна проходить; он должен быть вычислен из самого вектора. Либо вектор ошибочен, либо величина неверна. Вы не показываете, что такое тестовый пример или ответ, который вы получаете. Оба помогут в выяснении того, что вы сделали неправильно. Отладчик сказал бы вам быстрее, чем спрашивать здесь. – duffymo

ответ

1

Вы вычислить т единичный вектор для данного вектора, делящий каждый компонент по его величине.

Вот как я бы вычислить величину плоского вектора в прямоугольной системе координат:

package vector; 

import java.awt.geom.Point2D; 

/** 
* Created by Michael 
* Creation date 11/26/2016. 
* @link 
*/ 
public class VectorUtils { 

    public static double magnitude(Point2D beg, Point2D end) { 
     double magnitude = 0.0; 
     if ((beg != null) && (end != null)) { 
      double dx = Math.abs(end.getX()-beg.getX()); 
      double dy = Math.abs(end.getY()-beg.getY()); 
      if ((dx == 0.0) && (dy == 0.0)) { 
       magnitude = 0.0; 
      } else { 
       if (dx > dy) { 
        double r = dy/dx; 
        magnitude = dx*Math.sqrt(1.0+r*r); 
       } else { 
        double r = dx/dy; 
        magnitude = dy*Math.sqrt(1.0+r*r); 
       } 
      } 
     } 
     return magnitude; 
    } 
} 

Вы должны научиться использовать JUnit для тестирования ваших классов. Вы потратите меньше времени на отладчик или поцарапаете голову над дефектами:

package vector; 

import org.junit.Assert; 
import org.junit.Test; 

import java.awt.geom.Point2D; 

/** 
* Created by Michael 
* Creation date 11/26/2016. 
* @link 
*/ 
public class VectorUtilsTest { 

    public static final double TOLERANCE = 1.0E-16; 

    @Test 
    public void testMagnitude_NullArguments() { 
     // setup 
     Point2D beg = null; 
     Point2D end = null; 
     // exercise and assert 
     Assert.assertEquals(0.0, VectorUtils.magnitude(beg, end), TOLERANCE); 
    } 

    @Test 
    public void testMagnitude_ZeroVector() { 
     // setup 
     Point2D beg = new Point2D.Double(0.0, 0.0); 
     Point2D end = new Point2D.Double(0.0, 0.0); 
     // exercise and assert 
     Assert.assertEquals(0.0, VectorUtils.magnitude(beg, end), TOLERANCE); 
    } 

    @Test 
    public void testMagnitude_UnitX() { 
     // setup 
     Point2D beg = new Point2D.Double(0.0, 0.0); 
     Point2D end = new Point2D.Double(2.0, 0.0); 
     // exercise and assert 
     Assert.assertEquals(2.0, VectorUtils.magnitude(beg, end), TOLERANCE); 
    } 

    @Test 
    public void testMagnitude_UnitY() { 
     // setup 
     Point2D beg = new Point2D.Double(0.0, 0.0); 
     Point2D end = new Point2D.Double(0.0, 2.0); 
     // exercise and assert 
     Assert.assertEquals(2.0, VectorUtils.magnitude(beg, end), TOLERANCE); 
    } 

    @Test 
    public void testMagnitude() { 
     // setup 
     Point2D beg = new Point2D.Double(0.0, 0.0); 
     Point2D end = new Point2D.Double(1.0, 1.0); 
     // exercise and assert 
     Assert.assertEquals(Math.sqrt(2.0), VectorUtils.magnitude(beg, end), TOLERANCE); 
    } 
} 
+0

Благодарим за урок по тестированию единицы, он мне тоже пригодится. И ха-ха для смелого профильного описания. –