Problem bei Linienverwaltung
-
Hallo Leute,
sry ich bins schonwieder mit meinem snake spiel.
Ich habe bereits einiges hier erfahren, vor allem bezüglich der bewegung der schlange.
Zum bewegen und rendern der schlange nehme ich Linien.
Also habe ich eine eigene Linien Klasse geschrieben:Line.h:
#define LINE_ERROR_EOL -1 #define LINE_ERROR_FATAL_ERROR -2 #define LINE_OK 0 // Klasse zum speichern der Position der Schlange class CSnakeLine { public: CSnakeLine(); ~CSnakeLine(); void SetNewElement(tbVector3 const& v, bool const& bFirst = false); void ResetPos(); bool ResetFirstPos(tbVector3 const& vFirstPos); bool SetPos(tbVector3 const& vPos); tbVector3 GetNextPos(float fDif, int *iError = NULL); void Init(); void Uninit(); private: unsigned long int m_iNumOfElements; unsigned long int m_iMaxNumOfElements; unsigned long int m_iCurrentElement; tbVector3 *m_pvLineElement; tbVector3 *m_pvLineDir; tbVector3 m_vPos; }; bool PointIsOnLine(tbVector3 vLineStart, tbVector3 vLineEnd, tbVector3 vPoint, float fTollerance = 0.0f);Line.cpp:
//Konstruktor CSnakeLine::CSnakeLine() : m_iNumOfElements(0), m_iMaxNumOfElements(0) { Init(); } // Destruktor CSnakeLine::~CSnakeLine() { Uninit(); } // Fügt ein neues Element hinzu void CSnakeLine::SetNewElement(tbVector3 const& v, bool const& bFirst) { if((m_iNumOfElements + 1) >= m_iMaxNumOfElements) { m_pvLineElement = (tbVector3 *) tbMemReAlloc((void *) m_pvLineElement, sizeof(tbVector3) * (m_iMaxNumOfElements + 126)); m_pvLineDir = (tbVector3 *) tbMemReAlloc((void *) m_pvLineDir, sizeof(tbVector3) * (m_iMaxNumOfElements + 126)); m_iMaxNumOfElements += 126; } m_pvLineElement[m_iNumOfElements] = v; if(!bFirst) m_pvLineDir[m_iNumOfElements] = tbVector3Normalize(m_pvLineElement[m_iNumOfElements] - m_pvLineElement[m_iNumOfElements-1]); m_iNumOfElements++; } // Setzt die Position in der Linie zurück auf den Anfang void CSnakeLine::ResetPos() { m_vPos = m_pvLineElement[0]; m_iCurrentElement = 0; } // Setzt die erste Position der Linie auf vFirstPos bool CSnakeLine::ResetFirstPos(tbVector3 const& vFirstPos) { if(m_iNumOfElements >= 2) { m_pvLineElement[0] = vFirstPos; m_pvLineDir[1] = m_pvLineElement[1] - m_pvLineElement[0]; return true; } return false; } // Setzt die Position bool CSnakeLine::SetPos(const tbVector3 &vPos) { for(unsigned long int i = 0; i < m_iNumOfElements; i ++) { if(PointIsOnLine(m_pvLineElement[i], m_pvLineElement[i+1], vPos, 0.1f)) { m_vPos = vPos; return true; } } ResetPos(); return false; } // Liefert die nächste Position auf der Linie mit dem abstand fDif zurück tbVector3 CSnakeLine::GetNextPos(float fDif, int *iError) { bool bFound = false; tbVector3 vTemp; vTemp = m_vPos + m_pvLineDir[m_iCurrentElement+1] * fDif; // Neue Position berechnen while(!PointIsOnLine(m_pvLineElement[m_iCurrentElement], m_pvLineElement[m_iCurrentElement+1], vTemp, 0.1f)) { if(m_iCurrentElement + 1 >= m_iNumOfElements) { *iError = LINE_ERROR_EOL; ResetPos(); return m_vPos; } fDif -= tbVector3Length(vTemp - m_pvLineElement[m_iCurrentElement+1]); m_iCurrentElement++; vTemp = m_pvLineElement[m_iCurrentElement] + m_pvLineDir[m_iCurrentElement] * fDif; // Neue Position berechnen } m_vPos = vTemp; *iError = LINE_OK; return m_vPos; } // Initialisiert die Linie void CSnakeLine::Init() { m_pvLineElement = (tbVector3 *) tbMemAlloc(sizeof(tbVector3) * 256); m_pvLineDir = (tbVector3 *) tbMemAlloc(sizeof(tbVector3) * 256); m_iMaxNumOfElements = 256; } // Entinitialisiert die Linie void CSnakeLine::Uninit() { TB_SAFE_MEMFREE(m_pvLineElement); TB_SAFE_MEMFREE(m_pvLineDir); } // Berechnet ob der Punkt vPoint auf der Streke von vLineStart bis vLineEnd liegt bool PointIsOnLine(tbVector3 vLineStart, tbVector3 vLineEnd, tbVector3 vPoint, float fTollerance) { float fSX; float fSY; float fSZ; fSX = (vPoint.x - vLineStart.x) / vLineEnd.x; if(fSX < 0 - fTollerance || fSX > 1 + fTollerance) return false; fSY = (vPoint.y - vLineStart.y) / vLineEnd.y; if(fSY < 0 - fTollerance || fSY > 1 + fTollerance) return false; if(fSX < fSY - fTollerance || fSX > fSY + fTollerance) return false; fSZ = (vPoint.z - vLineStart.z) / vLineEnd.z; if(fSZ < 0 - fTollerance || fSZ > 1 + fTollerance) return false; if(!(fSY < fSZ - fTollerance || fSY > fSZ + fTollerance)) return true; return false; }irgendetwas verursacht immer den Fehler LINE_ERROR_EOL (EOL steht für End Of Line).
Ich habe keinen blassen schimmer was ich falsch gemacht habe.
Ich hoffe ihr könnt mir helfen.
-
Glaubs du ersnthaft, dass sich einer deinen ganzen Code durchschaut, um den Fehler zu finden? - Du schreibst nichteinmal, wo genau der Fehler herkommt, was du mit einem Debugger innerhalbt von 2 Minuten rausfinden kannst.
Im übrigen sehe ich keine Zeile Anwendungscode. Du hast lediglich eine Klasse gepostet, mit der wir herzlich wenig anfangen können.
Reduzier deinen Code auf das nötigste und mache eine genaue, wenn möglich lauffähige Version deines Problemes, damit wir das ganze nachvollziehen können. Ansonsten wird hier kaum jemand antworten..
EDIT:
Ich will mal nicht so sein. In deinem Code ist die einzige Funktion, die etwas mit diesem Status macht GetNextPos, also wird der Fehler wohl dort drin sein.. Benutz einfach deinen Debugger. Der ist Gold Wert!
-
Außerdem macht es das nicht leichter, dass Du anscheinend eine API verwendest (das ganze "tb..."-Zeug), uns aber nicht mitteilst, welche.
Gruß,
Simon2.
-
-
//ein Bit per const ref übergeben ?! void SetNewElement(tbVector3 const& v, bool const& bFirst = false); //schon mal was von exceptions gehört? tbVector3 GetNextPos(float fDif, int *iError = NULL); //idR wird so was Destruct oder so genannt void Uninit(); private: //nicht gerade schön: (wieso pointer?) tbVector3 *m_pvLineElement; tbVector3 *m_pvLineDir; tbVector3 m_vPos; };Imho wäre hier eine std::deque <tbVector3> viel besser angebracht - aber ich hab jz auch nciht alles durchgeguckt sondern den code nur überflogen - und hoffe lang genug, um verstanden zu haben, wie du das ganze machst ^^
//und hier übergibst du halt einfach mal alles per value obwohl du oben noch wusstest, wie das mit der const ref geht... bool PointIsOnLine(tbVector3 vLineStart, tbVector3 vLineEnd, tbVector3 vPoint, float fTollerance = 0.0f);{ float fSX; float fSY; float fSZ;Variable deklariert man erst dann, wenn man sie auch braucht (und gleich definieren kann...)
bb
-
Simon2 schrieb:
Außerdem macht es das nicht leichter, dass Du anscheinend eine API verwendest (das ganze "tb..."-Zeug), uns aber nicht mitteilst, welche.
Gruß,
Simon2.
Hehe. Das ist die Tribase-Engine von David Scherfgen.

-
drakon schrieb:
Simon2 schrieb:
Außerdem macht es das nicht leichter, dass Du anscheinend eine API verwendest (das ganze "tb..."-Zeug), uns aber nicht mitteilst, welche.
Gruß,
Simon2.
Hehe. Das ist die Tribase-Engine von David Scherfgen.

Aha - das ist ja wenigstens mal was, was ich in google eingeben kann...

Gruß,
Simon2.
-
Simon2 schrieb:
drakon schrieb:
Simon2 schrieb:
Außerdem macht es das nicht leichter, dass Du anscheinend eine API verwendest (das ganze "tb..."-Zeug), uns aber nicht mitteilst, welche.
Gruß,
Simon2.
Hehe. Das ist die Tribase-Engine von David Scherfgen.

Aha - das ist ja wenigstens mal was, was ich in google eingeben kann...

Gruß,
Simon2.
http://www.scherfgen-software.net/index.php?action=book&subsite=errata
Gibts aber nur mit dem Buch dazu.

Aber die Funktionen/Klassen, die er da benutzt hat sind eigentlich selbstsprechend und sollten klar sein, was sie machen.
- tbVector3 ist halt ein 3D Vektor, das MemFree sollte auch klar sein. Und das Realloc sollte auch klar sein, was es in etwa macht.
-
#define LINE_ERROR_EOL -1 #define LINE_ERROR_FATAL_ERROR -2 #define LINE_OK 0Das ist ziemlich unschön. Wieso machst du es nicht mit
enum?enum LINE_ERROR_TYPE // du hast gleich einen Typen für deine Fehler { LINE_ERROR_EOL = -1, LINE_ERROR_FATAL_ERROR = -2, LINE_OK = 0 };Ich hab jetzt mal deine Grossschreibweise übernommen, normalerweise würde ich das anders machen.
