弹丸从错误的位置发射

时间:2017-11-23 07:36:56

标签: c# monogame

当我像这样按空格键时,我创建了射弹

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类中,新实例就像这样创建。

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);

}

enter image description here

上述代码效果很好,除了射弹从太空中心发射。

我无法捕捉到一张显示从宇宙飞船中心发射射弹的图像,但确实如此。我的代码出了什么问题?我的三角函数相当弱,所以请保持温和并提供一些细节。

spaceship facing up and then rotated right 90deg.

4 个答案:

答案 0 :(得分:0)

根据我的理解,问题是你的射弹的起始位置必须通过船只精灵的大小和旋转来调整。

我不知道你的框架所以我只能帮助你理解这个概念。例如,如果您的船的旋转角度为0且朝北,则射弹X必须为:

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

并且抛射物Y必须是:

 shipSprite.Y

如果船朝西,则抛射物X必须是:

 shipSprite.X

并且抛射物Y必须是:

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

等等......

答案 1 :(得分:0)

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

编辑前的代码几乎正确:

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

只是(0)没有意义。这应该是船的尺寸/ 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

答案 2 :(得分:0)

我感谢那些把我带到路上的人。以下简单的代码行完美地解决了这个问题。

            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);
            }

答案 3 :(得分:0)

从头上写:

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

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