Ich erstelle ein Grid-basiertes Tactical RPG-Spiel in XNA.
Das Bild unten erklärt die Idee. Aber wenn Sie schon einmal Dwarf Fortress gespielt haben, versuche ich im Grunde, diese 3D-Sichtlinie zu erstellen, und Sie können meine Erklärung ignorieren.
(Außerdem ist es mir egal, wie effizient der Algorithmus derzeit ist.)
Derzeit zeichne ich eine Bresenham-Linie zu jedem Quadrat innerhalb eines Radius, und jedes Quadrat, das ich besuche, überprüfe die Richtung, in die ich gehe, wenn ich auf Wände stoße.
Der folgende Code ist meine Überprüfung, ob eine Position sichtbar ist. sx, sy, sz
ist die Änderung im Raster. Zum Beispiel, wenn die Linie nach Nordosten fährt , sx = 1, sy = -1, sz = 0
. Wenn ich direkt nach oben gehe, wäre es sx=0, sy = 0, sz = 1;
usw.
private bool IsVisible(APoint Cur, int sx, int sy, int sz)
{
bool Visible = true;
if (ValidCoordinates(Cur))
{
int newsx = -1;
int newsy = -1;
int newsz = -1;
switch (sx)
{
case -1:
newsx = 3; //west
break;
case 0:
newsx = -1;
break;
case 1:
newsx = 1; //east
break;
}
switch (sy)
{
case -1:
newsy = 0;// north
break;
case 0:
newsy = -1;
break;
case 1:
newsy = 2; //south
break;
}
switch (sz)
{
case -1:
newsz = 4; // down
break;
case 0:
newsz = -1;
break;
case 1:
newsz = 5; // up
break;
}
if (ValidCoordinates(Cur.X + sx, Cur.Y + sy, Cur.Z + sz))
{
if (newsx != -1 && newsy == -1 && newsz == -1) // X only.
{
if (TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsx))
Visible = true;
else
Visible = false;
}
if (newsx == -1 && newsy != -1 && newsz == -1) // Y only.
{
if (TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsy))
Visible = true;
else
Visible = false;
}
if (newsx != -1 && newsy != -1 && newsz == -1) // X and Y only
{
if (Visible && TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsx))
Visible = true;
else
Visible = false;
if (Visible && TileArray[Cur.X + sx, Cur.Y + sy, Cur.Z + sz].AllowSight(newsy))
Visible = true;
else
Visible = false;
}
}
return Visible;
}
return false;
}
Die Funktion Sicht zulassen ist hier:
public bool AllowSight(int i)
{
if (i == -1)
return true;
if (i >= 0 && i <= 3)
{
if (TileCreateCliff && HDifferenceUp > 0)
{
return false;
}
}
if (i == 4)
{
if (TileVoid)
return true;
else
return false;
}
if (i == 5)
{
if (TileVoid)
return true;
else
return false;
}
return true;
}
Dies funktioniert gut, wenn sich mein Charakter auf der Basisebene befindet, aber wenn ich in höhere Lagen oder nach unten schaue, bricht einfach alles zusammen.
Wie soll ich das umsetzen?
isSolidAt(x,y,z)
Funktion haben, können Sie diese verwenden. Wie Sie die Welt zeichnen, spielt keine Rolle.