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

Snake SFML ciało nie porusza się za głową

Object Storage Arubacloud
0 głosów
650 wizyt
pytanie zadane 24 maja 2015 w C i C++ przez Adrian1999 Nałogowiec (34,570 p.)

Witam, JW. posiadam problem stworzyłem po połowie konsolowego snake, i mam problem gdyż ogółem pierwszy element ciała podąża za głową ale jeżeli dodam jeszcze jeden to nie chce się poruszać, mógłby ktoś powiedzieć czemu? tutaj kod

bool Gra::waz(sf::RenderWindow& okno, sf::Sprite& tapeta)
{
	std::vector<float>px, py,pcx,pcy;

	int q = 0; // zmiena która oznacza długość węża
	
	sf::Vector2f pw(300, 200); // Definiuje pozycje węża przy rozpoczeciu gry

	sf::RectangleShape glowa(sf::Vector2f(30, 30)); // Tworzenie głowy węża (kwadrat)
	glowa.setFillColor(sf::Color::Black); // nadawanie koloru wężowi
	glowa.setPosition(pw.x, pw.y); // Nadawanie pozycji wężowi
	sf::RectangleShape cialo; // Tworzenie tabily 20 elementowej która ma odgrywać rolę ciała która będzie wpuszczana do vectora i na koniec rysowane
	std::vector<sf::RectangleShape> cialko; // Tworzymy vektor do przechowywania ciał
	okno.clear(); // czyścimy ekran który otrzymaliśmy poprzez referencje
	kierunek pierwszy;
	pierwszy = prawo;
	bool prawda=false;
okno.setKeyRepeatEnabled(false); // możliwość że gdy trzymamy klawisz postać się porusza,nie trzeba wciskać np 3 razy by zrobić 3 ruchy tylko w odpowiednich klatkach
cialko.push_back(cialo); cialko[0].setSize(sf::Vector2f(30, 30));
cialko[0].setFillColor(sf::Color::Green);
px.push_back(glowa.getPosition().x-50);
py.push_back(glowa.getPosition().y);
	while (okno.isOpen())	
	{
		px.push_back(glowa.getPosition().x);
		py.push_back(glowa.getPosition().y);

		sprawdzkierunek(pierwszy, glowa);

		sf::Event event;
		while (okno.pollEvent(event))
		{
			
		

			switch (event.type)
			{
			case sf::Event::Closed: okno.close(); break;
			case sf::Event::KeyPressed: {

				switch (event.key.code)
				{
				case sf::Keyboard::D: {if (pierwszy != lewo){ pierwszy = prawo; }  }break; // Jeżeli wąż nie porusza się w lewo porusz się w prawo
				case sf::Keyboard::A: {if (pierwszy != prawo){ pierwszy = lewo; } }break;// Jeżeli wąż nie porusza się w prawo idź porusz się w lewo
				case sf::Keyboard::W: {if (pierwszy != dol){ pierwszy = przod; } }break;// Jeżeli wąż nie porusza się w dół porusz się w górę
				case sf::Keyboard::S: {if (pierwszy != przod){  pierwszy = dol; } }break;// Jeżeli wąż nie porusza się w górę porusz się w dół
				case sf::Keyboard::E: {  ++q;cialko.push_back(cialo); cialko[q].setSize(sf::Vector2f(30, 30));
					cialko[q].setFillColor(sf::Color::Green);  if (prawda = false)prawda = true;  }break; // dodaj ciało
				case sf::Keyboard::Q: { return false; }break; // zakończ wykonwywanie funkcji wróć do menu głównego
				}

			}break;
			}

		}
		okno.clear(); // czyść ekran
		okno.draw(tapeta); // background
		okno.draw(glowa); // rysuj głowe			

		if (prawda = true) 
		{
			int i = 0;
			while(i <= q)
			{
				std::cout << i;
				//if (i == 0){
					cialko[i].setPosition(px[liczbaz-i],py[liczbaz-i]);
						liczbaz++;
						okno.draw(cialko[i]);

						

				//	}

	
			//	else
			//	{

			//		cialko[i].setPosition(pcx[i-1]-50,pcy[i-1]);
			//		okno.draw(cialko[i]); // rysujemyy odpowiednie elementy

			//	}
						i++;
		}

		}
		okno.display(); // wyświetlamy na ekranie
		
	}

}

 

1 odpowiedź

+1 głos
odpowiedź 24 maja 2015 przez niezalogowany
Kiedyś zacząłem pisać snake'a, ale z braku czasu projekt porzuciłem. Nie mniej jednak sporo chwil poświęciłem na przemyślenie mechaniki i... Nie rozumiem dlaczego, wszyscy przesuwają każdy element po kolei. Nie łatwiej jest przsunąć tylko ostatni? ;)

Taka moja skromna podpowiedź.
komentarz 24 maja 2015 przez Adrian1999 Nałogowiec (34,570 p.)
Czy to nie powinno być tak że elementy mają podążać za głową? przecież w takim razie muszą się przemieszczać.
komentarz 24 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)

ZlapZabijIZakop ma rację :)

Poruszając snake w "zły" sposób trzeba tak naprawdę odświerzyć każdy z kwadracików snake'a nadając im pozycję poprzedniego kwadratu,

Natomiast poruszając snake w lepszy sposób wystarczy zespawnować nowy kwadrat na nowej pozycji głowy i usunąć ostatni kwadrat.

Włącz sobie jakiegoś snake w necie albo na komputerze w najwolniejszej możliwej prędkości i przpatrz się ruchowi węża. Zauważysz, że tak naprawdę z każdym tickiem gry (odświeżeniem pozycji) jedyne co się zmienia to położenie głowy i położenie zakończenia ogona. Można to wykorzystać, wystarczy usuwać ostatnią pozycję węża i tworzyć nową w nowych koordynatach.

Ciężko to opisać słowami, po prostu przyjżyj się dokładnie ruchowi węża w innych tego typu grach ;)

komentarz 24 maja 2015 przez Adrian1999 Nałogowiec (34,570 p.)
bool Gra::waz(sf::RenderWindow& okno, sf::Sprite& tapeta)
{
	std::vector<float>px, py,pcx,pcy;

	int q = 0; // zmiena która oznacza długość węża
	
	sf::Vector2f pw(300, 200); // Definiuje pozycje węża przy rozpoczeciu gry

	sf::RectangleShape glowa(sf::Vector2f(30, 30)); // Tworzenie głowy węża (kwadrat)
	glowa.setFillColor(sf::Color::Black); // nadawanie koloru wężowi
	glowa.setPosition(pw.x, pw.y); // Nadawanie pozycji wężowi
	sf::RectangleShape cialo; // Tworzenie tabily 20 elementowej która ma odgrywać rolę ciała która będzie wpuszczana do vectora i na koniec rysowane
	std::vector<sf::RectangleShape> cialko; // Tworzymy vektor do przechowywania ciał
	okno.clear(); // czyścimy ekran który otrzymaliśmy poprzez referencje
	kierunek pierwszy;
	pierwszy = prawo;
	bool prawda=false;
okno.setKeyRepeatEnabled(false); // możliwość że gdy trzymamy klawisz postać się porusza,nie trzeba wciskać np 3 razy by zrobić 3 ruchy tylko w odpowiednich klatkach
cialko.push_back(cialo); cialko[0].setSize(sf::Vector2f(30, 30));
cialko[0].setFillColor(sf::Color::Green);
px.push_back(glowa.getPosition().x-90);
py.push_back(glowa.getPosition().y);
	while (okno.isOpen())	
	{
			if (glowa.getPosition().x >= 1280)
			{
				glowa.setPosition(1, glowa.getPosition().y);
			}
		px.push_back(glowa.getPosition().x);
		py.push_back(glowa.getPosition().y);

		sprawdzkierunek(pierwszy, glowa);

		sf::Event event;
		while (okno.pollEvent(event))
		{
			


			switch (event.type)
			{
			case sf::Event::Closed: okno.close(); break;
			case sf::Event::KeyPressed: {

				switch (event.key.code)
				{
				case sf::Keyboard::D: {if (pierwszy != lewo){ pierwszy = prawo; }  }break; // Jeżeli wąż nie porusza się w lewo porusz się w prawo
				case sf::Keyboard::A: {if (pierwszy != prawo){ pierwszy = lewo; } }break;// Jeżeli wąż nie porusza się w prawo idź porusz się w lewo
				case sf::Keyboard::W: {if (pierwszy != dol){ pierwszy = przod;  } }break;// Jeżeli wąż nie porusza się w dół porusz się w górę
				case sf::Keyboard::S: {if (pierwszy != przod){ pierwszy = dol;  } }break;// Jeżeli wąż nie porusza się w górę porusz się w dół
				case sf::Keyboard::E: {  ++q;cialko.push_back(cialo); cialko[q].setSize(sf::Vector2f(30, 30));
					cialko[q].setFillColor(sf::Color::Green);  if (prawda = false)prawda = true;  }break; // dodaj ciało
				case sf::Keyboard::Q: { return false; }break; // zakończ wykonwywanie funkcji wróć do menu głównego
				}

			}break;
			}

		}
		okno.clear(); // czyść ekran
		okno.draw(tapeta); // background
		okno.draw(glowa); // rysuj głowe			

		if (prawda = true) 
		{
			int i = 0;
			while(i <= q)
			{
				std::cout << liczbaz << std::endl;
		
				//if (i == 0){
					cialko[i].setPosition(px[liczbaz-i],py[liczbaz-i]);
						
						okno.draw(cialko[i]);
						if (cialko[i].getPosition().y == glowa.getPosition().y)
						{
							if (cialko[i].getPosition().x == glowa.getPosition().x)
							{
std::cout << "stop";
							}
						}
				{
					
				}
					
						i++;
		}

		}
		okno.display(); // wyświetlamy na ekranie
	liczbaz++;	
	}

}

Stworzyłem coś takiego, czym się to różni ogółem tam jest kasowanie jednego kwadratu i dawanie drugiego, a tu zmienianie pozycji każdemu, i jeżeli ktoś by mógł to podpowiedzcie jak zrobić tak jak napisaliście powyżej

komentarz 25 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
edycja 25 maja 2015 przez MrWeb
Cześć, dzisiaj tak z ciekawości napisałem sobie węża w SFML od zera, tak by zobaczyć ile by mi to zajęło stosując wszystkie techniki przejżystego kodu które znam.

Wiesz, ile to trwało ? +- 3h pisania. To dużo ? Pewnie tak, ale ja dość wolno piszę na klawiaturze, ale mimo tego, w ciągu 3h napisałem CZYSTY KOD który jest bardzo łatwo rozbudować i rozwiązać problemy logiczne.

U Ciebie jest inaczej. Rozumiem, to twój kod, pisz jak chcesz, ale gdy dajesz mi taki kod... Co ja mam z tym zrobić ? Kiedyś nauczysz się zasad czystego kodu i zrozumiesz dlaczego mi to tak przeszkadza.

A teraz o twoim kodzie:

Masz klasę Gra a mimo to, wpakowałeś wszystko do jednej funkcji... Czy naprawdę nie dało się dodać kilku nowych metod oddzielających poszczególne zadania do zrobienia ?

void Gra::init();

void Gra::start();

void Gra::event();

Eh... Dobra, tyle jeśli chodzi o stylistykę, bo będzie, że jestem złośliwy. (Nawet nie wspomnę o wcięciach czy spacjach...)

Miałem poprawić twój kod, ale po kilkunastu minutach stwierdziłem, że łatwiej będzie napisać wszystko od nowa. Tu masz moje rozwiązanie tego programu : http://wklej.org/id/1721337/

A jeśli chodzi Ci tylko o to przemieszczanie węża poprzez usunięcie ostatniego elementu i przestawienie pierwszego (to, o czym wspomniał ZlapZabijIZakop) To jest ono pokazane w liniach 159 - 184
komentarz 25 maja 2015 przez Adrian1999 Nałogowiec (34,570 p.)
edycja 25 maja 2015 przez Adrian1999
Hehe myslisz ze jest to w 1 pliczku hehe dobre zarty :D skoncze projekt pokaze caly kodzik ja voidy poprzenosilem do projektu myslalem ze czytelniej bedzie :D taak, mysle ze za 2-3dni skoncze ogolem chce poswiecic 1 dzien na przestudiowanie mojego kodu, skroceniu go i stworzeniu estetycznie ladnego kodu, udostepnie kod gdy skoncze :D Taak ale zauzylem ze sporo zbednych ,,&" uzylem... Bo moglem zainicjalizowac wszystko w private
komentarz 25 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Oceniłem surowo kod na podstawie tego, co mi wysłałeś :) Ale to dobrze, bo to znaczy, że moje zarzuty są już nieaktualne :) Powodzenia w rozwoju projektu :)
komentarz 25 maja 2015 przez Adrian1999 Nałogowiec (34,570 p.)
Jeszcze pytanie, co to za zmienna auto?
komentarz 25 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Nowość wprowadzona w standardzie c++11 jeśli dobrze pamiętam. auto to uniwersalny typ danych lub inaczej, zmienna szablonowa której typ wyznaczany podczas kompilacji. Jeśli mam funkcję fpow() która zwraca float i napiszę coś takiego auto var = fpow(3); To zmienna var jest typu float. To samo z dowolnym innym typem. Słowa auto używa się najczęściej żeby oszczędzić sobie kilku znaków do zapisania, no bo jeśli funkcjia zwraca typ std::vector* To łatwiej jest napisać słowo auto ;) Po więcej odsyłam do google bo na telefonie strasznie ciężko się pisze

Podobne pytania

+1 głos
1 odpowiedź 258 wizyt
pytanie zadane 23 maja 2015 w C i C++ przez Adrian1999 Nałogowiec (34,570 p.)
+1 głos
2 odpowiedzi 212 wizyt
pytanie zadane 17 maja 2015 w C i C++ przez Adrian1999 Nałogowiec (34,570 p.)
0 głosów
2 odpowiedzi 8,677 wizyt

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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!

...