Game::update, который передает Player::getPosition() в эту функцию
sf::Vector2f enemyLocation{0.f, 0.f};
начальное значение врагаLocation для отладки
///
/// gets the amount enemy should move
/// called from Game.update()
///
///
player window position
/// enemy move amount per frame (normalised)
sf::Vector2f Enemy::attemptMove(sf::Vector2f t_playerPos)
{
sf::Vector2f movement = { 0.f, 0.f }; // movement towards player each frame
sf::Vector2f direction = t_playerPos - enemyLocation; // delta playerPos and enemyPos
float angle = atan2f(direction.y, direction.x); // angle to player (rad)
angle = angle * 180.f / M_PI; // convert angle to degrees
float hyp = 1.f; // length of line to player (used for normalisation of vector)
// check if enemy is horizontally in line with player
if (direction.x == 0.f) {
if (direction.y > 0.f) { movement.y = hyp; } // move straight down
else { movement = -hyp; } // move straight up
}
// check if enemy is vertically in line with player
else if (direction.y == 0.f) {
if (direction.x > 0.f) { movement.x = hyp; } // move right
else { movement.x = -hyp; } // move left
}
// if enemy is not in line with player
else {
// ratio of sides y:x = opp:adj
movement.y = sinf(angle);
movement.x = cosf(angle);
// normalising the vector
hyp = sqrtf(abs(movement.x * movement.x) + abs(movement.y * movement.y));
hyp = abs(1.f / hyp); // inverse of pythagoras theorem hypothenuse
movement.x = hyp * movement.x;
movement.y = hyp * movement.y; // sqrt(x^2 + y^2) should equal 1
move(movement);
}
return movement; // return to Game::update() (not currently assigned to anything there)
}
///
/// moves the enemy by the amount it should each frame
/// in final code will be called from Game.update()
/// for now only called from Enemy::attemptMove()
///
/// amount to move each frame towards player
void Enemy::move(sf::Vector2f t_movement)
{
enemyLocation += t_movement; // update enemy location
enemySprite.setPosition(enemyLocation); // set enemy position to updated location
}
мои включения
#include
#include
#define _USE_MATH_DEFINES
#include
Я ожидаю, что враг будет двигаться по прямой к игроку, что и происходит, если игрок неподвижен.
Если игрок движется по диагонали от врага, это также работает , но если игрок движется в любом другом направлении, враг вращается по кругу (иногда по спирали), пока игрок не перестанет двигаться или не начнет двигаться по диагонали от врага, а иногда и не начнет двигаться по прямой в совершенно неправильном направлении.
Я пробовал:
- присвоить tryMove() переменной в Game::update и передать ее в Enemy::move()
- включая углы альфа и бета и вычисляя отношения угла по правилу синуса
- включая контрольные точки для проверки правильности угла (кажется, так всегда)
- включая точки останова для проверки правильности угла (кажется, так всегда)
- li>
удаляем проверки на соответствие игроку и всегда выполняем расчет - меняем if (movement.x/y == 0.f) на if (abs(movement.x/y) < 0.01f) и
Подробнее здесь: https://stackoverflow.com/questions/782 ... working-wh