• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem przy Vectorze, "ConsoleApplication1.exe has triggered a breakpoint"

Object Storage Arubacloud
0 głosów
368 wizyt
pytanie zadane 24 grudnia 2016 w C i C++ przez karmider013 Początkujący (340 p.)
edycja 24 grudnia 2016 przez karmider013

Witam,

Od pewnego czasu tworzę mini gierkę, à la Space Invaders w SFML'u. Przeciwników  z klasy Enemy (jest ich 10) wrzuciłem do vectora, kiedy następuje zderzenie pocisku z przeciwnikiem następuje usunięcie go z vectora przy użyciu funkcją erase.

Kiedy odpalam grę i wystrzeliwuje pocisk w przeciwnika gra się crashuje i wyskakuje mi taki oto komunikat:

"ConsoleApplication1.exe has triggered a breakpoint", wskazując właśnie na funkcję erase.


// Wykrywanie kolizji pocisku z przeciwnikiem i usunięcie go z vectora
for(int i=0; i<= tab.size()-1; i++)
{ 
		if (sprite_bullet.getGlobalBounds().intersects(tab[i].getBound()))
		{
//tu wskazuje na błąd
			 tab.erase(tab.begin() + i-1);
		}
}




//Część klasy Enemy
#include "Enemy.h"
#include <iostream>

void Enemy::update(float dt)
{}

void Enemy::draw(sf::RenderWindow &window)
{
	window.draw(enemy);
}


void Enemy::spos(float x, float y)
{
	enemy.setPosition(x,y);
}

void Enemy::movel(sf::Time time)
{
	enemy.move(sf::Vector2f(-0.1 * time.asMilliseconds(), 0));
}

void Enemy::movep(sf::Time time)
{
	enemy.move(sf::Vector2f(0.1 * time.asMilliseconds(), 0));
}

sf::FloatRect Enemy::getBound()
{
	sf::FloatRect y = enemy.getGlobalBounds();
	return y;
}



// Rysowanie przeciwników
for (int i = 0; i <= tab.size() - 1; i++)
		{
				tab[i].draw(window);
		}

Jeśli potrzebujecie więcej kodu lub jakieś zdjęcia gry czy coś takiego to tylko napiszcie, a wyślę.

 

Tak wygląda gra, kiedy następuje crash.

 

 

 



Tak wygląda cały komunikat:

A po kliknięciu Continue:

komentarz 24 grudnia 2016 przez Munvik Dyskutant (9,350 p.)

Może coś z funkcją getBounds()

albo

W pętli sprawdzającej kolizję pocisku z Enemy po spełnieniu warunku masz

tab.erase(tab.begin() + i-1);

a jeżeli 0-owy element spełni warunek to erase wygląda tak:

tab.erase(tab.begin()-1);

 i jest crash.

komentarz 24 grudnia 2016 przez criss Mędrzec (172,590 p.)
Dokładnie tak. Poza tym... po co to -1 ?
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)
Nie byłem pewny jak działa ta funkcja i przekopiowałem kawałek kodu ze strony:

http://www.cplusplus.com/reference/vector/vector/erase/

,i zmieniłem go pod mój kod.
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)
A co do tego vectora, to nie wydaje mi się ,że błędem jest to -1, bo nawet kiedy trafię miniona innego niż pierwszy to gra i tak się crashuje.
komentarz 24 grudnia 2016 przez criss Mędrzec (172,590 p.)

Po prostu sprawdź. Anyway - jeśli nie(tylko) to, to bład nie leży w kodzie który pokazałeś.

Btw. po sf::Transformable można dziedziczyć wlasnie po to zeby uniknąć czegoś takiego:

void Enemy::spos(float x, float y)
{
    enemy.setPosition(x,y);
}

 

1 odpowiedź

0 głosów
odpowiedź 24 grudnia 2016 przez Michał Muzyka Pasjonat (24,080 p.)
Wrzuć dokładnego screena błędu lub cały opis pojawiający się w crashu
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)
Wrzucone
komentarz 24 grudnia 2016 przez Michał Muzyka Pasjonat (24,080 p.)
a jak usuniesz usuniesz to -1 to błąd dalej się pojawia?
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)
Tak
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)
Natomiast, dużym problemem może być ruch wrogów. Ogólnie wygląda on tak,że kiedy przeciwnik który występuje jako pierwszy w vectorze dojdzie do końca mapy to wrogowie przechodzą o jeden poziom w dół i zmieniają kierunek. I tu wszystko gra bo jak wiadomo przy usuwaniu obiektu z vectora, wszystkie jego pozostałe elementy "przesuwają się w lewo".
komentarz 24 grudnia 2016 przez karmider013 Początkujący (340 p.)

Ale kiedy minionki poruszają się w prawo, to tutaj sprawdzany jest warunek czy ostatni minionek z vectora dotknął końca mapy. W swoim kodzie nie uwzględniłem tego,że przy usuwaniu z vectora obiektu wszystkie pozostałe przesuwają się w lewo, a więc kod:

if (tab[9].getPosX() >= 750)
					{
			
					}

Jest błędny bo jak zniszczę jednego minionka to warunek odwołuje się do nieistniejącego miejsca w vectorze.

 

Poprawcie mnie jeśli się mylę.

komentarz 24 grudnia 2016 przez Michał Muzyka Pasjonat (24,080 p.)

powinieneś używać iteretorów.
wydaje mi się że przy kodzie na sprawdzanie, przy usunięciu 1 minionka, iteratorem wychodzisz poza zakres.
 

for(auto it = tab.end()-1; it != tab.begin(); --it) 
{ 

        if (sprite_bullet.getGlobalBounds().intersects(it -> getBound()))
             it = tab.erase(it);

}

spróbuj czegoś takiego

Podobne pytania

0 głosów
1 odpowiedź 868 wizyt
0 głosów
1 odpowiedź 2,060 wizyt
pytanie zadane 9 lutego 2016 w C i C++ przez evergreen Użytkownik (680 p.)
0 głosów
1 odpowiedź 90 wizyt

92,552 zapytań

141,399 odpowiedzi

319,534 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...