2013-06-01 3 views
1

в настоящее время пытается оживить массив вражеских спрайтов для в игре я производить в C# с помощью XNA 4.0Анимационного массив

Используя этот анимационного код

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, однако я получаю сообщение об ошибке в методе Draw: «Ошибка 1« System.Array »не содержит определения для« Draw »и никакого метода расширения ' Draw ', принимающий первый аргумент типа «System.Array», можно найти (вам не хватает директивы использования или ссылки на сборку?) «

Любые идеи, что пошло не так?

Edit: Вот полный код 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); 
    } 
} 
} 

второй Edit: Кнопка класса

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

} 
+0

В вашем цикле foreach в 'Draw (GameTime)' вам нужно сделать 'invader.Draw (spriteBatch)' - на данный момент у вас есть «захватчики», который является массивом, что дает ошибку. Это означает, что foreach 'invader' в' invaders' будет вызван элемент Draw. – VisualMelon

+0

Как сторона, где вызывается 'spriteBatch.End()'? Из вашего кода похоже, что это не метод, и он должен быть в конце вашего метода Draw. – VisualMelon

+0

О, весь код во втором окне Я только скопировал соответствующий код в массив, так как у меня слишком много кода, поэтому часть foreach я скопировал эту часть и часть spriteBatch.End(), которую я также скопировал, объясняет, почему это выглядит странно там –

ответ

0

C# имеет прекрасную библиотеку классов коллекций для замены списка. Я очень не рекомендую использовать Array, поскольку он недостаточно гибкий. Если вы пишете код специально для низкоуровневого оборудования, а также знаете код и управляете им и управляете каждым его битом, а затем переходите к массиву.

Но мне нравится, как вы структурировали занятия. Это очень хорошо. Теперь, если у вас есть список, вы можете добавить любое количество классов в любой момент времени. Вам не нужно решать вышеприведенное время, как это сделать.

Теперь у этого класса есть коллекция Rectangles, которая дает положение спрайта в вашей коллекции спрайтов, тогда вам просто нужно использовать метод draw в вашей логике анимации. Что у вас уже есть.

И еще одна вещь, Там нет необходимости добавлять

Content.Load<Texture2D>("SpaceInvaderbefore") 

несколько раз. Вместо этого сохраните его в переменной и используйте его.

С этим здесь линия двух замечательных статей. 1 и 2. Подробные сведения о том, как сделать анимацию с XNA. И для развития игры должен быть курс Plural Sight. Вы также можете попробовать это.

Надеюсь, мой ответ вам поможет. пожалуйста, дайте мне знать, если требуется какая-либо дополнительная информация.

Смежные вопросы