消失的物体

Disappearing Objects

因此,对于我使用 MonoGame 的第一个项目,我决定制作一个俄罗斯方块克隆版,但我遇到了一个我不知道如何解决的问题。

目前我的代码正在生成一个块并将其向下移动直到到达特定的 y 位置。该块需要停留在这个位置,并且会产生一个新的块。我正在使用包含块 class 对象的列表来执行此操作,然后只绘制此列表中的所有块。

我删除了我认为与问题无关的部分:

 public class PlayField : DrawableGameComponent
    {
        private Game1 gameRef;
        private Texture2D fieldTexture;
        private BlockGenerator blockGenerator;
        private Texture2D[] allBlocks;

        private Block currentBlock;

        public bool[,] fieldFilled;
        private int down_Blocks = 22;
        private int side_Blocks = 10;

        public List<Block> placedBlocks;

        public PlayField(Game game) : base(game)
        {
            placedBlocks = new List<Block>();
            allBlocks = new Texture2D[4];
            blockGenerator = new BlockGenerator(allBlocks,gameRef);

        }   
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            try
            {
                if (currentBlock.isMoving == false)
                {
                    placedBlocks.Add(currentBlock);
                    currentBlock = null;
                    currentBlock = blockGenerator.GenerateBlock();
                }
                else
                {
                    currentBlock.UpdatePosition(gameTime);
                    if (InputManager.CheckForKeyBoardRelease(Keys.A))
                    {
                        currentBlock.MoveLeft();
                    }

                    if (InputManager.CheckForKeyBoardRelease(Keys.D))
                    {
                        currentBlock.MoveRight();
                    }
                }
            }
            catch(NullReferenceException e)
            {
                currentBlock = blockGenerator.GenerateBlock();
            }


        }

        public override void Draw(GameTime gameTime)
        {
            gameRef.SpriteBatch.Begin();

            if(currentBlock != null)
            {
                currentBlock.DrawBlocks();
            }

            foreach(Block b in placedBlocks)
            {
                b.DrawBlocks();
            }

            gameRef.SpriteBatch.End();
            base.Draw(gameTime);
        }

方法 "GenerateBlock" returns 类型的对象 "Block"

public class Block : DrawableGameComponent
    {
        Game1 gameRef;
        public Texture2D blockTexture;
        public Vector2[] blockPositions;
        TimeSpan lastMove;
        TimeSpan blockMove = TimeSpan.FromMilliseconds(500);

        public bool isMoving;


        public Block(Game game, Texture2D _blockTexture, Vector2[] _blockPositions) : base(game)
        {
            gameRef = (Game1)game;
            blockTexture = _blockTexture;
            blockPositions = _blockPositions;
            isMoving = true;
        }

        public void UpdatePosition(GameTime gameTime)
        {
            Vector2 bottomBlockPositon = FindBottomBlock();
            if(bottomBlockPositon.Y < 550)
            {
                if (WaitTillMove(gameTime))
                {
                    for (int i = 0; i < blockPositions.Length; i++)
                    {
                        blockPositions[i] = new Vector2(blockPositions[i].X, blockPositions[i].Y + 25);
                    }
                }
            }
            else
            {
                isMoving = false;
                Console.WriteLine("X: " +blockPositions[0].X + " Y:" + blockPositions[0].Y);
            }

        }

        public Vector2 FindBottomBlock()
        {
            Vector2 result = new Vector2(0, 0);
            for(int i = 0; i < blockPositions.Length; i++)
            {
                if(blockPositions[i].Y > result.Y)
                {
                    result = blockPositions[i];
                }
            }

            return result;
        }

        public bool WaitTillMove(GameTime gameTime)
        {
            if (lastMove + blockMove < gameTime.TotalGameTime)
            {
                lastMove = gameTime.TotalGameTime;
                return true;
            }
            return false;
        }

        public void DrawBlocks()
        {
            gameRef.SpriteBatch.Draw(blockTexture, blockPositions[0], Color.White);
            gameRef.SpriteBatch.Draw(blockTexture, blockPositions[1], Color.White);
            gameRef.SpriteBatch.Draw(blockTexture, blockPositions[2], Color.White);
            gameRef.SpriteBatch.Draw(blockTexture, blockPositions[3], Color.White);
        }
    }

调试显示我的列表包含一个元素,即使它的位置错误。但这应该无关紧要,因为我仍然同时只"see"一个街区。

希望有人能把我扔到正确的方向。

编辑:

public class BlockGenerator
    {
        Random random;
        Texture2D[] allBlocks;
        Vector2[] blockPositions;
        Texture2D currentBlock;
        BlockEnums currentBlockEnum;

        Game1 gameRef;

        public BlockGenerator(Texture2D[] blocks, Game1 game)
        {
            gameRef = (Game1)game;
            allBlocks = blocks;
            currentBlock = allBlocks[1];
            blockPositions = new Vector2[4];
            random = new Random();
        }

        public Block GenerateBlock()
        {
            int colorValue = random.Next(0, 4);     //0 = blue, 1 = green, 2 = red, 3 = yellow

            currentBlock = allBlocks[colorValue];
            currentBlockEnum = BlockEnums.Line;

            blockPositions[0] = new Vector2(100, 0);
            blockPositions[1] = new Vector2(125, 0);
            blockPositions[2] = new Vector2(150, 0);
            blockPositions[3] = new Vector2(175, 0);

            Block generatedBlock = new Block(gameRef,currentBlock, blockPositions);

            return generatedBlock;
        }
public class BlockGenerator
    {
        Random random;
        Texture2D[] allBlocks;
        Vector2[] blockPositions; // delete this

然后将构造函数中的初始化代码移到GenerateBlock中(添加var)。

var blockPositions = new Vector2[4];

那么应该可以了。您每次创建块时都在创建新向量,但每次都重复使用相同的 blockPositions 实例,因此两个块都存在但将始终具有完全相同的位置。

我还没来得及测试,但我认为这是正确的...让我知道:)

编辑:我还建议将 blockPositions 完全移动到 Block class 中。我认为在真正拥有它的 class 之外拥有该逻辑没有任何价值(在您发布的代码中,也许您以后有计划)......如果它包含在 class首先你会避免这个问题。只是一个建议:)