缩放时正确计算精灵的大小

问题描述

一个摄像机课程。相机具有将相机尺寸和纵横比考虑在内的从世界坐标(贴图平面)转换为屏幕坐标(sdl)的功能

public Point ConvertWorldToScreen(Point worldPoint)
{
    var w = Settings.Resolution.Width; // 800
    var h = Settings.Resolution.Height; // 600
    var ratio = w / h;
    var extents = new Point(ratio * Size,Size); // CameraSize = 5

    var u = (worldPoint.X + extents.X) / (extents.X + extents.X);
    var v = (worldPoint.Y + extents.Y) / (extents.Y + extents.Y);

    return new Point(u * w,(1 - v) * h);
}

在世界平面上,我绘制了一个网格,其中0x0点位于中心,每个格等于一个单位。一个单位认为100像素。

enter image description here

在0x0点,我绘制了一个精灵。子画面大小为128x128像素。如果pixelPerUnit = 100,则子画面的大小为1.28 x 1.28

我使用以下功能绘制精灵:

void Draw(Transform transformTo)
{
    var camera = SceneManager.GetCurrentScene.Camera; // Get the camera object
    var point = camera.ConvertWorldToScreen(transformTo.Position - camera.Transform.Position); // Shift the position of the sprite relative to the position of the camera in the world.

    var center = new SDL.SDL_FPoint();

    size.Width = rect.Width * transformTo.LocalScale.X; // LocalScale default 1x1
    size.Height = rect.Height * transformTo.LocalScale.Y;

    draw_rect.x = (float)(point.X - (size.Width * transformTo.Achor.X)); // Achor by default 0.5 x 0.5,multiplying by the size of the sprite to get the coordinates of the center
    draw_rect.y = (float)(point.Y - (size.Height * transformTo.Achor.Y));
    draw_rect.w = (float)size.Width; // here you need a formula that scales the sprite
    draw_rect.h = (float)size.Height; // and here

    center.x = (float)(draw_rect.w * transformTo.Achor.X);
    center.y = (float)(draw_rect.h * transformTo.Achor.Y);

    SDL.SDL_RendercopyExF(Game.RenderContext,srcTexture.TexturePtr,ref srcTexture.Rectangle,ref draw_rect,transformTo.degrees,ref center,SDL.SDL_RendererFlip.SDL_FLIP_NONE);
}

如果按原样绘制精灵,则它将不考虑相机的大小:

enter image description here

当我不使用Sprite大小的公式时,因为我需要这样做,所以它不起作用。理想情况下,在pixelPerUnit = 128的情况下,无论任何CameraSize,128px的精灵都应完美地适合网格中的正方形。

以防万一,网格绘图代码

public static void DrawGrid()
{
    var color = SceneManager.GetCurrentScene.ClearColor;
    var camera = SceneManager.GetCurrentScene.Camera;
    var size = new Graphics.Rect(100,100);

    SDL.SDL_SetRenderDrawColor(Game.RenderContext,100,0);

    for (int i = -size.Width; i <= size.Width; i++)
    {
        var p1 = camera.ConvertWorldToScreen(new Graphics.Point(i - camera.Transform.Position.X,size.Width - camera.Transform.Position.Y));
        var p2 = camera.ConvertWorldToScreen(new Graphics.Point(i - camera.Transform.Position.X,-size.Width - camera.Transform.Position.Y));
        var p3 = camera.ConvertWorldToScreen(new Graphics.Point(size.Width - camera.Transform.Position.X,i - camera.Transform.Position.Y));
        var p4 = camera.ConvertWorldToScreen(new Graphics.Point(-size.Width - camera.Transform.Position.X,i - camera.Transform.Position.Y));

        SDL.SDL_RenderDrawLineF(Game.RenderContext,(float)p1.X,(float)p1.Y,(float)p2.X,(float)p2.Y);
        SDL.SDL_RenderDrawLineF(Game.RenderContext,(float)p3.X,(float)p3.Y,(float)p4.X,(float)p4.Y);
    }

    var cx1 = camera.ConvertWorldToScreen(new Graphics.Point(0 - camera.Transform.Position.X,size.Width - camera.Transform.Position.Y));
    var cy1 = camera.ConvertWorldToScreen(new Graphics.Point(0 - camera.Transform.Position.X,-size.Width - camera.Transform.Position.Y));
    var cx2 = camera.ConvertWorldToScreen(new Graphics.Point(size.Width - camera.Transform.Position.X,0 - camera.Transform.Position.Y));
    var cy2 = camera.ConvertWorldToScreen(new Graphics.Point(-size.Width - camera.Transform.Position.X,0 - camera.Transform.Position.Y));

    SDL.SDL_SetRenderDrawColor(Game.RenderContext,200,0);
    SDL.SDL_RenderDrawLineF(Game.RenderContext,(float)cx1.X,(float)cx1.Y,(float)cy1.X,(float)cy1.Y);
    SDL.SDL_SetRenderDrawColor(Game.RenderContext,(float)cx2.X,(float)cx2.Y,(float)cy2.X,(float)cy2.Y);
    SDL.SDL_SetRenderDrawColor(Game.RenderContext,color.R,color.G,color.B,color.A);
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)