【问题标题】:Sprite walking and background moving too: XNA精灵行走和背景移动:XNA
【发布时间】:2014-04-15 20:35:49
【问题描述】:

我想在 XNA 中做一个简单的事情,当角色向右移动时背景会移动。

有什么办法吗?

谢谢

【问题讨论】:

  • 当你将角色移动到背景的右增量 x 时...背景会移动
  • 但在这种情况下,角色将始终处于同一位置。
  • 然后从你的背景 X 中减去一个值,让它向左移动。更好的是,如果你让它的行为与你的玩家的 X 方向相反,那么向左移动也可以! amountOfPlayerMovement * -1 * backgroundMoveSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

标签: xna xna-4.0


【解决方案1】:

我想你的意思是像游戏里的马里奥! 使用滚动。

创建游戏类。 按照绘制 Sprite 的过程中所述加载资源。 加载背景纹理。

private ScrollingBackground myBackground;

protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);
    myBackground = new ScrollingBackground();
    Texture2D background = Content.Load<Texture2D>("starfield");
    myBackground.Load(GraphicsDevice, background);
}

确定背景纹理的大小和屏幕的大小。

纹理大小由 Height 和 Width 属性决定,屏幕大小由图形设备上的 Viewport 属性决定。

使用纹理和屏幕信息,将纹理的原点设置为纹理上边缘的中心,并将初始屏幕位置设置为屏幕中心。

// class ScrollingBackground
private Vector2 screenpos, origin, texturesize;
private Texture2D mytexture;
private int screenheight;
public void Load( GraphicsDevice device, Texture2D backgroundTexture )
{
    mytexture = backgroundTexture;
    screenheight = device.Viewport.Height;
    int screenwidth = device.Viewport.Width;
    // Set the origin so that we're drawing from the 
    // center of the top edge.
    origin = new Vector2( mytexture.Width / 2, 0 );
    // Set the screen position to the center of the screen.
    screenpos = new Vector2( screenwidth / 2, screenheight / 2 );
    // Offset to draw the second texture, when necessary.
    texturesize = new Vector2( 0, mytexture.Height );
}

要滚动背景,请在 Update 方法中更改背景纹理的屏幕位置。 此示例通过增加屏幕位置的 Y 值每秒将背景向下移动 100 像素。

protected override void Update(GameTime gameTime)
{
    ...
    // The time since Update was called last.
    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

    // TODO: Add your game logic here.
    myBackground.Update(elapsed * 100);

    base.Update(gameTime);
}

Y值保持不大于纹理高度,使背景从屏幕底部滚动回顶部。

public void Update( float deltaY )
{
    screenpos.Y += deltaY;
    screenpos.Y = screenpos.Y % mytexture.Height;
}
// ScrollingBackground.Draw

使用在 LoadContent 和 Update 中计算的原点和屏幕位置绘制背景。

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin();
    myBackground.Draw(spriteBatch);
    spriteBatch.End();

    base.Draw(gameTime);
}

如果纹理没有覆盖屏幕,则会绘制另一个纹理。这会使用加载时创建的纹理大小向量从屏幕位置中减去纹理高度。这会产生循环的错觉。

public void Draw( SpriteBatch batch )
{
    // Draw the texture, if it is still onscreen.
    if (screenpos.Y < screenheight)
    {
        batch.Draw( mytexture, screenpos, null,
             Color.White, 0, origin, 1, SpriteEffects.None, 0f );
    }
    // Draw the texture a second time, behind the first,
    // to create the scrolling illusion.
    batch.Draw( mytexture, screenpos - texturesize, null,
         Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}

【讨论】: