C# 如何仅绘制屏幕上可见的平铺(精灵)
我正在尝试创建一个简单的2d滚动游戏,作为monogame(XNA)中的学习练习。目前,我从文本文件加载平铺信息,创建一个数组(tiles[,]),其中一个平铺对象存储有关平铺写入位置以及调用draw方法时应使用何种纹理的信息。目前,我一次绘制阵列中的每个磁贴,然后简单地更新磁贴的位置,使其在屏幕上移动。显然,一次绘制所有的瓷砖有点痛苦,我认为如果我只绘制屏幕上可见的瓷砖会更好,这样当瓷砖在屏幕上移动时,会绘制更多的瓷砖。我不知道如何最好地做到这一点?我有点不知所措,不知道该怎么画瓷砖。 任何帮助都将不胜感激。 这是我的level类中的draw和update方法-它只是调用Tile类中的方法来绘制/更新位置C# 如何仅绘制屏幕上可见的平铺(精灵),c#,xna,2d,monogame,side-scroller,C#,Xna,2d,Monogame,Side Scroller,我正在尝试创建一个简单的2d滚动游戏,作为monogame(XNA)中的学习练习。目前,我从文本文件加载平铺信息,创建一个数组(tiles[,]),其中一个平铺对象存储有关平铺写入位置以及调用draw方法时应使用何种纹理的信息。目前,我一次绘制阵列中的每个磁贴,然后简单地更新磁贴的位置,使其在屏幕上移动。显然,一次绘制所有的瓷砖有点痛苦,我认为如果我只绘制屏幕上可见的瓷砖会更好,这样当瓷砖在屏幕上移动时,会绘制更多的瓷砖。我不知道如何最好地做到这一点?我有点不知所措,不知道该怎么画瓷砖。 任何帮
/// <summary>
/// Draws each individual tile in the level.
/// </summary>
private void DrawTiles(SpriteBatch spriteBatch)
{
// For each tile position
for (int y = 0; y < Height; ++y)
{
for (int x = 0; x < Width; ++x)
{
tiles[x, y].Draw(spriteBatch);
}
}
}
public void Update(GameTime gameTime, int scrollSpeed, ScrollDirection direction)
{
// Update the positions of each of the Background sprites
foreach (Tile tile in tiles)
{
tile.Update(gameTime, new Vector2(0, scrollSpeed), scrollDirection);
}
}
}
//
///在标高中绘制每个单独的平铺。
///
专用空心抽瓷砖(SpriteBatch SpriteBatch)
{
//对于每个瓷砖位置
对于(int y=0;y
提前谢谢
现在,我尝试使用从图形设备传递的视口,仅循环通过屏幕上可见的瓷砖进行绘制。我基本上是在尝试绘制之前,通过将屏幕的高度除以瓷砖的高度,再除以宽度,来获得屏幕上可以容纳的瓷砖数量。这工作得很好,它可以绘制视点中所有可见的平铺
唯一的问题是它不再绘制从视口外部开始的任何平铺,因此即使在更新平铺中移动到视口中,它们也不会在循环使用其原始位置时绘制。但是,我想不出一种不在所有瓷砖之间循环的方法来修复此问题:-(
因为关卡可能很大,所以在所有的平铺中循环只绘制屏幕上的内容是非常低效的
如有任何建议,将不胜感激
以下是更新后的图纸:
private void DrawTiles(SpriteBatch spriteBatch)
{
float tileWidth = 40;
float tileHeight = 32;
for (int y = 0; y < (int)Math.Ceiling(mViewport.Height / tileHeight); ++y)
{
for (int x = 0; x < (int)Math.Ceiling(mViewport.Width / tileWidth); ++x)
{
tiles[x, y].Draw(spriteBatch);
}
}
}
private void DrawTiles(SpriteBatch SpriteBatch)
{
浮动瓷砖宽度=40;
浮球高度=32;
对于(int y=0;y<(int)数学天花板(mViewport.Height/tileHeight);+y)
{
对于(int x=0;x<(int)数学天花板(mViewport.Width/tileWidth);+x)
{
瓷砖[x,y]。绘制(spriteBatch);
}
}
}
您需要有关相机的信息。如果您知道相机的中心位置和屏幕大小,您可以进行如下抽签:
private void DrawTiles(SpriteBatch spriteBatch)
{
// For each tile position
for (int y = cameraOffset.Y - screenHeight / 2; y < cameraOffset.Y + (int)Math.Ceiling(screenHeight / 2); ++y)
{
for (int x = cameraOffset.X - screenWidth / 2; x < cameraOffset.X + (int)Math.Ceiling(screenWidth / 2); ++x)
{
tiles[x, y].Draw(spriteBatch);
}
}
}
private void DrawTiles(SpriteBatch SpriteBatch)
{
//对于每个瓷砖位置
对于(int y=cameraOffset.y-screenHeight/2;y
我使用Math.天花的原因是,如果屏幕上有部分瓷砖,它将覆盖。另一侧的Math.Floor是隐含的,因为它是整数除法
请注意,这假设cameraOffset、screenWidth和screenHeight是以分幅为单位的。如果不是,请进行适当的转换。创建名为WINDOW\u WIDTH和WINDOW\u HEIGHT的常量,存储窗口的宽度和高度。然后,按照所示绘制分幅,但仅使用WINDOW\u WIDTH和WINDOW\u HEIGHT值内的分幅。在平铺类中还需要X和Y属性
private void DrawTiles(SpriteBatch spriteBatch)
{
float tileWidth = 40;
float tileHeight = 32;
for (int y = 0; y < (int)Math.Ceiling(mViewport.Height / tileHeight); ++y)
{
for (int x = 0; x < (int)Math.Ceiling(mViewport.Width / tileWidth); ++x)
{
if (tiles[x, y].X <= WINDOW_WIDTH &&
tiles[x, y].X >= 0 &&
tiles[x, y].Y <= WINDOW_HEIGHT &&
tiles[x, y].Y >= 0)
{
tiles[x, y].Draw(spriteBatch);
}
}
}
}
private void DrawTiles(SpriteBatch SpriteBatch)
{
浮动瓷砖宽度=40;
浮球高度=32;
对于(int y=0;y<(int)数学天花板(mViewport.Height/tileHeight);+y)
{
对于(int x=0;x<(int)数学天花板(mViewport.Width/tileWidth);+x)
{
如果(平铺[x,y].x=0&&
平铺[x,y].y=0)
{
瓷砖[x,y]。绘制(spriteBatch);
}
}
}
}
再次感谢迈克,我对相机的这个概念有点迷茫。目前我只根据阵列位置定位磁贴,然后根据以下内容更改磁贴的位置:pritebatch.Draw(mSpriteTexture,position*sizeVector,Color.White);你知道我可以看哪些教程来让我了解如何设置摄像头吗?在本例中,摄像头是屏幕的中心,因此只需将其更改为玩家位置或其他“跟随”即可it@Pectus挖掘如果在你的spriteBatch中为世界设置一个矩阵,你可以轻松地变换整个“2d屏幕”。如果您的屏幕为400x400,并且您的相机位于X=0,Y=0,则它将在0,0到400400之间开始渲染所有内容。除非您缩放或旋转它。矩阵相机=矩阵。创建缩放(缩放)*矩阵。创建旋转Z(MathHelper.ToRadians(度))*矩阵。创建平移(位置X,位置Y,0);然后您只需将位置调整到您想要显示的任何位置。现在您可以将对象的位置设置为400,0(未渲染)但是如果你稍微移动一下相机,它就会显示出来。周围有一大堆2D相机的例子。我找不到我自己用过的那个,但这里有一个类似的例子。好吧,我得到了Mike建议的前提,只在屏幕上的瓷砖上循环。我认为这是一个很好的计划。但是我不明白为什么我不能使用视口让它工作-请看我的r对于代码,我提出了一个问题。当我尝试只循环t时,任何想法都将不胜感激