BloopIt spawn Kollision

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

BloopIt spawn Kollision

Beitrag von Raidenkk »

Hey,
ich habe nach langen mal wieder an meinem Projekt weiter gemacht und bin auf folgenden Fehler drauf zu gelaufen ^^:
Interator not incrementable.
1 Kugel lässt sich spawnen aber sobald er an dem Interator kommt kommt halt die Fehlermeldung.
Da ich schon seit Stunden nach einer Lösung suche wollte ich mal schauen was ihr davon haltet :)

std::vector<CBall>::iterator m_i;

Code: Alles auswählen

void CBloopIt::CreateBalls ()
{
	if (m_Player.GetSpawnBall () == true)
	{
		m_Player.SetSpawnBall (false);
		if (m_vBalls.size() > 0)
		{
			for (m_i=m_vBalls.begin(); m_i!=m_vBalls.end(); m_i++)
			{
				if (m_i->GetX() != m_Player.GetX ())
				{
					m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
					std::cout << "Ball Spawned!" << std::endl;
				}
			}
		}
		else
		{
			m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
			std::cout << "Ball Spawned!" << std::endl;
		}
	}
}
simbad
Establishment
Beiträge: 130
Registriert: 14.12.2011, 14:30

Re: BloopIt spawn Kollision

Beitrag von simbad »

Ähnliches hatten wir hier schonmal.

Wenn man einen Iterator hat und der Container verändert wird, ist der iterator ungültig. push_back verändert den vector.
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Raidenkk »

Hmm soll ich den interator weglassen und mir selber nen Zähler basteln?
simbad
Establishment
Beiträge: 130
Registriert: 14.12.2011, 14:30

Re: BloopIt spawn Kollision

Beitrag von simbad »

Nein.

Aber du benutzt den iterator ja im for-statement nachdem du ihn gespawnt hast. Einfach ein break einbauen. Du musst doch den vector eh nicht weiter ablaufen, oder?
Und selbst wenn, dann müsste man den iterator wieder auf den Anfang setzen und neu anfangen.
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Raidenkk »

habe das jetzt mal ausprobiert und festgestellt das es zwar klappt doch leider nur begrenzt. Die erste Kugel wird überprüft doch die anderen nicht die lassen sich überlappen.
Wenn ich den interator vor dem break wider auf begin setze will es nicht so ganz dann lässt sich auch nicht die erste Kugel mehr überprüfen und Zeichnet eine neue Kugel darauf.
Oder habe ich was falsch gemacht :X?

Code: Alles auswählen

void CBloopIt::CreateBalls ()
{
	if (m_Player.GetSpawnBall () == true)
	{
		m_Player.SetSpawnBall (false);
		if (m_vBalls.size() > 0)
		{
			for (m_i=m_vBalls.begin(); m_i!=m_vBalls.end(); m_i++)
			{
				if (m_i->GetX() != m_Player.GetX ())
				{
					m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
					std::cout << "Ball Spawned!" << std::endl;
					m_i = m_vBalls.begin();
					break;
				}
			}
		}
		else
		{
			m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
			std::cout << "Ball Spawned!" << std::endl;
		}
	}
}
Benutzeravatar
Jonathan
Establishment
Beiträge: 2545
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Jonathan »

Ich versteh überhaupt nicht den Sinn, von dem Programmfetzen da. Du willst einen Ball erstellen und gehts dafür die Liste der vorhandenen Bälle durch und erstellst immer dann einen neuen, wenn der aktuelle Ball nicht an der Spielerposition ist? Das ist so wirr, das muss eigentlich falsch sein und wenn nicht gehört da mal mindestens ein erklärendes Kommentar dazu.

Willst du prüfen, ob vor dem Spieler platz ist? Da tu das doch einfach. Durchlauf die Liste und speichere in einem boolean, ob vor dem Spieler Platz ist. Wenn 'ja', erstellst du NACH der Schleife einen Ball, wenn 'nein' eben nicht.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Raidenkk »

Ich möchte beim Spawnen prüfen ob da schon ein ball ist weil die nicht übereinander spawnen sollen ^^
Bergmon
Beiträge: 46
Registriert: 03.05.2003, 16:39
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Bergmon »

Hi, ich reformatiere auch ein Mal den Code ;):

Code: Alles auswählen

void CBloopIt::CreateBalls ()
{
    if (m_Player.GetSpawnBall () == true)
    {
        m_Player.SetSpawnBall (false);
        if (m_vBalls.size() > 0)
        {
            for (m_i=m_vBalls.begin(); m_i!=m_vBalls.end(); m_i++)
            {
                if (m_i->GetX() != m_Player.GetX ())
                {
                    m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
                    std::cout << "Ball Spawned!" << std::endl;
                    m_i = m_vBalls.begin();
                    break;
                }
            }
        }
        else
        {
            m_vBalls.push_back (CBall(m_Player.GetX()*64, m_Player.GetY()*64));
            std::cout << "Ball Spawned!" << std::endl;
        }
    }
}
Und da fallen einem mehrere Sachen ein: Du schreibst leider nichts über die Kollisionsabfrage bzw. die Geometrie. Aus

Code: Alles auswählen

CBall(m_Player.GetX()*64, m_Player.GetY()*64)
nehme ich an, dass du auf einem Gitter mit quadratischen Zellen der Größe 64 arbeitest.
Wenn du einen Ball erzeugen möchtest, dann darf das immer in der Diagonal-Spieler-Zelle passieren. Das passiert immer, wenn es noch keinen gab oder wenn die aktuelle X-Zelle eines Balles nicht mit der Spieler-X-Zelle übereinstimmt. Im letzteren Fall fügst du einen neuen Ball wieder an der Diagonal-Spieler-Zelle ein und fängst die Einfügeprozedur von neuem an.
Fragen:
  • Warum überprüfst du nur die X-Zelle, was ist mit der Y-Zelle?
    Kann es passieren, dass du mehrere Bälle in der Diagonal-Spieler-Zelle einfügst? (Ich denke ja.)
Ich denke, wenn du die beiden Fragen beantwortet hast, wirst du dein Problem lösen können.

Viele Grüße
Bergmon
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Raidenkk »

Hier ist meine Kollision leider habe ich noch Schwierigkeiten einen Ball1 auf Ball2 Stoppen zu lassen weil die sich irgendwie verhaken und einfach in der Luft stehen bleiben.

Code: Alles auswählen

void CBloopIt::Gravity (sf::RenderWindow &Game)
{
	for (std::vector<CBall>::iterator i=m_vBalls.begin(); i!=m_vBalls.end(); i++)
	{
		i->SetFall (true);
		for (std::vector<CBall>::iterator k=m_vBalls.begin(); k!=m_vBalls.end(); k++)
		{
			if (i != k)
			{
				if (i->GetAnimX() == k->GetAnimX() && i->GetAnimY() >= k->GetAnimY()-64)
				{
					i->SetFall (false);
				}
			}
		}

		if (i->GetFall () == true)
		{
			float Fallspeed = i->GetAnimY();
			Fallspeed += 150*Game.GetFrameTime ();
			i->SetAnimY(Fallspeed);

			if (i->GetAnimY() > 448)
			{
				i->SetAnimY(448);
			}
		}

		if (i->GetAnimY() > i->GetY()*64)
		{
			float Temp;
			Temp = i->GetAnimY ();
			i->SetAnimY (Temp);
		}
	}
}
Ich bedanke mich für die Hilfe :)
Bergmon
Beiträge: 46
Registriert: 03.05.2003, 16:39
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Bergmon »

Bitte verwende doch eine gute Formatierung für Programmcode (z.B. mit Tabulatoren siehe Post oben und mit [ code=cpp ][ /code ]-Tag, sonst kann das Lesen des Post wirklich eine Mühe sein.

Ich habe dieses Mal nicht alles genau angeschaut, doch was auffällt: In einem jeder mit jedem Vergleich reicht es, wenn du

Code: Alles auswählen

for (std::vector<CBall>::iterator i = m_vBalls.begin(); i != m_vBalls.end(); i++)
{
    i->SetFall (true);
    for (std::vector<CBall>::iterator k = i + 1; k != m_vBalls.end(); k++)
    {...

prüfst. Das ist dann nur eine Dreiecksmatrix ohne Diagonale. Damit fällt deine If-Abfrage weg und auch die restliche doppelte Interaktion. Vielleicht verursacht sie diese Probleme? Wenn es Bälle sind, dann musst du sie nach der Kollision um den gemeinsamen physikalischen Mindestabstand verrücken (hier schätze ich die Summe der beiden Radien der interagierenden Bälle, bzw. der Durchmesser), da sonst gleich wieder eine Kollision mit dem selben Objekt stattfindet.

Viele Grüße
Bergmon

p.s.:
Was hat

Code: Alles auswählen

float Temp;
Temp = i->GetAnimY ();
i->SetAnimY (Temp);
für eine Funktion? :lol:
Benutzeravatar
Raidenkk
Beiträge: 64
Registriert: 27.11.2011, 02:32
Echter Name: Kevin
Wohnort: Bergkamen
Kontaktdaten:

Re: BloopIt spawn Kollision

Beitrag von Raidenkk »

Es gibt ein mal X und dann gibt es AnimX das ist wie X nur *64.
Und meine Funktion oben ist nicht vollständig ^^.

Code: Alles auswählen

float Temp;
Temp = i->GetAnimY ();
++ Temp;
i->SetAnimY (Temp);
Antworten