所以对于我的第一个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;
}
答案 0 :(得分:1)
public class BlockGenerator
{
Random random;
Texture2D[] allBlocks;
Vector2[] blockPositions; // delete this
然后将初始化代码从构造函数移动到GenerateBlock(添加var)。
var blockPositions = new Vector2[4];
然后它应该工作。您每次创建一个块时都在创建新的向量,但每次都重复使用相同的blockPositions实例,因此两个块都存在但总是具有完全相同的位置。
我没有时间去测试,但我认为这是对的......让我知道:)。
编辑:我还建议将blockPositions完全移入Block类。我认为没有任何价值(在你发布的代码中,也许你有以后的计划)在类之外拥有真正拥有它的逻辑......如果它开始包含在类中,你就可以避免这种情况问题。只是一个建议:)