Problem: Snake Spiel Kolisionsberehnung und Steuerung Hilfe
-
das hilft mir nicht viel ich kenne mich nicht mit java / java script aus
trotzdem danke
-
endlich ist der code zusammen und ich kann kompilieren...
ich glaube das mit der rotation und velocity funtzt net.
kannste mir das ma bidde also code geben?
-
Hmm. Zeig mal was du machst. Das funktioniert sonst so.
-
// Rotation durch Tastendruck verändern m_fRotation += g_pfButtons[TB_KEY_RIGHT] * 30 * fTime; m_fRotation -= g_pfButtons[TB_KEY_LEFT] * 30 * fTime; // maximum 360° danach wieder 0° und umgekehrt if(m_fRotation > 360) m_fRotation = 0; if(m_fRotation < 0) m_fRotation = 360; m_vVelocity = tbVector3(cosf(DEG_TO_RAD(m_fRotation)), 0.0f, DEG_TO_RAD(sinf(m_fRotation))) * 50 * fTime; // Schwanzteile bewegen for(int i = m_iNum; i > 0; i--) { m_vPos[i] = m_vPos[i - 1]; } // Kopf bewegen m_vPos[0] += m_vVelocity;
am anfang wird m_fRotation auf 90 gesetzt, damit die Schlange zu anfang nach rechts läuft, wenn man von oben draf guckt.
die schlange bewegt sich nicht und die richtung lässt sich nicht verändern
-
sry die richtung lässt sich verändern, aber nicht so wie ich das will, sondern viel zu ruckelich.
-
*schlag vor den kopf*
ich idiot!!!!!!!!!!!
ich muss doch einfach den faktor mit dem ich die grad multipliziere niedriger machen........
ein prob bleibt aber noch: alle schlangenteile sind auf mehr oder weniger der selben stelle warum?
-
LOL
tbVector3
Du arbeitest mit der Tribase?
BackToTopic:
m_fRotation += g_pfButtons[TB_KEY_RIGHT] * 30 * fTime; m_fRotation -= g_pfButtons[TB_KEY_LEFT] * 30 * fTime;
Das ist schon sehr komisch.
ich würde das eher so machen:
if (g_pfButtons[TB_KEY_RIGHT]) m_fRotation += 90.0f; if (g_pfButtons[TB_KEY_LEFT]) m_fRotation -= 90.0f;
Hier brauchst du fTime eigentlich nicht, da du ja keine gleichmässige Rotation haben willst, sondern eine "entweder rauf, runter, links, oder rechts" - Schaltung. (OK. Wäre wahrscheinlich mit vector(1,0), (-1,0) (0,1), (0,-1) auch gegangen, aber jetzt kannst du relativ einfach eine Erweitreung für das Spiel schreiben, nämlich die Möglichkeit dich schräg zu bewegen..)
ein prob bleibt aber noch: alle schlangenteile sind auf mehr oder weniger der selben stelle warum?
Du hast ev. einen zu gerngen Abstand zwishcen den Teilen?!
-
Du arbeitest mit der Tribase?
ja hab das buch von David Scherfgen grade durch und Snake ist jetzt mein erstes selbstentwickeltes Spiel.
Hier brauchst du fTime eigentlich nicht, da du ja keine gleichmässige Rotation haben willst, sondern eine "entweder rauf, runter, links, oder rechts" - Schaltung.
dann habe ich mich missverständlich ausgedrückt. Ich wollte sehrwohl gleichmäßige Rotation
Du hast ev. einen zu gerngen Abstand zwishcen den Teilen?!
ja und nein ich hatte nen denkfehler kannste mir villeicht helfen ich krig das net hin.
-
Aso.. Dann zeig mal aktuellen Code her. Und bitte einen genaueren Fehlerbeschreib..
-
#define MAX_TAILS 256 // Die Klasse für die Schlange class CSnakePlayer { public: // Variablen tbVector3 m_vPos[MAX_TAILS]; // Speichert die Position jedes Teils der schlange tbVector3 m_vVelocity; // Speichert die Geschwindigkeit des Kopfes bool m_bExist[MAX_TAILS]; // Speichert welche Schwanzabschnitte existieren bool m_bCrashed; // Ist die Schlange gegen sich oder eine Wand gelaufen? int m_iNum; // Speichert die Teile der Schlange float m_fRotation; // Speichert die Rotation des Kopfes zur berechnung von m_vVelocity // Methoden tbResult Init(); // Initialisiert die Schlange tbResult Move(float fTime); // Bewegt die Schlange tbResult Render(float fTime); // Rendert die Schlange tbResult CreateNewTail(); // Erstellt einen neuen Schwanzabschnitt CSnakePlayer() {for(int i = 0; i < MAX_TAILS; i++) m_bExist[i] = false; m_bCrashed = false; m_iNum = 0;} // Konstruktor };
Die Deklaration der kritischen methoden:
tbResult CSnakePlayer::Init() { // Kopf an Position setzten m_vPos[0] = tbVector3(2.5f, 0.85f, 0.0f); m_iNum++; // Richtung einstellen m_fRotation = 90.0f; // 4 Schwanzabschnitte setzten for(int i = 1; i < 5; i++) { m_bExist[i] = true; m_vPos[i] = tbVector3(1.5f - 1.7f * i, 0.75f, 0.0f); m_iNum++; } return TB_OK; }
zum initialisieren der schlange mit ihren segmenten
tbResult CSnakePlayer::Move(float fTime) { // Wenn nicht schon "gecrashd" if(!m_bCrashed) { // überprüfen ob die Schlange sich selbst berührt hat for(int i = 3; i < m_iNum; i++) { if(tbVector3LengthSq(m_vPos[0] - m_vPos[i]) <= ( 0.85f + 0.75f ) * ( 0.85f + 0.75f )) { // Sound abspielen g_pSnake->m_pSound[4]->PlayNextBuffer(); // m_bcrashed auf true setzten m_bCrashed = true; // zurzeit automatisch weil alle schlangensegmente die gleichen koordinaten haben break; } } // überprüfen ob die Schlange eine Wand berührt hat if((m_vPos[0].x + 0.85f > 20.0f) || (m_vPos[0].x - 0.85f < -20.0f) || (m_vPos[0].z + 0.85f > 15.0f) || (m_vPos[0].z - 0.85 < -20.0f)) { // Sound abspielen g_pSnake->m_pSound[3]->PlayNextBuffer(); // m_bcrashed auf true setzten m_bCrashed = true; } } // Rotation durch Tastendruck verändern m_fRotation -= g_pfButtons[TB_KEY_RIGHT] * 2.5f * fTime; m_fRotation += g_pfButtons[TB_KEY_LEFT] * 2.5f * fTime; // maximum 360° danach wieder 0° if(m_fRotation > 360) m_fRotation = 0; if(m_fRotation < 0) m_fRotation = 360; m_vVelocity = tbVector3(cosf(m_fRotation), 0.0f, sinf(m_fRotation)) * 1 * fTime; // Schwanzteile bewegen for(int i = m_iNum; i > 0; i--) { m_vPos[i] = m_vPos[i - 1]; } // Kopf bewegen m_vPos[0] += m_vVelocity; return TB_OK; }
der fehler: nach dem ersten frame haben alle segmente der Schlange die gleichen koordinaten
-
mal was ganz anderes:
ich würde einen
std::vector <Tpoint>
nehmen und extra dazu die position abspeichern, an der sich gerade der kopf befindet... dadurch hast du das hässliche kopieren nicht mehr und deine schlange ist von der länge her gesehen nicht mehr begrenzt...//sei Tpoint nen pair <int, int> oder irgend so was in der richtung... class Tsnake { public: //typedefs etc typedef std::vector <Tpoint> Tparts; private: Tparts parts; Tparts::size_tpye head; //drehung des kopfes etc //... }
jetzt gibts nur noch ein problem: das verlängern der schlange... aber dafür gibts ja insert... das heißt zwar, dass im schnitt der halbe vector umkopiert werden muss, aber das sollte ja a) nicht das problem sein und b) ist es alles in allem immer noch besser als jz ^^ nur halt, dass dadurch der spiel-"schritt" im vrgl. zum anderen (parts[i] = X; vs parts.insert(Y, X);) wesentlich länger dauert - ich glaube, so etwas sollte man möglichst vermeiden, aber bei nen paar ints sollte das kein prob sein und du wirst ja eh irgendwo nen sleep() oder so haben?!
und das hier halte ich für nich sooo gut: ^^ (mal davon abgesehen, dass ich die ungarische notation ablehne würde vermutlich auch ein int reichen!?
if(m_fRotation > 360) m_fRotation = 0; if(m_fRotation < 0) m_fRotation = 360;
while (m_fRotation >= 360) {m_fRotation -= 360;}; while (m_fRotation < 0) {m_fRotation += 360;};
das hingegen würde so vermutlich nicht nur besser aussehen:
//m_fRotation durch rot ersetzt - sonst brech ich mir noch die finger ^^ for (; rot >= 360; rot -= 360); for (; rot < 0; rot += 360);
aber ich tippe ja ma darauf, dass du meinen Ansatz da oben nicht übernehmen wirst, weil du dann zu viel umschreiben müsstest?!
Außerdem würde ich m_bCrashed nicht als Member-Variable führen sondern beispielsweise der move-methode als return wert geben... vermutlich gäbs nen besseren ansatz, aber mir fällt gerade kein besserer ein - man könnte es auch per try/catch lösen - aber ich würd try/catch nur für fehler nehmen und nicht für so was - also würds doch auf das int /*0 if successfully moved otherwise errorcode*/ Move(...) rauslaufen^^
bb
-
Noch ein kleiner Tipp zur Kollision zweier Kreise bzw. Abstandsberechnung: Wenn man mit dem quadrierten Abstand rechnet, kann man sich das Ziehen der Wurzel sparen und so Rechenzeit sparen, was gerade bei vielen Objekten einiges ausmacht.
-
erstma sry das ich solang nichts von mir hab hören lassen.
zu Fellhuhn: Das habe ich bereits gemacht da ich weiß das ne wurzel ziehen LANGE dauert.
zu Unskilled: erstma danke für deinen aufwand, aber das bringt mir nichts, da ich nicht nur in integer schritten sondern feiner arbeiten will, also nicht wie bei diesen uralt nokia handys wo man eh nur ne 90° drehung und in ganzahlenschritten gehen kann, deshalb funktioniert das nicht, oder ich habs nicht verstanden.
Ich habe eine lösungs idee, die klingt mir ganz plausibel, funktioniert aber nicht. und zwar ich habe ein array was die ganzen richtungen die der kopf einmal hatte weitergibt. also das gleiche wie bisher nur mit der m_vVelocity:
// die geschwindigkeit der einzelnen segmente verschieben for(int i = m_iNum; i > 0; i--) { m_vVelocity[i] = m_vVelocity[i - 1]; } // Die Geschwindigkeit des Kopfes verändern m_vVelocity[0] = tbVector3(sinf(m_fRotation), 0.0f, cosf(m_fRotation)) * 1 * fTime; for(int i = 0; i < m_iNum; i++) { // Die einzelnen Segmente bewegen m_vPos[i] += m_vVelocity[i]; }
zurzeit dreht sich nur der kopf, der rest der schlange bleibt starr, bewegt sich in die richtung gleiche richtung wie der kopf aber nicht in seiner bahn
-
Wenn du Fließkommawürmer haben willst, brauchst du dir doch nur die Punkte merken, an denen der Wurm seine Richtung ändert. Plus Schwanzende und Kopfposition natürlich. Und die beiden jeden Zyklus in Kopfrichtung verschieben. Im Grunde also Linien verwalten.
-
Yazoo schrieb:
zu Unskilled: erstma danke für deinen aufwand, aber das bringt mir nichts, da ich nicht nur in integer schritten sondern feiner arbeiten will, also nicht wie bei diesen uralt nokia handys wo man eh nur ne 90° drehung und in ganzahlenschritten gehen kann, deshalb funktioniert das nicht, oder ich habs nicht verstanden.
Vermutlich hast du es einfach nicht verstanden...
oder willst du mir erzählen, dass dir die Genauigkeit von 1° nicht reicht? Aber das war ja auch nur nen Tip am Rande...
Es ging eigtl hauptsächlich um den vector, den du aber wahrscheinlich wirklich nicht nehmen wolltest - naja, musst du ja selbst wissen, aber ich find die lösung sehr viel besser als deine jetzigebb
-
Fellhuhn schrieb:
Wenn du Fließkommawürmer haben willst, brauchst du dir doch nur die Punkte merken, an denen der Wurm seine Richtung ändert. Plus Schwanzende und Kopfposition natürlich. Und die beiden jeden Zyklus in Kopfrichtung verschieben. Im Grunde also Linien verwalten.
das kling logisch, nur habe ich zur zeit nicht wirklich eine vorstellung wie das als code aussieht.
könntest du mir vielleicht netterweise das mal als code ziegen?thx
-
Im Grunde hast du einen vector in dem mindestens zwei Punkte drin sind: Kopf und Schwanz.
Jeden Zyklus bewegst du den Kopf weiter und den Schwanz in Richtung des nächsten Punktes (in diesem Fall den Kopf).
Drehst du dich nun, hängst du die Position vor dem Kopf in die Liste ein. Also hast du nun drei Elemente, der Kopf bewegt sich in die neue Richtung (immernoch 3 Elemente), der zweite Punkt verändert sich nicht und der letzte, der Schwanz, bewegt sich nun auf den zweiten Punkt zu (halt den nächsten im vector).
Wenn der Abstand zwischen Schwanz und nächsten Punkt einen Schwellwert erreicht, löschst du den zweiten Punkt einfach aus dem vector und somit läuft der Schwanz weiter zum nächsten Punkt. Bist du nicht wieder abgebogen hast du wieder einen vector mit zwei Punkten und bewegst dich auf den Kopf zu.
So in etwa sollte das funktionieren.
-
ok ich galub das habe ich verstanden.
ich weiß nur noch nicht wie ich dann rendere, schließlich hat die Schlange mehr segmente als nur den kopf und das ende vom schwanz
-
Yazoo schrieb:
ok ich galub das habe ich verstanden.
ich weiß nur noch nicht wie ich dann rendere, schließlich hat die Schlange mehr segmente als nur den kopf und das ende vom schwanzDu renderst mehrmals?
Kopf ist ein seperates Objekt und auch der Schwanz. Die Teile dazwischen können ja immer die gleichen sein.Ist jetzt nicht böse gemeint, aber ich habe irgendwie das laue Gefühl, dass dir noch mächtig Grundlagen fehlen.. Vlt. wäre es besser mal etwas simpleres, ev. 2D zu machen, bevor du dich mit 3D auseindandersetzt..
-
Wo gibt es Tutorials zu so 2D Sachen würde ich mir nähmlich auch mal gerne anschauen.