Ne peut pas comprendre inverse de la fonction get Coords du monde pour le jeu isométrique

StackOverflow https://stackoverflow.com/questions/1302086

  •  19-09-2019
  •  | 
  •  

Question

J'écris un jeu isométrique, mais malheureusement j'ai écrit coincé avec l'algorithme utilisé pour le plan retour au monde des coordonnées à partir des coordonnées d'écran (ou peut-être vice-versa). Quoi qu'il en soit, je ne peux pas comprendre les implémentations qui sont l'inverse de mes méthodes GetScreenX / Y. Voici un code. largeur et hauteur représentent le rapport largeur / hauteur de la zone de fenêtre en tuiles.

Avec la mise en œuvre correcte, cela doit traverser sans aucun problème. Vous pouvez l'exécuter dans 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;
}

Désolé d'avoir à demander, mais je suis à la fin de mon esprit!

Était-ce utile?

La solution

Je ne comprends pas votre fonction WrappingMod. Vous semblez calculer coordonnées de l'écran, puis prendre la dimension modulo de la fenêtre (deux fois) juste pour l'enfer de celui-ci. Cela rend votre cartographie écran mondialement> non bijective, il n'a donc pas inverse.

Pourquoi dessinez plusieurs tuiles ontop vous de l'autre pour commencer?

Au lieu de prendre le module, vous devez être désireux de soulever une exception quand le monde coordonnées ne rentre pas dans la fenêtre.

Autres conseils

Vous avez besoin de deux matrices: un pour convertir de vue de coordonnées du monde, et son inverse pour convertir l'inverse

.
// 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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top