消失的物体

时间:2017-03-29 06:49:14

标签: c# monogame

所以对于我的第一个MonoGame项目,我决定制作一个俄罗斯方块克隆,但我有一个问题,我不知道如何解决。

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

我拿出了我认为没有涉及问题的部分:

 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”返回“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);
        }
    }

调试说我的List包含一个Element,即使它的位置错误。但这应该不重要,因为我仍然只能同时“看到”一个Block。

希望有人可以把我拉向正确的方向。

编辑:

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

1 个答案:

答案 0 :(得分:1)

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

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

var blockPositions = new Vector2[4];

然后它应该工作。您每次创建一个块时都在创建新的向量,但每次都重复使用相同的blockPositions实例,因此两个块都存在但总是具有完全相同的位置。

我没有时间去测试,但我认为这是对的......让我知道:)。

编辑:我还建议将blockPositions完全移入Block类。我认为没有任何价值(在你发布的代码中,也许你有以后的计划)在类之外拥有真正拥有它的逻辑......如果它开始包含在类中,你就可以避免这种情况问题。只是一个建议:)