1

我正在尝试创建一个效果,其中两个射弹将以给定的实体在给定的玩家偏移处射出。一个快速的实现是这样的;

sf::Vector2f offset = m_owner->GetSprite().getPosition();

offset.y -= 5;
createProjectile(offset, m_owner->GetSprite().getRotation());
offset.y += 10;
createProjectile(offset, m_owner->GetSprite().getRotation());

如果您的实体只想在 .x 轴上发射,这非常有效,但是一旦您旋转播放器,它就会中断,因为偏移量没有脱离播放器当前的旋转。

我尝试了很多实现,但似乎都没有奏效,而且由于我的数学非常糟糕,我自己无法解决。

void Weapon::createProjectile(const sf::Vector2f& position, float angle)
{
        m_owner->_state->addEntity(new Projectile(m_owner, position, angle,*m_texture, m_velocity, m_damage));
}

Projectile::Projectile(Entity* emitter, const sf::Vector2f& position, float angle,
    const sf::Texture& image, int speed, int damage) :
    Entity(emitter->_state, true, entityName::entityBullet, speed)
{
        Load(_state->getApp()->gettextureManager().Get("Content/ball.png"));
    GetSprite().setRotation(angle);

        SetPosition(position.x,position.y);
        GetSprite().setScale(0.4f,0.4);
}

回答:

float rad;
offset = m_owner->GetSprite().getPosition();

rad = math::to_rad(m_owner->GetSprite().getRotation());

offset.x += 5*sin(rad);
offset.y += -5*cos(rad);

createProjectile(offset,m_owner->GetSprite().getRotation());

offset = m_owner->GetSprite().getPosition();

offset.x += -5*sin(rad);
offset.y += 5*cos(rad);

createProjectile(offset,m_owner->GetSprite().getRotation());
4

1 回答 1

2

The math you need to study up on is trigonometry. It is very useful!

If your character is rotated theta radians from "straight up" going clockwise, your top offset will be:

offset.x += 5*sin(theta);
offset.y += -5*cos(theta);

and the other will be

offset.x += -5*sin(theta);
offset.y += 5*cos(theta);

This is "circle math" (trigonometry) the 5 is the offset you speak of, also called the radius of the circle. A quick sanity check when doing this kind of math is to consider what will happen at 0 radians. Some quick facts of sin and cos:

sin(0) = 0
cos(0) = 1
sin'(0) = 1
cos'(0) = 0

(the second ones are derivatives: sin is initially increasing, cos is flat at the start. Check their graphs.) This and a bit more intuition is helpful for writing graphics code - if we consider the case when theta = 0 we get back your original code. One exception: you are getting the second offset relative to the first offset: I'd avoid doing that and instead make two copies of m_owner->GetSprite().getPosition(); or reset offset after creating the first projectile.

于 2013-04-11T15:04:55.603 回答