弹丸从错误的位置发射

Projectile fires from the wrong location

当我像这样按下 space 栏时我创建了射弹

if (keyboard.IsKeyDown(Keys.Space) && shoot)
{
    shoot = false;
    this.fire.Play(.2f, .9f, 0);
    lazerX = (float)(spritePosX);
    lazerY = (float)(spritePosY);

    Projectile projectile = new Projectile(heroLazer, "heroLazer",
        lazerX, lazerY, rotationAngle);

    Game1.AddProjectile(projectile);
}

然后在 Projectiles 中 class 新实例是这样创建的。

public Projectile(Texture2D lazerSprite, string spriteName,
    float posx, float posy, float heading)
{
    projectileSprite = lazerSprite;
    type = spriteName;
    spriteRotOrigin = new Vector2(projectileSprite.Width / 2, projectileSprite.Height / 2);
    spriteHeading = heading;
    spritePosX = posx; // the x position of the lazer
    spritePosY = posy; // the y position of the lazer

    spritePos = new Vector2(spritePosX, spritePosY);
    drawRectangle = new Rectangle((int)spritePosX, (int)spritePosY,
        projectileSprite.Width / 2, projectileSprite.Height / 2);

}

像这样更新

public void update(GameTime gameTime, KeyboardState keyboard)
{
    //projectile active or not?
    if (active == true)
    {
        projectileAge += gameTime.ElapsedGameTime.Milliseconds;

        spritePosX += (float)(Math.Sin(spriteHeading) *
            gameTime.ElapsedGameTime.TotalMilliseconds) * ProjectileMoveAmount;
        spritePosY -= (float)(Math.Cos(spriteHeading) *
            gameTime.ElapsedGameTime.TotalMilliseconds) * ProjectileMoveAmount;

        spritePos = new Vector2(spritePosX, spritePosY);
    }
    if (projectileAge > projectileLife)
    {
        active = false;
    }
}

并像这样绘制在屏幕上

public void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(projectileSprite, spritePos, null,
        Color.FromNonPremultiplied(255, 255, 255, 255), spriteHeading,
        spriteRotOrigin, 1.0f, SpriteEffects.None, 0f);

}

除了射弹从宇宙飞船的中心发射外,以上代码运行良好。

我无法捕捉到从 space 飞船中心发射炮弹的图像,但确实如此。我的代码有什么问题?我的三角函数比较弱,所以请温柔并提供一些细节。

据我了解,问题是你的抛射物的起始位置必须根据船精灵的大小和旋转来调整。

我不知道你的框架,所以我只能在概念上帮助你。例如,如果你的船的旋转为 0 且面向北方,则抛射物 X 必须为:

 shipSprite.X + (shipSprite.Width * 0.5f)

并且射弹 Y 必须是:

 shipSprite.Y

如果船朝西,弹丸X必须是:

 shipSprite.X

并且射弹 Y 必须是:

 shipSprite.Y + (shipSprite.Y * 0.5f)

等等...

(假设 spritePosX 和 spritePosY 给出船舶在船舶中心的位置,rotationAngle 为 弧度 ...)

您的代码在编辑前几乎正确:

lazerX = (float)(spritePosX - (0) * Math.Cos(rotationAngle));

只是 (0) 没有意义。船的size/2应该是这样的:

lazerX = (float)(spritePosX - (shipSize * 0.5f) * Math.Cos(rotationAngle));

(shipSize是飞船的高度,所以shipSize * 0.5f是半径=飞船中心到喷嘴的距离)

示例:

如果 "North" 是 0° 的角度,则 Cos(0) 是 1 => lazerX = shipCenterX - shipSize*0.5 * 1

对于 "East" : 90° Cos(PI/2) = 0 => lazerX = shipCenterX - shipSize*0.5 * 0

因此 lazerY:

lazerY = (float)(spritePosY + (shipSize * 0.5f) * Math.Sin(rotationAngle));

这还假设您的坐标系是:

+-----------------------------------------------> y
|
|
|                       ^  - Nozzle      ^ = 0°,  > = 90° , v = 180° , < = 270°
|                       X  - Ship Center
|
|
v

x

https://dotnetfiddle.net/32txfb

我感谢所有让我一路走来的人。下面几行简单的代码就完美解决了问题

            if (keyboard.IsKeyDown(Keys.Space) && shoot)
            {
                shoot = false;
                //is.fireInst.Play();
                this.fire.Play(.2f, .9f, 0);
                float newRotAngle = Game1.DegreesToRadians(rotationAngle);

                // the new code

                lazerX = spritePosX + (float)Math.Sin(rotationAngle) * HeroSprite.Width / 2;
                lazerY = spritePosY - (float)Math.Cos(rotationAngle) * HeroSprite.Height/2;

                Projectile projectile = new Projectile(heroLazer, "heroLazer",
                    lazerX, lazerY, rotationAngle);

                Game1.AddProjectile(projectile);
            }

写在头上:

x=player.x+cos(angle)*z;
y=player.y+sin(angle)*z;

其中 z 是从枪的中心到顶部的距离以及玩家已经拥有的角度。