在其他地方使用的唯一其他代码是 Player::getPosition(),它只是返回playerSprite.getPosition() 和 Game::update 将 Player::getPosition() 传递给此函数
sf::Vector2f enemyLocation{0.f, 0.f};
用于调试的敌人位置的起始值
///<summary>
/// gets the amount enemy should move
/// called from Game.update()
///</summary>
/// <param name="t_playerPos"> player window position </param>
/// <returns> enemy move amount per frame (normalised) </returns>
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)
}
///<summary>
/// 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()
///</summary>
///<param name="t_movement"> amount to move each frame towards player </param>
void Enemy::move(sf::Vector2f t_movement)
{
enemyLocation += t_movement; // update enemy location
enemySprite.setPosition(enemyLocation); // set enemy position to updated location
}
我的包括
#include <SFML/Graphics.hpp>
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
我预计敌人会沿直线向玩家移动,如果玩家静止不动,这种情况就会发生 如果玩家沿对角线远离敌人移动,这也有效,但如果玩家向任何其他方向移动,敌人会绕圈(有时是螺旋形)旋转,直到玩家停止移动或开始沿对角线远离敌人移动,或者有时移动沿着完全错误的方向走一条直线。 我试过了:
似乎没有任何效果,而且很多事情让问题变得更糟或更严重,我真的不知道还能做什么
编辑:下面是工作代码
void Enemy::attemptMove(sf::Vector2f t_playerPos)
{
sf::Vector2f direction = t_playerPos - enemyLocation; // playerPos-enemyPos (direction to player)
float hyp;
// normalising the vector
hyp = sqrtf(abs(direction.x * direction.x) + abs(direction.y * direction.y));
hyp = abs(1.f / hyp); // inverse of pythagoras theorem hypothenuse
direction.x = hyp * direction.x;
direction.y = hyp * direction.y; // sqrt(x^2 + y^2) should equal 1
move(direction);
}
void Enemy::move(sf::Vector2f t_movement)
{
enemyLocation += t_movement; // update enemy location
enemySprite.setPosition(enemyLocation); // set enemy position to updated location
}
再次感谢用户@trojanfoe,他说 “你想太多了。要以给定的速度将
A
移向B
,你只需要做auto dir = normalize(B - A); A += dir * (speed * deltaTime);
”
下面是我修改后的代码,以合并这个更简单的解决方案(此代码在其他地方已经有一个 deltaTime 函数,可以修复帧渲染之间的间隔。)
void Enemy::attemptMove(sf::Vector2f t_playerPos)
{
sf::Vector2f direction = t_playerPos - enemyLocation; // playerPos-enemyPos (direction to player)
float hyp;
// normalising the vector
hyp = sqrtf(abs(direction.x * direction.x) + abs(direction.y * direction.y));
hyp = abs(1.f / hyp); // inverse of pythagoras theorem hypothenuse
direction.x = hyp * direction.x;
direction.y = hyp * direction.y; // sqrt(x^2 + y^2) should equal 1
move(direction);
}
void Enemy::move(sf::Vector2f t_movement)
{
enemyLocation += t_movement; // update enemy location
enemySprite.setPosition(enemyLocation); // set enemy position to updated location
}