基于横向滚动图块的游戏中的相机移动速度比角色慢
The camera in a side-scrolling tile based game in moving slower than the character
在我的横向卷轴游戏中,当角色移动经过特定区域(在世界的左侧)时,相机应该开始移动,直到角色经过下一个区域(在世界的右侧) ).然而,当我穿过第一个区域并且是摄像机应该移动的位置时,它移动得比玩家慢,过了一会儿角色从屏幕上消失了。
我的相机代码(C#):
int worldWidth = world.GetLength(0) * _TILE_WIDTH;
int resX = camera.Width / TILE_WIDTH;
int resY = camera.Height / TILE_HEIGHT;
Bitmap screenBmp = new Bitmap(camera.Width, camera.Height);
Graphics g = Graphics.FromImage(screenBmp);
// upper left corner of the camera in the world
Vector2D pCamera = new Vector2D(p.X + (p.PlayerSize.Width / 2) - (screenBmp.Width / 2), 0);
int oneMoreX_tile = 0; // draw one more tile off the screen?
if (p.X + (p.PlayerSize.Width / 2) < 0 + screenBmp.Width / 2) // past the left zone
{
pCamera.X = 0;
}
else if (p.X + (p.PlayerSize.Width / 2) >= worldWidth - screenBmp.Width / 2) // past the right zone
{
pCamera.X = worldWidth - screenBmp.Width;
}
else // between the zones
{
oneMoreX_tile = 1;
}
int xOffset = (int)pCamera.X % TILE_WIDTH;
int yOffset = (int)pCamera.Y % TILE_HEIGHT;
int startX_tile = (int)pCamera.X / TILE_WIDTH;
int startY_tile = (int)pCamera.Y / TILE_HEIGHT;
for (int i = 0; i < resX + oneMoreX_tile; i++)
{
for (int j = 0; j < resY; j++)
{
int tileValue = world[startX_tile + i, startY_tile + j];
// tile coord in tileset
int x = tileValue % tilesetWidth_tile;
int y = tileValue / tilesetWidth_tile;
// pixel coord in tileset (top left)
int x_px = x * TILE_WIDTH;
int y_px = y * TILE_HEIGHT;
g.DrawImage(tileset,
new Rectangle(i * TILE_WIDTH - xOffset, j * TILE_HEIGHT - yOffset, TILE_WIDTH, TILE_HEIGHT),
new Rectangle(x_px, y_px, TILE_WIDTH, TILE_HEIGHT),
GraphicsUnit.Pixel);
}
}
我不明白的是,我应该计算相机应该从角色位置开始的位置,因此只要相机在移动(即不在一侧),角色就应该始终居中。对我来说它看起来应该有效,但我不明白为什么它不起作用。
我知道问题出在哪里了。这不是相机计算的问题,而是绘制玩家的问题。
玩家的坐标在作品中以像素为单位(介于 0 和 world.GetLength(0) * tile_width 之间)。所以当我画玩家时,我忘了减去相机位置,这样玩家世界就留在相机视图内。 ¨
这是我绘制玩家的代码现在的样子:
g.DrawImage(p.PlayerSpriteCharSet,
new RectangleF(p.X - (float)pCamera.X, p.Y - (float)pCamera.Y, p.PlayerSize.Width, p.PlayerSize.Height),
new Rectangle(new Point(tilesetX_px, tilesetY_px), p.PlayerSpriteSize),
GraphicsUnit.Pixel);
在我的横向卷轴游戏中,当角色移动经过特定区域(在世界的左侧)时,相机应该开始移动,直到角色经过下一个区域(在世界的右侧) ).然而,当我穿过第一个区域并且是摄像机应该移动的位置时,它移动得比玩家慢,过了一会儿角色从屏幕上消失了。
我的相机代码(C#):
int worldWidth = world.GetLength(0) * _TILE_WIDTH;
int resX = camera.Width / TILE_WIDTH;
int resY = camera.Height / TILE_HEIGHT;
Bitmap screenBmp = new Bitmap(camera.Width, camera.Height);
Graphics g = Graphics.FromImage(screenBmp);
// upper left corner of the camera in the world
Vector2D pCamera = new Vector2D(p.X + (p.PlayerSize.Width / 2) - (screenBmp.Width / 2), 0);
int oneMoreX_tile = 0; // draw one more tile off the screen?
if (p.X + (p.PlayerSize.Width / 2) < 0 + screenBmp.Width / 2) // past the left zone
{
pCamera.X = 0;
}
else if (p.X + (p.PlayerSize.Width / 2) >= worldWidth - screenBmp.Width / 2) // past the right zone
{
pCamera.X = worldWidth - screenBmp.Width;
}
else // between the zones
{
oneMoreX_tile = 1;
}
int xOffset = (int)pCamera.X % TILE_WIDTH;
int yOffset = (int)pCamera.Y % TILE_HEIGHT;
int startX_tile = (int)pCamera.X / TILE_WIDTH;
int startY_tile = (int)pCamera.Y / TILE_HEIGHT;
for (int i = 0; i < resX + oneMoreX_tile; i++)
{
for (int j = 0; j < resY; j++)
{
int tileValue = world[startX_tile + i, startY_tile + j];
// tile coord in tileset
int x = tileValue % tilesetWidth_tile;
int y = tileValue / tilesetWidth_tile;
// pixel coord in tileset (top left)
int x_px = x * TILE_WIDTH;
int y_px = y * TILE_HEIGHT;
g.DrawImage(tileset,
new Rectangle(i * TILE_WIDTH - xOffset, j * TILE_HEIGHT - yOffset, TILE_WIDTH, TILE_HEIGHT),
new Rectangle(x_px, y_px, TILE_WIDTH, TILE_HEIGHT),
GraphicsUnit.Pixel);
}
}
我不明白的是,我应该计算相机应该从角色位置开始的位置,因此只要相机在移动(即不在一侧),角色就应该始终居中。对我来说它看起来应该有效,但我不明白为什么它不起作用。
我知道问题出在哪里了。这不是相机计算的问题,而是绘制玩家的问题。
玩家的坐标在作品中以像素为单位(介于 0 和 world.GetLength(0) * tile_width 之间)。所以当我画玩家时,我忘了减去相机位置,这样玩家世界就留在相机视图内。 ¨
这是我绘制玩家的代码现在的样子:
g.DrawImage(p.PlayerSpriteCharSet,
new RectangleF(p.X - (float)pCamera.X, p.Y - (float)pCamera.Y, p.PlayerSize.Width, p.PlayerSize.Height),
new Rectangle(new Point(tilesetX_px, tilesetY_px), p.PlayerSpriteSize),
GraphicsUnit.Pixel);