使数组动画化

本文关键字:动画 数组 | 更新日期: 2023-09-27 18:16:35

目前正在尝试为我使用XNA 4.0在c#中制作的游戏中的一组敌人精灵动画

使用动画代码

namespace Rotationgame
{
class Animation
{
    Texture2D texture;
    Rectangle rectangle;
    Vector2 position;
    Vector2 origin;
    Vector2 velocity;
    int currentFrame;
    int frameHeight;
    int frameWidth;
    float timer;
    float interval = 150;
    public Animation(Texture2D newTexture, Vector2 newPosition, int newFrameHeight, int newFrameWidth)
    {
        texture = newTexture;
        position = newPosition;
        frameHeight = newFrameHeight;
        frameWidth = newFrameWidth;
    }
    public void Update(GameTime gameTime)
    {
        rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
        origin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);
        position = position + velocity;
        if (Keyboard.GetState().IsKeyUp(Keys.F1))
        {
            AnimateRight(gameTime);
            velocity.X = 0;
        }
        else if (Keyboard.GetState().IsKeyUp(Keys.F2))
        {
            AnimateLeft(gameTime);
            velocity.X = -0;
        }
        else velocity = Vector2.Zero;
    }
    public void AnimateRight(GameTime gameTime)
    {
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
        if (timer > interval)
        {
            currentFrame++;
            timer = 0;
            if (currentFrame > 1)
                currentFrame = 0;
        }
    }
    public void AnimateLeft(GameTime gameTime)
    {
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
        if (timer > interval)
        {
            currentFrame++;
            timer = 0;
            if (currentFrame > 1)
                currentFrame = 0;
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, rectangle, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
    }
}
}

数组

的代码
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Animation[] invaders;

protected override void Initialize()
    {
       invaders = new Animation[13];
        // TODO: Add your initialization logic here
        base.Initialize();
    }
  protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

// Array of Space Invaders
        invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
        invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
        invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
        invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
        invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
        invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
        invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
        invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
        invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
        invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
        invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
        invaders[12] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);
     }
protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
// Drawing Invaders
                foreach (Animation invader in invaders)
                    invaders.Draw(spriteBatch);
}
        spriteBatch.End();

一切工作在visual Studio的代码,但我得到一个错误的绘制方法说:"错误1"系统。Array'不包含'Draw'的定义,也没有扩展方法'Draw'接受第一个类型为'System '的参数。Array'可以找到(您是否缺少using指令或程序集引用?)"

你知道哪里出错了吗?

编辑:这里是game1文件的完整代码

namespace Rotationgame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Animation[] invaders;
    // Different Windows
    enum GameState
    {
        MainMenu,
        Playing,
    }
    GameState CurrentGameState = GameState.MainMenu;
    // Screeb Adjustments
    int screenWidth = 1250, screenHeight = 930;
    // Main Menu Buttons
    button btnPlay;
    button btnQuit;
    // Pause Menu & buttons
    bool paused = false;
    button btnResume;
    button btnMainMenu;

    // Player's Movement
    Vector2 spriteVelocity;
    const float tangentialVelocity = 0f;
    float friction = 1f;
    Texture2D spriteTexture;
    Rectangle spriteRectangle;
    Vector2 spritePosition;
    float rotation;
    // The centre of the image
    Vector2 spriteOrigin;

    // Background
    Texture2D backgroundTexture;
    Rectangle backgroundRectangle;

    // Shield
    Texture2D shieldTexture;
    Rectangle shieldRectangle;
    // Bullets
    List<Bullets> bullets = new List<Bullets>();
    KeyboardState pastKey;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

    }
    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
       invaders = new Animation[12];
        // TODO: Add your initialization logic here
        base.Initialize();
    }
    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        // Load Player's Shield (Cosmetic at moment as not set up fully
        shieldTexture = Content.Load<Texture2D>("Shield");
        shieldRectangle = new Rectangle(517, 345, 250, 220);
        // Load Player's Ship
        spriteTexture = Content.Load<Texture2D>("PlayerShipright");
        spritePosition = new Vector2(640, 450);
        // Load Game background
        backgroundTexture = Content.Load<Texture2D>("Background");
        backgroundRectangle = new Rectangle(0, 0, 1250, 930);
        // Screen Adjustments
        graphics.PreferredBackBufferWidth = screenWidth;
        graphics.PreferredBackBufferHeight = screenHeight;
        graphics.ApplyChanges();
        IsMouseVisible = true;

        // Main menu Buttons & locations
        btnPlay = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
        btnPlay.setPosition(new Vector2(550, 310));
        btnQuit = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
        btnQuit.setPosition(new Vector2(550, 580));
        // Array of Space Invaders
        invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
        invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
        invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
        invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
        invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
        invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
        invaders[6] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
        invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
        invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
        invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
        invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
        invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);

        // Pause menu buttons & locations
        btnResume = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
        btnResume.setPosition(new Vector2(550, 310));
        btnMainMenu = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
        btnMainMenu.setPosition(new Vector2(550, 580));
        // TODO: use this.Content to load your game content here
    }
    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }
    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        MouseState mouse = Mouse.GetState();

        // Allows the game to exit
        if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();
        switch (CurrentGameState)
        {
            case GameState.MainMenu:
                if(btnPlay.isClicked == true) CurrentGameState = GameState.Playing;
                btnPlay.Update(mouse);
                if (btnQuit.isClicked == true)
                    this.Exit();
                    btnQuit.Update(mouse);
                  break;
            case GameState.Playing:
                  if (!paused)
                  {
                      if (Keyboard.GetState().IsKeyDown(Keys.Enter))
                      {
                          paused = true;
                          btnResume.isClicked = false;
                      }
                  }
                  else if (paused)
                  {
                      if (Keyboard.GetState().IsKeyDown(Keys.Enter))
                      if (btnResume.isClicked)
                          paused = false;
                      if (btnMainMenu.isClicked) CurrentGameState = GameState.MainMenu;
                  }

                break;

        }

        // TODO: Add your update logic here
        if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
            Shoot();
        pastKey = Keyboard.GetState();
        spritePosition = spriteVelocity + spritePosition;
        spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y,
            spriteTexture.Width, spriteTexture.Height);
        spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);
        if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f;
        if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f;
        if (Keyboard.GetState().IsKeyDown(Keys.Up))
        {
            spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
            spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
        }
        else if (Vector2.Zero != spriteVelocity)
        {
            float i = spriteVelocity.X;
            float j = spriteVelocity.Y;
            spriteVelocity.X = i -= friction * i;
            spriteVelocity.Y = j -= friction * j;

            base.Update(gameTime);
        }
        UpdateBullets();
    }
    public void UpdateBullets()
    {
        foreach (Bullets bullet in bullets)
        {
            bullet.position += bullet.velocity;
            if (Vector2.Distance(bullet.position, spritePosition) > 760)
                bullet.isVisible = false;
        }
        for (int i = 0; i < bullets.Count; i++)
        {
            if(!bullets[i].isVisible)
            {
                bullets.RemoveAt(i);
                i--;

            }

        }
    }
    public void Shoot()
    {
        Bullets newBullet = new Bullets(Content.Load<Texture2D>("bullet"));
        newBullet.velocity = new Vector2((float)Math.Cos(rotation),(float)Math.Sin(rotation)) * 3f + spriteVelocity;
        newBullet.position = spritePosition + newBullet.velocity * 5;
        newBullet.isVisible = true;
        if(bullets.Count() < 25)
            bullets.Add(newBullet);
    }

    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        switch (CurrentGameState)
        {
            case GameState.MainMenu:
                spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
                btnPlay.Draw(spriteBatch);
                btnQuit.Draw(spriteBatch);
                break;
            case GameState.Playing:
                // Drawing Background
                spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White);
                // Drawing Shield
                spriteBatch.Draw(shieldTexture, shieldRectangle, Color.White);
                // Drawing Invaders
                foreach (Animation invader in invaders)
                    invader.Draw(spriteBatch);
                // Drawing Bullets
                foreach (Bullets bullet in bullets)
                    bullet.Draw(spriteBatch);
                // Drawing Player's Character
                spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0);

                if (paused)
                {
                    spriteBatch.Draw(Content.Load<Texture2D>("PauseMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
                    btnResume.Draw(spriteBatch);
                    btnMainMenu.Draw(spriteBatch);
                }
                break;



        }
        spriteBatch.End();

        // TODO: Add your drawing code here
        base.Draw(gameTime);
    }
}
}

第二次编辑:按钮类

namespace Rotationgame
{
class button
{
    Texture2D texture;
    Vector2 position;
    Rectangle rectangle;
    Color colour = new Color(255, 255, 255, 255);
    public Vector2 size;
    public button(Texture2D newTexture, GraphicsDevice graphics)
    {
        texture = newTexture;
        // ScreenW = 1250 (currently atm 800), ScreenH = 930 (currently atm 600)
        //ImgW =     100 , ImgH = 20
        size = new Vector2(graphics.Viewport.Width / 8, graphics.Viewport.Height / 30);
    }
    bool down;
    public bool isClicked;
    public void Update(MouseState mouse)
    {
        rectangle = new Rectangle((int)position.X,(int)position.Y,
            (int)size.X, (int)size.Y);
            Rectangle mouseRectangle = new Rectangle(mouse.X, mouse.Y, 1, 1);
        if (mouseRectangle.Intersects(rectangle))
        {
            if (colour.A == 255) down = false;
            if (colour.A == 0) down = true;
            if (down) colour.A += 3; else colour.A -= 3;
            if (mouse.LeftButton == ButtonState.Pressed) isClicked = true;
        }
        else if (colour.A < 255)
        {
            colour.A += 3;
            isClicked = false;
        }
    }
    public void setPosition(Vector2 newPosition)
    {
        position = newPosition;
    }
    public void Draw(SpriteBatch spritebatch)
    {
        spritebatch.Draw(texture, rectangle, colour);
    }
}
}

使数组动画化

c#有很棒的集合类库来代替list。我强烈反对使用Array,因为它不够灵活。如果你是专门为低端硬件编写代码,并且了解代码的进出和管理代码的每一个比特,那么只有选择数组。

但是我喜欢你组织课程的方式。非常好。现在,如果你有一个列表,那么你可以在任何时候添加任何数量的类。你不必事先决定怎么做。

现在,这个类有了矩形集合,它给出了精灵在精灵集合中的位置,然后你只需要在动画逻辑中使用in draw方法。你已经有了。

还有一件事,没有必要添加

Content.Load<Texture2D>("SpaceInvaderbefore")

多个时间。相反,将它存储到变量中并使用它。

这是两篇精彩的文章。1和2。其中提供了有关如何使用XNA做动画的详细信息。游戏开发必须有多元视角的过程。你也可以试试。

我希望我的回答对你有帮助。