Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

11

21.01.2018, 22:47

Tatsächlich, war grade schon dabei, ein eigenes Struct zu schreiben :search: noch nie vorher gesehen / genutzt ..

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

12

22.01.2018, 09:31

Das mit dem Konvertieren hat noch ein ziemlich ernsthaftes Problem, speziell mit oben gezeigtem Algorithmus. Durch Rundungsfehler ist deine Bewegungsrichtung schnell mal sowas wie (0.0001, 0.9999). Damit bewegst du dich dann überhaupt nicht, wenn man nach jedem Schritt abrundet. Dann würde es evtl. crashen, weil das Rekursionsende nicht erreicht wird. Man muss also extrem aufpassen, wann man rundet.

Als Ansatz, ich haette sowas in der Art um die Distanz zum nächsten Hindernis zu messen - das waere simpel und uebersichtlich:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
IntVec2 Directions[] = {Dir(0,1), Dir(0,-1), Dir(-1,0), Dir(1,0)};

int Dist = 1;
while(true)
{
    IntVec2 CurPos = StartPos + Dir[moveDirection] * Dist;
    if (Map.Countains(CurPos) && Map.Walkable(CurPos))
    {
        Dist++;
    }
    else
    {
        break;
    }
}

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

13

22.01.2018, 09:47

Aktuell hab ichs so aufgeschrieben

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Cell GetTargetCell(Vector2Int movementDirection) {
 Vector2Int targetCellIndex = new Vector2Int( /* aktuelleZelleMitSpielerX */ , /* aktuelleZelleMitSpielerY */ );

 while (targetCellIndex.x >= 0 &&
  targetCellIndex.y >= 0 &&
  targetCellIndex.x < mapCells.GetLength(0) &&
  targetCellIndex.y < mapCells.GetLength(1) &&
  !mapCells[targetCellIndex.x + movementDirection.x, targetCellIndex.y + movementDirection.y].IsObstacle) 
  {
  targetCellIndex += movementDirection;
  }

 return mapCells[targetCellIndex.x, targetCellIndex.y];
}


aber

1. kann man die Bedingungen garantiert noch runterkürzen

2. gibt es eine Out Of Range Exception, sobald er durch die fünfte Bedingung einen maximalen Index setzt, den es gar nicht mehr gibt.

Ich arbeite jetzt erstmal an 2., aber das ist ja schonmal schön kurz.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Garzec« (22.01.2018, 10:15)


TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

14

22.01.2018, 12:10

Wenn du es kurz mit meinen Vorschlag vergleichst, siehst du direkt das Problem: du checkst nicht ob der Punkt, wo du hinwillst, auf der Map liegt, sondern der wo du herkommst.

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

15

22.01.2018, 21:15

bin ich grade zu blöd für solch ein "einfaches" Problem? ?(

Der Spieler weiß, auf welcher Zelle er steht. Setzen tue ich

C#-Quelltext

1
Vector2Int targetCellIndex = new Vector2Int(cellIndexHorizontal, cellIndexVertical);


so



Laut Debugger scheint die Spieler Position immer korrekt zu sein. Danach mache ich weiter mit dem Code Vorschlag von @TTGC



cellExists scheint laut Debugger ebenfalls richtig gesetzt zu werden. Kommt er in eine out of Range Exception, ist der Index 1 zu viel. Für einen weiteren kleinen Denkanstoß wäre ich sehr dankbar ...

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

16

22.01.2018, 22:29

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        int cellIndexHorizontal = 0;
        int cellIndexVertical = 0;

        for (int x = 0; x < mapCells.GetLength(0); x++)
        {
            for (int y = 0; y < mapCells.GetLength(1); y++)
            {
                Cell mapCell = mapCells[x, y];

                if (mapCell.Equals(playerInfo.CurrentCell))
                {
                    cellIndexHorizontal = x;
                    cellIndexVertical = y;
                }
            }
        }

Sorry, aber WTF?! Jetzt durchläufst du schon wieder die komplette Map, um eine Zelle zu "finden" - ich dachte du hättest eingesehen, dass das Quatsch ist. Du musst dir doch nur die Zellkoordinaten aus den Spielerkoordinaten berechnen und nicht irgendwas in einem riesigen Array suchen.
Der Spieler muss sich keine Zelle merken, sondern allerhöchstens die Koordinaten seiner Zelle. Aber auch das ist unnötig, da du die - wie gesagt - einfach aus der Spielerposition berechnen kannst.
Du machst es dir echt unnötig kompliziert.

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

17

23.01.2018, 06:44

Sorry, ich habe nicht weit genug gedacht. Den Block oben kannst du streichen. Der Spieler hat jetzt nur noch einen Vector2Int Den muss er haben, weil falls es Abstände zu den Zellen geben sollte, kann ich ja nicht mit den wirklichen Positionen rechnen. Also kennt der Spieler jetzt nur noch die Koordinaten der aktuellen Zelle.

Ebenso gehe ich davon aus, dass man den bool, ob eine Zelle innerhalb der Karte liegt, noch kürzen kann. Ich wollte aber erstmal die Exception rausbekommen.



Vor return prüfe ich nochmal, ob sich die Position überhaupt verändern würde. Sonst darf ich ja keine Richtung draufrechnen. Das passt aber noch nicht so ganz, es gibt immer noch die Exception..

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

18

23.01.2018, 06:57

1. Ich denke nicht, dass du die Zellkoordinaten im Spieler speichern musst. Die kannst du ganz sicher berechnen.
2. Steppe doch mal mit dem Debugger durch das Programm, dann wirst du schon merken, was schief läuft.

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

19

23.01.2018, 07:25

Für eine nähere Erklärung, ich benutze das hier: http://www.c-sharpcorner.com/article/sho…ion-in-c-sharp/

Zitat

n the above if clause, Condition1() will not be evaluated because whatever the value of Condition1() the whole expression will be false.If we use & instead of &&, it will execute Condition1() also. So always try to stick with short-circuited version.



Dein Fehler ist aber glaube was anderes, naemlich das if mit dem distance. Distance gibt die Entfernung bis zum Hindernis an, du brauchst also kein if, sondern stattdessen ein Distance =- 1. Alternativ kann du die Zuweisung targetCellIndex = currentCellIndex; immer in der Zeile vor Distance++ ausführen.

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

20

23.01.2018, 13:17

stimmt, die Distanz auf 0 zu setzen (bei keiner Bewegung), bzw. eins abzuziehen, war eine gute Idee.

Dieser Code hier berechnet erstmal fehlerfrei die korrekte Zielposition



Den bool, der prüft, ob eine Zelle noch auf der Karte liegt, könnte ich so abkürzen

C#-Quelltext

1
bool cellExists = Math.Min(mapCells.GetLength(0) - 1, Math.Abs(x)) == x && Math.Min(mapCells.GetLength(1) - 1, Math.Abs(y)) == y;


aber lesbarer gestaltet es den Code nicht wirklich glaube ich und ob dieser Code optimierter ist, ja vielleicht ein wenig..

Ich werde ihn mal ausprobieren. Erstmal ist das Thema hier aber abgeschlossen :) Jetzt hab ich mich aber auch echt blöd angestellt gehabt :D vielen Dank euch!

Werbeanzeige