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

Bug w mojej minigierce

Object Storage Arubacloud
+1 głos
196 wizyt
pytanie zadane 16 października 2017 w JavaScript przez Riddick Bywalec (2,600 p.)

Zrobiłem sobie minigierkę w js i nie mogę sobie poradzić z jednym bugiem. Efekt jest taki, że jak ma się usunąć kilka obiektów na mapie niektóre z nich się freezują.
Funkcja odpowiadająca za obsługę tych obiektów wygląda nastepująco:

function updateBullets() {
	//PLAYER 1 BULLETS
	var bulletsToRemove1 = new Array();
	bullets1.forEach(function(el,i){
		if(el.x<=0) {
			bulletsToRemove1.push({
				index : i,
				id	  : el.id
			});
		} else {
			el.x-=50;
			$(el.id).css('right',el.x+'px');
			//COLLISION
			if(
			el.x<=x2+90&&
			el.x+50>=x2-10&&
			el.y+20>=y2-10&&
			el.y<=y2+90
			) {
				bulletsToRemove1.push({
					index : i,
					id	  : el.id
				});
				hp2-=10;
				if(hp2<=0) end(1);
			}
		}
	});
	bulletsToRemove1.forEach(function(el){
		bullets1.splice(el.index,1);
		$(el.id).remove();
	});
	//PLAYER 2 BULLETS
	var bulletsToRemove2 = new Array();
	bullets2.forEach(function(el,i){
		if(el.x<=0) {
			bulletsToRemove2.push({
				index : i,
				id	  : el.id
			});
		} else {
			el.x-=50;
			$(el.id).css('left',el.x+'px');
			//COLLISION
			if(
			el.x<=x1+90&&
			el.x+50>=x1-10&&
			el.y+20>=y1-10&&
			el.y<=y1+90
			) {
				bulletsToRemove2.push({
					index : i,
					id	  : el.id
				});
				hp1-=10;
				if(hp1<=0) end(2);
			}
		}
	});
	bulletsToRemove2.forEach(function(el){
		bullets2.splice(el.index,1);
		$(el.id).remove();
	}); 
}

Mam dwie tablice i dwie pętle na każdego gracza. Jedna tablica przechowuje identyfikatory i współrzędne obiektu a druga przechowuje identyfikator i index elementu z pierwszej tablicy do usunięcia. Pierwsza pętla aktualizuje pozycje obiektu oraz wykrywa kolizje oraz wykrywa które obiekty usunąć i zapisuje je do drugiej tablicy. Druga petla po prostu usuwa wskazane elementy tylko tu jest problem bo czasami usuwa nie te elementy co trzeba albo wogóle nie usuwa. Napewno to ma związek z tym że przy każdym usunięciu elementy się przesuwają i nie trafia w ten element ale nie mam pojęcia jak zrobić by wskazało właściwy element do usunięcia.

Tu link do mojej gry, można zobaczyć cały kod wszystko działa po stronie klienta.

http://marcin-kalinowski.pl/games/StarDuel/index.html

1 odpowiedź

+1 głos
odpowiedź 16 października 2017 przez elwood Gaduła (4,180 p.)
wybrane 16 października 2017 przez Riddick
 
Najlepsza
Pierwsze co się rzuca w oczy, to kod wygląda strasznie :). Druga sprawa, od tego typu rzeczy jest canvas.

A co do samego problemu, wydaje mi się, że przyczyna leży w tworzeniu tablic: bulletsToRemove2 i bulletsToRemove1 w funkcji  updateBullets. Przenieś obie tablice do globalnej (fuj) przestrzeni i powinno pomóc. Nie zagłębiałem się w ten kod wiec mogę się mylić.
komentarz 16 października 2017 przez Riddick Bywalec (2,600 p.)
Te tablice muszą być w funkcji gdyż są tylko pomocnicze, przechowują tylko tymczasowe dane, jeśli zrobię je globalne wszystko się sypie. A co jest nie tak z kodem? Bo zawsze robiłem to tak by było jak najbardziej czytelne dla mnie, niekoniecznie dla innych. Canvas. zapamiętam i opanuje. :)
1
komentarz 16 października 2017 przez elwood Gaduła (4,180 p.)
Po prostu tego nie robi się w ten sposób, ale nie o tym tutaj. Te tablice nie mogą być tworzone w tym miejscu. Zauważ że funkcja updateBullets jest wywoływana w setIntervalu (lepsze rozwiązanie to requestAnimationFrame) przez co za każdym tiknięciem interwału tworzona jest nowa tablica, więc w jaki sposób chcesz coś z niej skasować skoro wystrzał był trzy tiknięcia temu? Tablica będzie pusta... Swoją drogą te dwie tablice są zupełnie zbędne. W momencie kolizji albo gdy pocisk opuści mapę po prostu wykonaj na bullets1 i bullets2 metodę splice.
komentarz 16 października 2017 przez Riddick Bywalec (2,600 p.)
Usuwam dane z tablicy globalnej nie z tej definiowanej w funkcji i owszem mogłoby się wydawać że najlepiej będzie, że można by to usunąć w pierwszej pętli i tak zrobiłem na samym początku jednak przy każdym usuwaniu jest pomijany następny element w pętli i się przez jeden tick nie porusza stąd pomysł na tablice pomocniczą. pomyślałem że najpierw spisze adresy obiektów do usunięcia jak w death note i następnie je usunę ale coś z imionami jest nie tak tj. zapisanymi danymi w tablicy pomocniczej :)
requestAnimationFrame - kolejna funkcja warta zapamiętania. :)
Zdaje sobie sprawę że zabrałem się do tego od nie właściwej strony bo i za bardzo nie wiedziałem jak takie gry się robi więc wymyśliłem własny sposób. I dzięki temu pytaniu dowiedziałem się paru istotnych rzeczy :)
komentarz 16 października 2017 przez Riddick Bywalec (2,600 p.)
Pokombinowałem z tym co mówiłeś i wywaliłem te pomocne tablice a usuwam je tak jak mówiłeś w pierwszej pętli. z tym że foreach() zamieniłem na tradycyjne for i podczas usuwania obiektu po prostu cofam tablice o 1. Temat chyba zakończony :)
1
komentarz 16 października 2017 przez elwood Gaduła (4,180 p.)
Zamień jeszcze setInterval na requestAnimationFrame i wtedy w momencie kolizji albo opuszczenia planszy przez pocisk daj na końcu return. Zastąpi to dziwaczny sposób z cofaniem tablicy ;O.

Podobne pytania

0 głosów
0 odpowiedzi 301 wizyt
0 głosów
4 odpowiedzi 673 wizyt
pytanie zadane 1 listopada 2017 w Sieci komputerowe, internet przez Normalny-człowiek Nowicjusz (170 p.)
+4 głosów
2 odpowiedzi 299 wizyt
pytanie zadane 12 października 2017 w Nasze projekty przez Jakub Florkowski Użytkownik (500 p.)

92,568 zapytań

141,420 odpowiedzi

319,617 komentarzy

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

...