C# 在平铺贴图中移动平台
我使用的是一个平铺贴图,如果移动的平台撞到了一个平铺,它应该朝另一个方向移动。我正在使用tilemap和platform的列表,这有助于保持整洁 下图显示了平台,它一直在运动,当它与一个黑色圆圈碰撞时,它应该改变方向,朝着相反的方向前进 不幸的是,我遇到了一个问题,我需要找到正确的平台,这样它就会转向另一个方向。我在main类中创建了列表,但不知道如何在main之外的另一个类中调用该列表 问题: 我如何调用一个列表,该列表包含多个在不同方向、不同位置运行的对象,并且是在主类中创建的,这样我就可以知道平台是否与平铺发生碰撞 简单地说,如何使平台与磁贴碰撞? 以下是使用和调用平铺贴图必须经过的过程: 要制作平铺贴图,需要使用两个类:Block类和Game1类(主类) 在Block类中,纹理、位置和BlockState(决定它将做什么) 然后Block类将使用一个使用Player类的方法C# 在平铺贴图中移动平台,c#,object,xna,tile,C#,Object,Xna,Tile,我使用的是一个平铺贴图,如果移动的平台撞到了一个平铺,它应该朝另一个方向移动。我正在使用tilemap和platform的列表,这有助于保持整洁 下图显示了平台,它一直在运动,当它与一个黑色圆圈碰撞时,它应该改变方向,朝着相反的方向前进 不幸的是,我遇到了一个问题,我需要找到正确的平台,这样它就会转向另一个方向。我在main类中创建了列表,但不知道如何在main之外的另一个类中调用该列表 问题: 我如何调用一个列表,该列表包含多个在不同方向、不同位置运行的对象,并且是在主类中创建的,这样我就可
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;
}