0

So I saw multiple tutorials using rectangle as an array. But their invaders are not animated. I'm using a spritesheet for my invaders and I need to have them all animated... How to do this?

Here's my invader class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;

namespace SpaceInvaders
{
    class botInvaders
    {

        public botInvaders()
        {

        }

        public static Texture2D BotInvaderTex;
        Rectangle BotInvaderHitBox;
        public static Vector2 BotInvaderPos = new Vector2(0, 28), BotInvaderOrigin;

        int BotInvaderCurrentFrame = 1, BotInvaderFrameWidth = 52, BotInvaderFrameHeight = 88;

        float Timer = 0f, Interval = 100f;

        public void Initialize()
        {

        }

        public void LoadContent(ContentManager Content)
        {
            BotInvaderTex = Content.Load<Texture2D>(".\\gameGraphics\\gameSprites\\botInvaders\\normalInvaders\\invaderShip1");
        }

        public void Update(GameTime gameTime)
        {
            BotInvaderHitBox = new Rectangle(BotInvaderCurrentFrame * BotInvaderFrameWidth, 0, BotInvaderFrameWidth, BotInvaderFrameHeight);
            BotInvaderOrigin = new Vector2(BotInvaderHitBox.X / 2, BotInvaderHitBox.Y / 2);

            Timer += (float)gameTime.ElapsedGameTime.Milliseconds;

            if (Timer > Interval)
            {
                BotInvaderCurrentFrame++;
                Timer = 0f;
            }

            if (BotInvaderCurrentFrame == 2)
            {
                BotInvaderCurrentFrame = 0;
            }

            BotInvaderHitBox = new Rectangle(BotInvaderCurrentFrame * BotInvaderFrameWidth, 0, BotInvaderFrameWidth, BotInvaderFrameHeight);
            BotInvaderOrigin = new Vector2(BotInvaderHitBox.Width / 2, BotInvaderHitBox.Height / 2);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(BotInvaderTex, BotInvaderPos, BotInvaderHitBox, Color.White, 0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);      
        }
    }
}

This shows how I animate the invaders. Can I have the portion of modified code so that there are 5 rows of invaders and 10 collumns? I can do the movement myself, I only need the array. Thanks in advance!

PowerUser
  • 812
  • 1
  • 11
  • 32
  • I do know how to create an array but I need the code for adding the *animated* invaders to it. – PowerUser Nov 20 '14 at 21:45
  • 1
    The best way would be to encapsulate all of the invader stuff in its own class. Let's say you call it `Invader`. Then, you'd have `Invader[] array = new Invader[10,5]` and in the Update loop you could call `array[x,y].Update(gameTime)` and in the Draw() method you could call `array[x,y].Draw(spriteBatch)` – itsme86 Nov 20 '14 at 21:47
  • @itsme86 You should post that as the answer... – BradleyDotNET Nov 20 '14 at 21:49

2 Answers2

2

The best way to achieve what you want would be to encapsulate all of the invader stuff in its own class. Let's say you call it Invader. It could look something like this:

public class Invader
{
    private Texture2D _texture;

    public Invader(Texture2D texture)
    {
        _texture = texture;
    }

    public void Update(GameTime gameTime)
    {
        // Update logic for this individual invader goes here
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        // Draw routine for this invidual invader goes here
    }
}

Then, you'd have:

Invader[,] array = new Invader[columns,rows];

which you'd initialize at game start. In the Update() method you'd loop through the array and call the invader's Update() method:

for (int y = 0;y < rows;++y)
{
    for (int x = 0;x < columns;++x)
    {
        array[x,y].Update(gameTime);
    }
}

and, similarly, in the Draw() method you would do the same looping and call:

array[x,y].Draw(spriteBatch);
itsme86
  • 19,266
  • 4
  • 41
  • 57
  • Alright I got the first part, but in the array, I should replace `collumns, rows` with my numbers? And you didn't declare `x` and `y`, I know you mean these are coordinates, but yeah. – PowerUser Nov 20 '14 at 21:58
  • @Charlie Instead of replacing columns and rows with your numbers, I would make them variables (or constants) since having the values will make things easier for loops. However, x and y should refer to the indices into the multidimensional array. I've added the loop for the `Update()` method so it's clear. – itsme86 Nov 20 '14 at 21:59
  • I think it should be `botInvaders[,] Array = new botInvaders[10, 5];`, Otherwise it'd throw an error. – PowerUser Nov 20 '14 at 22:05
  • @Charlie Oops yeah, I forgot the comma. I've fixed it now. – itsme86 Nov 20 '14 at 22:07
  • Wait, if I initialize the constructor like this: `BotInvader = new botInvaders();` it would throw an error again: `'SpaceInvaders.botInvaders' does not contain a constructor that takes 0 arguments` – PowerUser Nov 20 '14 at 22:09
  • @Charlie That's because the constructor expects the texture (BotInvaderTex) to be passed to it. So it would be `BotInvader = new BotInvader(BotInvaderTex);` – itsme86 Nov 20 '14 at 22:14
  • And here's the last thing the debugger threw at me: after I added the `for` loop to `Update()`, `x` and `y` are not being recognised in `Draw()`. What am I missing? `The name 'x'/'y' does not exist in the current context`... – PowerUser Nov 20 '14 at 22:20
  • @Charlie Not sure. Did you use a / instead of a , or something? – itsme86 Nov 20 '14 at 22:27
  • No, I meant for both of them. Both `x` and `y` are mistaken? I used a comma. – PowerUser Nov 20 '14 at 22:29
  • I'm guessing your loop looks different than mine. Make sure it looks like the nested `for` loops I have in my answer. – itsme86 Nov 20 '14 at 22:38
  • That can't be because I copy-pasted it from right there. – PowerUser Nov 20 '14 at 22:41
  • Alright I got the `for` loop in my `Update()`. I also wrapped my `array[x,y].Draw(spriteBatch);` within a new for loop that looks like the one in `Update()`. The errors are gone. But I get a NullReferenceException... I can post my `Game1` class in another question if you need to see it? – PowerUser Nov 21 '14 at 11:55
  • @Charlie That would be best. – itsme86 Nov 21 '14 at 15:36
  • http://stackoverflow.com/questions/27065728/c-sharp-xna-nullreferenceexception-on-my-for-loop – PowerUser Nov 21 '14 at 16:15
1

Encapsulate it! You can use an invader class to make a array of space invaders.

Invader[] InvaderArray = new Invader[x,y];

You would then have to call:

InvaderArray[x,y].Update(gameTime);

and then in the draw method you need to draw it.

InvaderArray[x,y].Draw(spriteBatch)
Needham
  • 457
  • 1
  • 6
  • 15