Monogame,为啥即使有功能,块也不会移动?

Posted

技术标签:

【中文标题】Monogame,为啥即使有功能,块也不会移动?【英文标题】:Monogame, why wont the block move even if there is an function for it?Monogame,为什么即使有功能,块也不会移动? 【发布时间】:2021-12-02 19:29:31 【问题描述】:

我需要一些帮助,我有一个迷宫游戏,我需要在其中推块。如果我与块相交,第一个应该向右移动,第二个应该向左移动。问题是当我相交时我不能让它们中的任何一个移动。帮助将不胜感激。

Game1.cs

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace Labyrintspel


public class Game1 : Game

    private GraphicsDeviceManager _graphics;
    private SpriteBatch _spriteBatch;
    Texture2D pixelTexture;
    Texture2D playerTexture;
    List<Block> blocks = new List<Block>();
    Player player;
    Color backgroundColor = Color.CornflowerBlue;
    Block door;
    Block door2;
    int i = 0;
    int i2 = 0;
    int speed1 = 1;
    int speed2 = -1;

    public Game1()
    
        _graphics = new GraphicsDeviceManager(this);
        _graphics.PreferredBackBufferWidth = 800;
        _graphics.PreferredBackBufferHeight = 500;
        _graphics.ApplyChanges();
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
        


    protected override void Initialize()
    
        base.Initialize();
    
        
            blocks.Add(BlockFactory.CreateEatableBlock(70, 300));
            blocks.Add(BlockFactory.CreateEatableBlock(190, 300));
            blocks.Add(BlockFactory.CreateEatableBlock(490, 300));
            blocks.Add(BlockFactory.CreateWall(0, 460, 800, 40));
            blocks.Add(BlockFactory.CreateWall(0, 0, 800, 30));
            blocks.Add(BlockFactory.CreateWall(0, 0, 40, 460));
            blocks.Add(BlockFactory.CreateWall(760, 0, 40, 460));
            blocks.Add(BlockFactory.CreateWall(640, 200, 40, 260));
            blocks.Add(BlockFactory.CreateWall(140, 100, 700, 40));
            blocks.Add(BlockFactory.CreateWall(540, 130, 40, 250));
            blocks.Add(BlockFactory.CreateWall(440, 200, 40, 260));
            blocks.Add(BlockFactory.CreateWall(340, 130, 40, 250));
            blocks.Add(BlockFactory.CreateWall(240, 200, 40, 260));
            blocks.Add(BlockFactory.CreateWall(140, 130, 40, 250));
            blocks.Add(BlockFactory.RemovableWall(600, 0, 40, 100));
            blocks.Add(BlockFactory.CreateWall(650, 375, 150, 200));
            door = new Block(720, 40, 30, 50, Color.SaddleBrown);
            blocks.Add(door);
            door2 = new Block(700, 400, 30, 50, Color.SaddleBrown);


            player = new Player(700, 300, playerTexture.Width, playerTexture.Height);
        
    

    protected override void LoadContent()
    
        _spriteBatch = new SpriteBatch(GraphicsDevice);
        pixelTexture = Content.Load<Texture2D>("pixel");
        playerTexture = Content.Load<Texture2D>("player");

    

    protected override void Update(GameTime gameTime)
    
        var keyState = Keyboard.GetState();
        base.Update(gameTime);

        player.StorePosition();

        if (keyState.IsKeyDown(Keys.Left)) player.MoveLeft();
        if (keyState.IsKeyDown(Keys.Right)) player.MoveRight();
        if (keyState.IsKeyDown(Keys.Up)) player.MoveUp();
        if (keyState.IsKeyDown(Keys.Down)) player.MoveDown();
        

        if (player.GetRectangle().Intersects(door.Rectangle))
        
            i = 0;
            blocks.RemoveAll(block => block.IsVisible);
            blocks.Add(BlockFactory.CreateWall(0, 460, 800, 40));
            blocks.Add(BlockFactory.CreateWall(0, 0, 800, 30));
            blocks.Add(BlockFactory.CreateWall(0, 0, 40, 460));
            blocks.Add(BlockFactory.CreateWall(760, 0, 40, 460));
            blocks.Add(BlockFactory.CreateWall(100, 100, 800, 40));
            blocks.Add(BlockFactory.CreateWall(0, 200, 400, 40));
            blocks.Add(BlockFactory.CreateWall(500, 200, 400, 40));
            blocks.Add(BlockFactory.CreateWall(0, 300, 200, 40));
            blocks.Add(BlockFactory.CreateWall(300, 300, 500, 40));
            blocks.Add(BlockFactory.RemovableWall(600, 300, 40, 300));
            blocks.Add(BlockFactory.CreateEatableBlock(700, 250));
            blocks.Add(BlockFactory.CreateEatableBlock(190, 150));
            blocks.Add(BlockFactory.CreateEatableBlock(500, 400));
            blocks.Add(BlockFactory.CreatePushableBlock(50, 150));
            blocks.Add(BlockFactory.CreatePushableBlock(50, 400));
            blocks.Add(door2);

        
        if (player.GetRectangle().Intersects(door2.Rectangle))
        
            this.Exit();
        
       

        backgroundColor = Color.CornflowerBlue;
            foreach (var block in blocks)
            
                if (player.GetRectangle().Intersects(block.Rectangle))
                
                   if (block.IsPushable && keyState.IsKeyDown(Keys.Space) && i2 == 0)
                   
                    block.MoveRight();
                    i2++;                        
                   
                    if (block.IsSolid) player.RestorePosition();
                    if (block.IsEatable)
                    
                        block.IsVisible = false;
                        i++;

                    
                
                if (i == 3)
                
                    if (block.IsRemovable)
                    
                        block.IsSolid = false;
                        block.IsVisible = false;
                    
                


            


            blocks.RemoveAll(block => !block.IsVisible);
        
    

    protected override void Draw(GameTime gameTime)
    
        GraphicsDevice.Clear(backgroundColor);

        _spriteBatch.Begin();
        blocks.ForEach(block => block.Draw(_spriteBatch, pixelTexture));
        player.Draw(_spriteBatch, playerTexture);
        _spriteBatch.End();

        Window.Title = "Antal block: " + blocks.Count;

        base.Draw(gameTime);
    

块.cs

public class Block


    public Rectangle Rectangle  get; set; 
    public Color Color  get; set; 
    public bool IsSolid  get; set;  = true;
    public bool IsEatable  get; set;  = false;
    public bool IsVisible  get; set;  = true;
    public bool IsRemovable  get; set;  = false;
    public bool IsPushable  get; set;  = false;
    private Vector2 position;
    private Rectangle rectangle;


    public Block(int x, int y, int w, int h, Color color)
    
        
        Color = color;
        position.X = x;
        position.Y = y;
        Rectangle = new Rectangle(x, y, w, h);
    

    public void Move(float dx, float dy)
    
        position.X += dx;
        position.Y += dy;
    
    public Rectangle PushabelRectangle()
    
        rectangle.X = (int)position.X;
        rectangle.Y = (int)position.Y;
        return rectangle;
    

    internal void MoveLeft() => Move(-10, 0);
    internal void MoveRight() => Move(100, 0);

    public void Draw(SpriteBatch spriteBatch, Texture2D texture)
    
       
       if (IsVisible)
         
                spriteBatch.Draw(texture, Rectangle, Color);
         
       
    
    

blockfactory.cs

 internal class BlockFactory
    

    internal static Block CreateEatableBlock(int x, int y)
    
        var block = new Block(x, y, 40, 40, Color.Yellow);
        block.IsSolid = false;
        block.IsEatable = true;
        return block;
    
    internal static Block CreatePushableBlock(int x, int y)
    
        var block =  new Block(x, y, 40, 40, Color.Orange);
        block.IsPushable = true;
        return block;
    

    internal static Block CreateWall(int x, int y, int w, int h)
    
         return new Block(x, y, w, h, Color.Black);
    

    internal static Block RemovableWall(int x, int y, int w, int h)
    
        var block = new Block(x, y, w, h, Color.Black);
        block.IsSolid = true;
        block.IsEatable = false;
        block.IsVisible = true;
        block.IsRemovable = true;
        return block;
    
    internal static Block CreatePushBlock(int x, int y, int w, int h)
    
        return new Block(x, y, w, h, Color.Orange);
    

这段代码没有显示错误,但是当我相交并按空格键时没有任何反应。

【问题讨论】:

你是否设置了断点并进行了调试以检查它是否到达block.MoveRight() 我需要强调显示问题所需的最小可重现代码。在通过门之前没有可推动的块?多次减少代码会给你答案。 【参考方案1】:

Move() 正在更改 position 变量,但该块是从 Rectangle 字段中绘制的,该字段未更改以反映移动。

我建议以下相关性: public Rectangle Rectangle getreturn rectangle; set rectangle = value; )

public void Move(float dx, float dy)
    
        position.X += dx;
        position.Y += dy;
        Rectangle =  new Rectangle((int)position.X, (int)position.Y, Rectangle.Width, Rectangle.Height);
    // you cannot set the X and Y of field structures directly.
    

【讨论】:

以上是关于Monogame,为啥即使有功能,块也不会移动?的主要内容,如果未能解决你的问题,请参考以下文章

如何在monogame中缩小和增长一个矩形?

我的球和我的矩形不会正确碰撞(Monogame)

XNA (MonoGame) 世界空间和物体运动

C# MonoGame - 玩家向后移动

已经关闭所有占用程序,移动硬盘还是不能安全移除?为啥,怎么解决?

为啥即使电子邮件经过验证,电子邮件验证仍然存在?