俄罗斯方块删除行问题

时间:2013-11-23 22:32:47

标签: c# xna

我正在尝试在XNA中创建一个俄罗斯方块游戏,以便更好地学习将来制作更好的游戏。我遇到的唯一问题是游戏的“删除行”功能。我有一个整数矩阵来保存其中块的所有行数。每当我创建一个新块时,我在指定的行中将计数增加一。然后,我检查矩阵中的任何值是否达到或超过10.然后,如果有,我删除所述行中的所有块。我遇到的问题是它不可靠,并且由于某些原因它不会跟踪计数,有时它也不会删除行中的所有块。如果您需要查看任何其他课程,请告诉我。谢谢,感谢您的帮助。

public class Main : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    //Texture for the block
    public static Texture2D block;
    //Font 
    public static SpriteFont font1;
    //Which shape we're dealing with(Moving)
    public static int shapeIndex;
    //The next shape, the one we can see previewed
    public static Shape nextShape;
    //The first shape we use
    public static Shape s2;
    //All the shapes
    public static List<Shape> shapes = new List<Shape>();
    //All the blocks that have stopped moving (The shapes are converted to blocks when they stop moving to make for easier deletion)
    public static List<Block> blocks = new List<Block>();
    //The count of blocks in each row
    public static int[] rowCount = new int[20];

    public Main()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        graphics.PreferredBackBufferHeight = 500;
    }

    protected override void Initialize()
    {
        this.IsMouseVisible = true;
        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        block = Content.Load<Texture2D>("Sprites//TetrisBlock");
        font1 = Content.Load<SpriteFont>("Fonts//GameFont");
        //Creating a random shape
        switch (new Random().Next(1, 3))
        { 
            case 1:
                nextShape = new Shape(Shape.Shapes.tShape, new Vector2(550, 0), false);
                break;
            case 2:
                nextShape = new Shape(Shape.Shapes.lineShape, new Vector2(550, 0), false);
                break;
        }
        //The current shape we're dealing with
        shapeIndex = 0;
        //Creating the first shape
        s2 = new Shape(Shape.Shapes.lineShape, new Vector2(), true);
    }

    protected override void Update(GameTime gameTime)
    {
        //If the blocks that are still are rainbow, have them cycle through their colors
        foreach (Block b in nextShape.Blocks)
        {
            if (b.RainbowBlock)
                b.changeColor(gameTime);
        }
        //Update all the shapes
        for (int i = 0; i < shapes.Count; i++)
        {
            shapes[i].Update(gameTime);
        }
        //If the shape has hit another shape and stopped moving
        if (!shapes[shapeIndex].MoveDown)
        {
            //For every block that was in the shape, add it to the block list and increase that row's count by one
            foreach (Block b in shapes[shapeIndex].Blocks)
            {
                blocks.Add(b);
                rowCount[b.Row]++;
            }
            //Remove that shape
            shapes.RemoveAt(shapeIndex);
            //The current shape we need to move
            Shape s3 = nextShape;
            s3.Position = new Vector2();
            s3.Imaginary = false;
            shapes.Add(s3);
            //Creating a new random shape for the next shape
            switch (new Random().Next(1, 4))
            {
                case 1:
                    nextShape = new Shape(Shape.Shapes.tShape, new Vector2(550, 0), false);
                    break;
                case 2:
                    nextShape = new Shape(Shape.Shapes.lineShape, new Vector2(550, 0), false);
                    break;
                case 3:
                    nextShape = new Shape(Shape.Shapes.lShape, new Vector2(550, 0), false);
                    break;
            }
        }
        //Testing whether or not rows have reached their maximum capacity
        for (int i = 0; i < rowCount.Length; i++)
        {
            //If a row has reached its capacity
            if (rowCount[i] >= 10)
            {
                //Remove that row
                removeRow(i);
                //Move all blocks that are above that row down one
                foreach (Block b in blocks)
                {
                    if (b.Row < i)
                    {
                        //Subtract the old rowcount by one
                        rowCount[b.Row]--;
                        b.Row++;
                        //Add one to the rowcount(If I remove this, it seems to work a little better but it still has issues)
                        rowCount[b.Row]++;
                    }
                }
            }
        }
        //Update all the blocks that are still
        foreach (Block b in blocks)
            b.Update(gameTime);
        base.Update(gameTime);
    }

    //Remove the row specified in the parameters
    public void removeRow(int row)
    {
        //For every block
        for (int i = 0; i < blocks.Count; i++)
        {
            //See if it's in the row the user wants to remove
            if (blocks[i].Row.Equals(row))
            {
                //If it is, remove it and decrement that row's rowcount
                blocks.RemoveAt(i);
                rowCount[row]--;
                //Here was the problem, I wasn't decrementing i to check the next block
                i--;
            }
        }
    }

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

        spriteBatch.Begin();
        //Draws every shape in the game
        foreach (Shape s in shapes)
            s.Draw(spriteBatch);
        //Draws all the blocks at the bottom that have stopped moving
        foreach (Block b in blocks)
            b.Draw(spriteBatch);
        //Info for me
        spriteBatch.DrawString(font1, "Next Block:", new Vector2(430, 0), Color.Black);
        spriteBatch.DrawString(font1, rowCount[19].ToString() + " " + blocks.Count + " Blocks", new Vector2(300, 0), Color.Black);
        //For the next shape, draw every block so we know what it looks like
        foreach (Block b in nextShape.Blocks)
            b.Draw(spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

[编辑] 向下移动的部件工作正常,它只是删除麻烦的行。我也尽力发表评论,如果你有任何问题,请问。再次感谢。

1 个答案:

答案 0 :(得分:1)

当我迭代我正在检查的块时,如果我删除了它,我没有递减迭代变量来检查下一个块 - 所以所有的块都没有被检查。