Polo Swelsen
Polo Swelsen

Reputation: 69

Space Invaders stick to wall

So I have to develop an XNA game for school and I thought Space Invaders was a nice thing to make. But now I'm stuck with a problem. I have a List filled with 'Aliens' from another class. And every second it moves 20 px to the right and I want it to descend when it touches the right side of the screen (not the problem). But I want it to move the opposite direction (to the left) as soon as it touches the wall. Here lies the problem. As soon as it touches the wall it still moves 20px once, changes direction, moves 20px back and changes direction again. This keeps repeating. So where lies the problem. I think it has to check earlier if one of the aliens touches the screen but don't know how to accomplish that and thought maybe one of you could help me out because it is very frustrating!

I included the update method

if (xPos % step == 0)
{
   if (!isDescending)
   {
      for (int k = 0; k < sprites.Count; k++)
      {
         Sprite sprite = sprites[k];

         if (touchedRight) sprite.position.X += step;
         else sprite.position.X -= step;
      }

      for (int k = 0; k < sprites.Count; k++)
      {
         Sprite sprite = sprites[k];
         bool hitLeft = sprite.position.X == 0;
         bool hitRight = sprite.rect.Right == screenWidth;
         if ((hitLeft) || (hitRight))
         {
            touchedRight = !touchedRight;
            isDescending = true;
         }
      }
   }

   else
   {
      isDescending = false;
      for (int k = 0; k < sprites.Count; k++)
      {
         sprites[k].position.Y += sprites[k].rect.Height;
      }
   }
}
// CheckCollision(alienBounds, k-1);
// sprite.rect = new Rectangle((int)sprite.position.X, (int)sprite.position.Y, 20, 20);
// alienBounds = sprite.rect;
xPos += 1;

Upvotes: 1

Views: 731

Answers (3)

Polo Swelsen
Polo Swelsen

Reputation: 69

So i made a new rectangle called 'bounds' which is as wide as the aliens and moves the same as the aliens do. And got it working! (half of it). It moves to the right until it touches the right side, then it goes to the left but keeps going to the left and never goes back to the right. So where am i going wrong this time?

if (xPos % step == 0)
            {
                if (!isDescending)
                {

                    for (int k = 0; k < sprites.Count; k++)
                    {
                        Sprite sprite = sprites[k];
                        sprite.position.X += step;
                    }

                    if (bounds.Right == screenWidth || bounds.Left == 0)
                    {
                        touchedRight = !touchedRight;
                        step *= -1;
                    }

                    if (!touchedRight) bounds.X += step;
                    if (touchedRight) bounds.X -= step;

                    // for (int k = 0; k < sprites.Count; k++)
                    // {
                    //    Sprite sprite = sprites[k];

                    //    bool hitLeft = sprite.position.X == 0;
                    //    bool hitRight = sprite.rect.Right == screenWidth;
                    //    if ((hitLeft) || (hitRight))
                    //    {
                    //        touchedRight = !touchedRight;
                    //        isDescending = true;
                    //    }
                    // }
                }

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283733

Well, this is wrong:

if ((hitLeft) || (hitRight))

When moving right, you only care about hitRight. And when moving left, you care only about hitLeft.

So try

if (touchedRight? hitLeft: hitRight)

This will also fix the issue where multiple aliens can hit the wall at the same time.

Upvotes: 1

CSharpie
CSharpie

Reputation: 9477

Im not sure but I bellieve in Space invaders, if you kill all columns but the most left, it doesnt move completely to the right side of the screen before switching its direction.

So what I suggest is you create a derivate of a Sprite called Invader:

class Invader : Sprite
{
    readonly float distanceFromCenterHorizontal;

    public Invader(float distanceFromCenterHorizontal)
    {
        this.distanceFromCenterHorizontal= distanceFromCenterHorizontal;
    }

    public void UpdatePosition(Point center)
    {
        this.Position.X = center.X + distanceFromCenterHorizontal;
        this.Position.Y = center.Y;
    }
}



// global variables:
Point center = ....
bool moveLeft = false;

void createInvaders()
{
    int invaderWidth = 20; // whatever your value is
    float columnCenter = ((float) columnMax) / 2 * invaderWidth;

    for(var column = 0; column < columnMax ; column++)
    {
        float invaderX = (column * invaderWidth);

        float distanceFromCenterHorizontal = invaderX - columnCenter;

        for(var row = 0; row < rowMax; row ++)
        {
            Invader invader = new Invader(distanceFromCenterHorizontal);
            invader.Position.Y = row * invaderHeight // Needs adjustment here!
        }
    }
}

void update()
{
    if(center.X == screenWidth) moveLeft = true;
    else if(center.X <= 0) moveLeft = false;

    center.X += moveLeft? -step : step;

    foreach(var invader in invaders) invader.UpdatePosition(center);
}

You want to move the "centerPoint" and all Invaders update According to the new Center.

Im not sure if XNA uses double or float values, so youmight need to adjust this.

You can then easily expand this to create some up / down wobbling.

Upvotes: 0

Related Questions