0

我正在编写一个等距游戏,但不幸的是,我一直坚持使用用于从屏幕坐标映射回世界坐标的算法(反之亦然)。无论如何,我无法弄清楚与我的 GetScreenX/Y 方法相反的实现。这是一些代码。width 和 height 表示图块中视口区域的宽度/高度。

通过正确的实现,这应该可以顺利进行。您可以在 Linqpad 中运行它。

void Main()
{
    for(int width = 1;width<15;width++)
    {   
        for(int height = 1;height<10;height++)
        {
            for(int x = -50;x<50;x++){          
                for(int y = -50;y<50;y++){
                    var screenX = GetScreenX(x, y, width, height);
                    var screenY = GetScreenY(x, y, width, height);
                    var worldX = GetWorldX(screenX, screenY, width, height);
                    var worldY = GetWorldY(screenX, screenY, width, height);
                    if (worldX != x || worldY != y)
                    {
                        throw new Exception("Algorithm not right!");    
                    }
                }   
            }
        }
    }
}

protected int GetScreenX(int x, int y, int width, int height)
{
    return WrappingMod(x + y, width);
}

protected int GetWorldX(int x, int y, int width, int height)
{
    return 1; //needs correct implementation
}

protected int GetWorldY(int x, int y, int width, int height)
{
    return 1; //needs correct implementation
}

protected int GetScreenY(int x, int y, int width, int height)
{
    return WrappingMod((int) ((y - x)/2.0), height);
}

static int WrappingMod(int x, int m)
{
    return (x % m + m) % m;
}

很抱歉不得不问,但我无能为力!

4

2 回答 2

0

我不明白你的 WrappingMod 功能。你似乎计算了屏幕坐标,然后取模视口尺寸(两次)只是为了它的地狱。这使您的世界->屏幕映射非双射,因此它没有逆。

一开始你为什么要在彼此的顶部绘制几块瓷砖?

当世界坐标不适合视口时,您应该希望引发异常,而不是取模数。

于 2009-08-19T19:37:08.943 回答
0

您需要两个矩阵:一个用于从视图转换为世界坐标,其逆矩阵用于转换另一种方式。

// my matrices are in 4x4 column-major format

// projection matrix (world -> view)
this.viewTransform.identity()
    .translate(this.viewOrigin)
.scale(1, 0.5, 1)
.rotate(this.viewRotation, 2); // 2 = Z axis

var m = this.viewTransform.current().m;
this.context.setTransform(m[0], m[1], m[4], m[5], m[12], m[13]);

// construct inverse projection matrix (view -> world)
this.viewTransformInv.identity()
    .rotate(-this.viewRotation, 2)
    .scale(1, 2, 0)
    .translate(new Vect4(-this.viewOrigin.x, -this.viewOrigin.y));

// calculate world and map coordinates under mouse
this.viewTransformInv.project(this.mousePos, this.worldPos);

// convert coordinates from view (x, y) to world (x, y, z)
this.worldPos.z = this.worldPos.y;
this.worldPos.y = 0;
this.mapPos[0] = Math.floor(this.worldPos.x / this.TileSideLength);
this.mapPos[1] = Math.floor(this.worldPos.z / this.TileSideLength);
于 2011-10-10T06:52:23.033 回答