C# 在平铺贴图中移动平台

C# 在平铺贴图中移动平台,c#,object,xna,tile,C#,Object,Xna,Tile,我使用的是一个平铺贴图,如果移动的平台撞到了一个平铺,它应该朝另一个方向移动。我正在使用tilemap和platform的列表,这有助于保持整洁 下图显示了平台,它一直在运动,当它与一个黑色圆圈碰撞时,它应该改变方向,朝着相反的方向前进 不幸的是,我遇到了一个问题,我需要找到正确的平台,这样它就会转向另一个方向。我在main类中创建了列表,但不知道如何在main之外的另一个类中调用该列表 问题: 我如何调用一个列表,该列表包含多个在不同方向、不同位置运行的对象,并且是在主类中创建的,这样我就可

我使用的是一个平铺贴图,如果移动的平台撞到了一个平铺,它应该朝另一个方向移动。我正在使用tilemap和platform的列表,这有助于保持整洁

下图显示了平台,它一直在运动,当它与一个黑色圆圈碰撞时,它应该改变方向,朝着相反的方向前进

不幸的是,我遇到了一个问题,我需要找到正确的平台,这样它就会转向另一个方向。我在main类中创建了列表,但不知道如何在main之外的另一个类中调用该列表

问题:

我如何调用一个列表,该列表包含多个在不同方向、不同位置运行的对象,并且是在主类中创建的,这样我就可以知道平台是否与平铺发生碰撞

简单地说,如何使平台与磁贴碰撞?

以下是使用和调用平铺贴图必须经过的过程:

要制作平铺贴图,需要使用两个类:Block类和Game1类(主类)

在Block类中,纹理、位置和BlockState(决定它将做什么)

然后Block类将使用一个使用Player类的方法

    public Player BlockCollision(Player player)
    { 
        Rectangle top = new Rectangle((int)Position.X + 5, (int)Position.Y - 10, Texture.Width - 10, 10);
        Rectangle bottom = new Rectangle((int)Position.X + 5, (int)Position.Y + Texture.Height, Texture.Width - 10, 10);
        Rectangle left = new Rectangle((int)Position.X - 10, (int)Position.Y + 5, 10, Texture.Height - 10);
        Rectangle right = new Rectangle((int)Position.X + Texture.Width, (int)Position.Y + 5, 10, Texture.Height - 10);

        if (BlockState == 1 || (BlockState == 2 && !player.goingUp))
        {
            if (top.Intersects(new Rectangle((int)player.Position.X, (int)player.Position.Y, player.Texture.Width, player.Texture.Height)))
            {
                if (player.Position.Y + player.Texture.Height > Position.Y && player.Position.Y + player.Texture.Height < Position.Y + Texture.Height / 2)
                {
                    player.Position.Y = player.ground = Position.Y - player.Texture.Height;
                    player.Velocity.Y = 0;
                    player.isJumping = false;
                    player.Time = 0;
                    player.botCollision = true;
                }
            }
        }

        return player;
    }
然后我们转到主类Game1

我创建了块和平台的列表

    List<Block> Blocks;
    List<MovingPlatform> Platforms;
最后,Draw方法调用它们

        foreach (Block b in Blocks)
        {
            b.Draw(spriteBatch);
        }

        foreach (MovingPlatform m in Platforms)
        {
            m.Draw(spriteBatch);
        }

我想我理解你的问题,我不确定,但我还是要冒险回答

我认为你需要做的是把东西从主要的游戏类中移出。你有一个地图的概念和一堆属于地图的东西(平台、块),所以最好将其封装在自己的类中,例如:

class Map
{
    public List<Block> Blocks;
    public List<MovingPlatform> Platforms;

    void LoadLevel(int level)
    {
        ///
    }
}
因此,在map类LoadLevel()方法中,您将传入'this'作为MovingPlatform构造函数的第一个参数:

class Map
{
    void LoadLevel(int level)
    {
        //Vertical Moving Platform
        if (Levels[level][y, x] == '=')
        {
            Platforms.Add(new MovingPlatform(this, ...));
        }
    }
}
您可以将其他特定于地图的内容(甚至是对玩家的引用?)添加到地图类中,移动平台将自动访问这些内容

这称为依赖注入。您的MovingPlatform类在映射上有一个依赖项,您正在通过构造函数将该依赖项注入

编辑:

对于碰撞,可以向平铺和MovingPlatform类添加Bounds属性。这样可以更容易地获取它们的当前矩形边界。MovingPlatform中的IntersectsTile方法,如果平台与指定的平铺相交,该方法将返回true

class Tile
{
    Rectangle Bounds
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, tileWidth, tileHeight);
        }
    }
}

class MovingPlatform
{
    Rectangle Bounds
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, platformWidth, platformHeight);
        }
    }

    //returns true if this platform intersects the specified tile
    bool IntersectsTile(Tile tile)
    {
        return Bounds.Intersects(tile.Bounds);
    }
}
然后,在更新方法中的MovingPlatfom类中,每个帧移动平台,检查移动后是否有碰撞。如果发生碰撞,则退出移动并反转平台方向,以便下一帧它将以相反的方向移动

class MovingPlatform
{
    void Update(Tile[] collidableTiles)
    {
        Position += direction;

        //test collision
        bool isCollision = CollisionTest(collidableTiles);
        if (isCollision)
        {
            //undo the movement and change direction
            Position -= direction;
            direction = newDirection;
        }
    }

    //returns true if this platform intersects with any of the specified tiles
    bool CollisionTest(Tile[] tiles)
    {
        foreach (Tile tile in tiles)
            if (IntersectsTile(tile))
                return true;
        return false;
    }
}
要使上述功能正常工作,您需要将地图上的可碰撞分幅列表传递给MovingPlatform更新。调用map类中的每个MovingPlatform,并向其传递可碰撞平铺列表

class Map
{
    List<Tile> _collidableTiles;

    void Update(GameTime gameTime)
    {
        foreach (MovingPlatform platform in MovingPlatforms)
        {
            platform.Update(_collidableTiles);
        }
    }
}
因此,所有平铺都具有IsSolid属性,任何设置为true的平铺都会导致移动平台与它们发生碰撞

class Tile
{
    bool IsSolid;
}

谢谢你帮我处理我的乱七八糟的代码。我会努力解决这个问题,很抱歉我不清楚我的问题。我真的不知道是什么让你们有点困惑,我想从类中分别添加代码并不是最好的主意。我没有看到一种更简单的方式来显示我的代码,因为它是一个大的块,任何人都会讨厌它。不,我理解你的帖子好的,我只是不确定我是否应该在答案中发布代码来进行实际的碰撞检测(我不确定如何使用块)好的,这个呢,我们只查看包含平台对象的列表。现在我如何做一个for循环,并找到它们的位置,看看它们是否与瓷砖的位置重叠。只要告诉我如何找到平台,我可以做瓷砖。这看起来很棒,我认为这会很好,谢谢你的帮助Weyland。
class Map
{
    public List<Block> Blocks;
    public List<MovingPlatform> Platforms;

    void LoadLevel(int level)
    {
        ///
    }
}
class MovingPlatform
{
    Map _map;
    public MovingPlatform(Map map, Vector2 position, ...)
    {
        _map = map;
    }

    public void Update(GameTime gameTime)
    {
        //move platform
        //detect collision
        //have access to all the blocks and other platforms on map
        //_map.Blocks;
        //_map.Platforms;
    }
}
class Map
{
    void LoadLevel(int level)
    {
        //Vertical Moving Platform
        if (Levels[level][y, x] == '=')
        {
            Platforms.Add(new MovingPlatform(this, ...));
        }
    }
}
class Tile
{
    Rectangle Bounds
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, tileWidth, tileHeight);
        }
    }
}

class MovingPlatform
{
    Rectangle Bounds
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, platformWidth, platformHeight);
        }
    }

    //returns true if this platform intersects the specified tile
    bool IntersectsTile(Tile tile)
    {
        return Bounds.Intersects(tile.Bounds);
    }
}
class MovingPlatform
{
    void Update(Tile[] collidableTiles)
    {
        Position += direction;

        //test collision
        bool isCollision = CollisionTest(collidableTiles);
        if (isCollision)
        {
            //undo the movement and change direction
            Position -= direction;
            direction = newDirection;
        }
    }

    //returns true if this platform intersects with any of the specified tiles
    bool CollisionTest(Tile[] tiles)
    {
        foreach (Tile tile in tiles)
            if (IntersectsTile(tile))
                return true;
        return false;
    }
}
class Map
{
    List<Tile> _collidableTiles;

    void Update(GameTime gameTime)
    {
        foreach (MovingPlatform platform in MovingPlatforms)
        {
            platform.Update(_collidableTiles);
        }
    }
}
class MovingPlatform
{
    void Update()
    {
        Position += direction;

        //test collision
        Tile[] tiles = _map.GetNearbyTiles(Position);
        foreach (Tile tile in tiles)
            if (tile.IsSolid)
                if (IntersectsTile(tile))
                {
                    //undo the movement and change direction
                    Position -= direction;
                    direction = newDirection;
                    break;
                }
    }
}
class Tile
{
    bool IsSolid;
}