Kolizja wykryta, ruch nie zatrzymany do końca

1

Cześć, rzućmy najpierw okiem:
user image
Jak widzimy: górne dwa się nie poruszają, natomiast dolny - tak.
Metody odpowiedzialne za kolizje i poruszanie się:

@Override
	public void keyPressed(KeyEvent k) {
		int key = k.getKeyCode();
		switch (key) {
		case KeyEvent.VK_LEFT:
			left = true;
			game.physic.xVel = 2;
			break;
		case KeyEvent.VK_RIGHT:
			right = true;
			game.physic.xVel = 2;
			break;
		case KeyEvent.VK_SPACE:
//jump
			break;

		default:
			break;
		}

	}
	/*
	 * game.lvl1.getX()[i] to ablica z współrzędnymi platform
	 */
	public void move() {
		if (left) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += game.physic.xVel;
				break;

			}
		} else if (right) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] -= game.physic.xVel;
				break;
			}
		}
	}

	public void checkCollision() {
		switch (game.currentLevel()) {
		case 1:
			for (int i = 0; i < game.lvl1.getX().length; i++) {
				if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
					if (game.man.getBounds().getY() < game.lvl1.getBounds(i)
							.getY() && !game.man.isOnGround) {
						/*
						 * kolizja powyżej platformy
						 */
						game.man.setyPos(-2);
						game.man.isOnGround = true;
						break;
					} else if (game.man.getBounds().getY() > game.lvl1
							.getBounds(i).getY() && isJumping) {
						/*
						 * kolizja poniżej
						 */
						game.man.setyPos(2);
						game.man.isOnGround = false;
						break;
					} else if (game.man.getBounds().getX() < game.lvl1
							.getBounds(i).getX() && right) {
						/*
						 * lewa strona
						 */
						game.lvl1.getX()[i] += 2;
						right = false;
						break;
					} else if (game.man.getBounds().getX() > game.lvl1
							.getBounds(i).getX() && left) {
						/*
						 * prawa strona
						 */
						game.lvl1.getX()[i] -= 2;
						left = false;
						break;
					}

				} else {
					game.physic.xVel = 2;
					game.man.isOnGround = false;
				}
			}
		}
	}

	@Override
	public void keyReleased(KeyEvent k) {
		int key = k.getKeyCode();
		switch (key) {
		case KeyEvent.VK_LEFT:
			left = false;
			game.physic.xVel = 0;
			break;
		case KeyEvent.VK_RIGHT:
			right = false;
			game.physic.xVel = 0;
			break;
		case KeyEvent.VK_SPACE:
			break;
		default:
			break;
		}
	}

Jakieś pomysły, jakieś pytania?

0

Ja wiem, że nie na temat - ale czym zrobiłeś to wideo?:D jest mega

0

Nagrywane CamStudio (kodek TechSmith Video Capture) w *.avi, strzałka i renderowanie do *.gif w Camtasia Studio.

2

Okej, zrobiłem to, łapcie rozwiązanie:

//checkCollision() zatrzymuje grawitacje
//colliLeft() sprawdza uderzenie z lewej strony
//colliRight() z prawej

//Nic się już nie przesuwa, nic już nie spada.
		int manCenterX, manCenterY, boxCenterX, boxCenterY;

	public void checkCollision() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			manCenterX = (int) game.man.getBounds().getCenterX();
			manCenterY = (int) game.man.getBounds().getCenterY();
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				boxCenterX = (int) game.lvl1.getBounds(i).getCenterX();
				boxCenterY = (int) game.lvl1.getBounds(i).getCenterY();
				if (manCenterX - boxCenterX < 0
						&& manCenterY - boxCenterY < 0 && !game.man.isOnGround) {
		
					 game.man.yPos-=2;
					
				} else if (manCenterX - boxCenterX > 0
						&& manCenterY - boxCenterY < 0 && !game.man.isOnGround) {

					 game.man.yPos-=2;
				}
			}
		}
	}

	public void colliLeft() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX < 0) {
					System.out.println(game.lvl1.getX()[i]);
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++){
					game.lvl1.getX()[i1] += game.physic.xVel;
					}
				}
			}
		}
	}

	public void colliRight() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX > 0) {
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++){
					game.lvl1.getX()[i1] -= game.physic.xVel;
					}
				}
			}
		}
	}
0

Bug, którego nie przeskoczyłem:
user image
Jeżeli dotykam lewą ściane bez stykania się z podłogą - działa świetnie i nie poruszam się wgłąb niej. Gdy dotykam podłogę i dotkne lewej ściany, wchodze w nią jak w masło.
Czemu przy prawej ścianie tego bugu nie ma, skoro wywoływane są te same czynności, ale w przeciwnym kierunku?

	public void move() {
		if (left) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += game.physic.xVel;
				break;

			}
		} else if (right) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += -game.physic.xVel;
				break;
			}
		}
	}

	int manCenterX, manCenterY, boxCenterX, boxCenterY;

	public void checkCollision() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			manCenterX = (int) game.man.getBounds().getCenterX();
			manCenterY = (int) game.man.getBounds().getCenterY();
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				boxCenterX = (int) game.lvl1.getBounds(i).getCenterX();
				boxCenterY = (int) game.lvl1.getBounds(i).getCenterY();
				if (manCenterY - boxCenterY > 0 || manCenterY - boxCenterY < 0) {
					game.man.setyPos(-2f); //antygrawitacja przy dotykaniu podłogi
				}
			}
		}
	}
//lewa strona ściany
	public void colliLeft() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX < 0) {
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++) {
						System.out.println("WITKA2");
						game.man.setyPos(0.5f); //grawitacja przy dotykaniu ściany z boku
						game.lvl1.getX()[i1] += game.physic.xVel; //ruch w przeciwną stronę - nie wchodze w ściane
					}
				}
			}
		}
	}
	//kolizja z prawej strony ściany
	public void colliRight() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX > 0) {
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++) {
						game.man.setyPos(0.5f);
						game.lvl1.getX()[i1] += -game.physic.xVel;
					}
				}
			}
		}
	}

Metody wywoływane są z nieskończonej pętli w takiej kolejności:

checkCollision();
colliRight();
colliLeft();

1

Sformatowałem troszkę kod, żeby lepiej się w nim orientować (i żeby ładniej formatował go Coyote):

public void move()
{
  if (left)
  {
    switch (game.currentLevel())
    {
      case 1:
        for (int i = 0; i < game.lvl1.getX().length; i++)
          game.lvl1.getX()[i] += game.physic.xVel;

        break;
    }
  }
  else if (right)
  {
    switch (game.currentLevel())
    {
      case 1:
        for (int i = 0; i < game.lvl1.getX().length; i++)
          game.lvl1.getX()[i] += -game.physic.xVel;

        break;
    }
  }
}

int manCenterX, manCenterY, boxCenterX, boxCenterY;

public void checkCollision()
{
  for (int i = 0; i < game.lvl1.getX().length; i++)
  {
    manCenterX = (int) game.man.getBounds().getCenterX();
    manCenterY = (int) game.man.getBounds().getCenterY();

    if (game.man.getBounds().intersects(game.lvl1.getBounds(i)))
    {
      boxCenterX = (int) game.lvl1.getBounds(i).getCenterX();
      boxCenterY = (int) game.lvl1.getBounds(i).getCenterY();

      if (manCenterY - boxCenterY > 0 || manCenterY - boxCenterY < 0)
      {
        game.man.setyPos(-2f);
      }
    }
  }
}

public void colliLeft()
{
  for (int i = 0; i < game.lvl1.getX().length; i++)
  {
    if (game.man.getBounds().intersects(game.lvl1.getBounds(i)))
    {
      if (manCenterX - boxCenterX < 0)
      {
        for (int i1 = 0; i1 < game.lvl1.getX().length; i1++)
        {
          System.out.println("WITKA2");
          game.man.setyPos(0.5f);
          game.lvl1.getX()[i1] += game.physic.xVel;
        }
      }
    }
  }
}

public void colliRight()
{
  for (int i = 0; i < game.lvl1.getX().length; i++)
  {
    if (game.man.getBounds().intersects(game.lvl1.getBounds(i)))
    {
      if (manCenterX - boxCenterX > 0)
      {
        for (int i1 = 0; i1 < game.lvl1.getX().length; i1++)
        {
          game.man.setyPos(0.5f);
          game.lvl1.getX()[i1] += -game.physic.xVel;
        }
      }
    }
  }
}

Znawcą języków z rodziny C nie jestem, ale trochę nie podoba mi się funkcja move - spróbuj przetestować poniższy kod:

public void move()
{
  if (left)
  {
    if (game.currentLevel() == 1)
    {
      for (int i = 0; i < game.lvl1.getX().length; i++)
        game.lvl1.getX()[i] += game.physic.xVel;
    }
  }
  else if (right)
  {
    if (game.currentLevel() == 1)
    {
      for (in i = 0; i < game.lvl1.getX().length; i++)
        game.lvl1.getX()[i] -= game.physic.xVel;
    }
  }
}

W przypadku, gdy drugi warunek jest spełniony zmieniłem instrukcję w pętli na odejmowanie - nie wiem czy to pomoże, ale sprawdź; Poza tym warunek if (right) i game.currentLevel() == 1 (to samo tyczy się warunku z left) można połączyć operatorem koniunkcji - zapoznaj się z nim;

Tak samo sprawdź przy kolizjach z lewej i prawej strony:

public void colliLeft()
{
  for (int i = 0; i < game.lvl1.getX().length; i++)
  {
    if (game.man.getBounds().intersects(game.lvl1.getBounds(i)))
    {
      if (manCenterX - boxCenterX < 0)
      {
        for (int i1 = 0; i1 < game.lvl1.getX().length; i1++)
        {
          game.man.setyPos(0.5f);
          game.lvl1.getX()[i1] += game.physic.xVel;
        }
      }
    }
  }
}

public void colliRight()
{
  for (int i = 0; i < game.lvl1.getX().length; i++)
  {
    if (game.man.getBounds().intersects(game.lvl1.getBounds(i)))
    {
      if (manCenterX - boxCenterX > 0)
      {
        for (int i1 = 0; i1 < game.lvl1.getX().length; i1++)
        {
          game.man.setyPos(0.5f);
          game.lvl1.getX()[i1] -= game.physic.xVel;
        }
      }
    }
  }
}
0

Nie pomogło. Operator AND znam i używam, ale nie mam pojęcia dlaczego go tutaj nie stosowałem.
Tak wygląda keyPressed, może się przyda:

	@Override
	public void keyPressed(KeyEvent k) {
		int key = k.getKeyCode();
		switch (key) {
		case KeyEvent.VK_LEFT:
			left = true;
			game.physic.xVel = 2;
			break;
		case KeyEvent.VK_RIGHT:
			right = true;
			game.physic.xVel = 2;
			break;
		default:
			break;
		}
}

/Dodano/
Przedłużyłem dolną podstawe i zauważyłem, że gdy dotkne mniejszą ściane z prawej (i nadal dotykam podłogi) to nie wpadam pod nią. Problem jest chyba tylko z tą jedną.

/Dodano2/
Postawiłem kilka ścian i teraz na wszystkich zapadam się w dół. Wiem, co jest nie tak, ale nie mam pojęcia jak to zastąpić. Mam na myśli:
game.man.setyPos(0.5f);
To odpowiada za ciągłe spadanie ciała przy dotykaniu ściany z boku. Bez tego klocek gracza zatrzymuje sie.
Bez powyższej linijki przy kolizji bocznej:
user image

1

Hmmm...

Nie wiem naprawdę co jest grane (trochę się nie orientuję w tym kodzie) bo nie znam jego budowy oraz znaczenia obiektów i ich metod, które używasz... Dziwne, że przedtem Ci działało, a teraz nie - widać fizyka postaci jest w jakiś sposób powiązana z układem elementów planszy, a nie powinno tak być;

Nie wiem ile już zdążyłeś napisać, ale może lepiej będzie zacząć od początku - najpierw dobrze zaplanować obiekt postaci oraz planszy a potem kodzić; Chyba, że masz już wszystko zaplanowane ale nie wychodzi, no to trzeba dalej szukać;


Wytłumacz mi co dają Ci te instrukcje:

game.man.setyPos(0.5f);

//i

game.man.setyPos(-2f);

i dlaczego argumenty mają takie wartości a nie inne, bo nie bardzo kumam;

Najlepiej to zakomentuj cały przedstawiony kod żebym wiedział co się w nim dzieje - po identyfikatorach ciężko poznać (może ja taki oporny dziś jestem...?) - wtedy będę mógł coś więcej napisać; Napisz ogólnie co robisz krok po kroku w sprawdzaniu kolizji;

0
Szinek napisał(a):
	public void move() {
		if (left) { //naciśnięcie strzałki w lewo
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += game.physic.xVel; //game.lvl1.getX()[i] jest tablicą współrzędnych wszystkich platform w grze
//tutaj cała klasa z lvl1 http://pastebin.com/vs0ZdiSu
				break;

			}
		} else if (right) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += -game.physic.xVel;
				break;
			}
		}
	}

	int manCenterX, manCenterY, boxCenterX, boxCenterY;

	public void checkCollision() { //sprawdza kolizje na płaszczyźnie Y
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			manCenterX = (int) game.man.getBounds().getCenterX();
			manCenterY = (int) game.man.getBounds().getCenterY();
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				boxCenterX = (int) game.lvl1.getBounds(i).getCenterX();
				boxCenterY = (int) game.lvl1.getBounds(i).getCenterY();
				if (manCenterY - boxCenterY > 0 || manCenterY - boxCenterY < 0) { //jeżeli środkowy punkt osi Y  prostokąta gracza jest większy od środkowego punktu platformy z którą się styka, wtedy...
					game.man.setyPos(-2f); //...antygrawitacja przy dotykaniu podłogi. Grawitacja jest równa 2, co daje nam 0 - daje nam złudzenie stąpania po podłodze
				}
			}
		}
	}
//lewa strona ściany
	public void colliLeft() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX < 0) {
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++) {
						game.man.setyPos(0.5f); //grawitacja przy dotykaniu ściany z boku. Jeżeli pozbędę się tej linii - przy dotknięciu ściany powyżej środkowego punktu Y platformy - grawitacja zamiera tak jak przy stąpaniu po podłodze
						game.lvl1.getX()[i1] += game.physic.xVel; //ruch w przeciwną stronę - nie wchodze w ściane
					}
				}
			}
		}
	}
	//kolizja z prawej strony ściany
	public void colliRight() {
		for (int i = 0; i < game.lvl1.getX().length; i++) {
			if (game.man.getBounds().intersects(game.lvl1.getBounds(i))) {
				if (manCenterX - boxCenterX > 0) {
					for (int i1 = 0; i1 < game.lvl1.getX().length; i1++) {
						game.man.setyPos(0.5f);
						game.lvl1.getX()[i1] += -game.physic.xVel;
					}
				}
			}
		}
	}

//game.physic.xVel jest przy naciśnięciu przycisku prawo/lewo równe 2
//tak naprawdę ta klasa jest zbędna, ale jak już wrzuciłem kod - nie chcę niczego zmieniać póki nie zostanie rozwiązany problem

A do tego mam już plan, gdyby się nie udało błędu zniwelować - wspinaczka po ścianie :)

0
Szinek napisał(a):
Szinek napisał(a):
	
		if (left) { //naciśnięcie strzałki w lewo
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += game.physic.xVel; //game.lvl1.getX()[i] jest tablicą współrzędnych wszystkich platform w grze
//tutaj cała klasa z lvl1 http://pastebin.com/vs0ZdiSu
				break;

			}
		} else if (right) {
			switch (game.currentLevel()) {
			case 1:
				for (int i = 0; i < game.lvl1.getX().length; i++)
					game.lvl1.getX()[i] += -game.physic.xVel;
				break;
			}
		}
	}


A do tego mam już plan, gdyby się nie udało błędu zniwelować - wspinaczka po ścianie :)

Czy mi sie wydaje czy ty przemieszczasz wszystkie platformy podczas ruchu obiektu zamiast samo obiekt?? poza tym .. czemu masz tablice wsp. x?? pewnie też masz analogiczna Y?

0
xxx_xx_x napisał(a):

Czy mi sie wydaje czy ty przemieszczasz wszystkie platformy podczas ruchu obiektu zamiast samo obiekt?? poza tym .. czemu masz tablice wsp. x?? pewnie też masz analogiczna Y?

Chcę, aby gracz był cały czas w oknie, a gdybym nie przesuwał platformami, uciekłby.
Mam 4 tablice dla platform: X, Y, width, height. Każdy indeks w niej ma informacje o jednej platformie. Informacje o nich otrzymuje za pomocą funkcji zwracającej rectangle.getBounds(x[i], y[i], width[i], width[i]).
Dzisiaj napisałem też wstępny edytor mapy, zapisuje właśnie do takich tablic.

I jak już wspomniałem: błąd zamienił się w nową funkcjonalność.

1
Szinek napisał(a):
xxx_xx_x napisał(a):

Czy mi sie wydaje czy ty przemieszczasz wszystkie platformy podczas ruchu obiektu zamiast samo obiekt?? poza tym .. czemu masz tablice wsp. x?? pewnie też masz analogiczna Y?

Chcę, aby gracz był cały czas w oknie, a gdybym nie przesuwał platformami, uciekłby.
Mam 4 tablice dla platform: X, Y, width, height. Każdy indeks w niej ma informacje o jednej platformie. Informacje o nich otrzymuje za pomocą funkcji zwracającej rectangle.getBounds(x[i], y[i], width[i], width[i]).
Dzisiaj napisałem też wstępny edytor mapy, zapisuje właśnie do takich tablic.

I jak już wspomniałem: błąd zamienił się w nową funkcjonalność.

Źle sie do tego zabierasz, za jakiś czas się w tym pogubisz, statyczny obiekt sie nie powinien poruszać.. od tego masz "kamerę", pomyśl ile problemów będziesz miał w przypadku gdy zaczniesz dodawać obiekty ruchome do tego w czasie działania gry(np spawn point potwora - też bedziesz go musiał przemieszczać)? Możesz też zaobserwować drobne rozjeżdżanie sie obiektów w czasie gry, beda sie przemieszczać przez bład obliczen(zakladajac ze uzywasz zmiennych zmiennoprzecinkowych). Najprostsza ale i nie najwydajniejsza implementacja takiej kamery moze byc zwykła klasa np ViewMatrix { int x, int y, int width, int height }. W każdej klatce przed samym rysowaniem, pobierasz wsp. x,y,widht,height prostokata, ktorego chcesz narysować sprawdzasz czy prostokat miesci się w obszarze viewMatrix, jeżeli tak to rysujesz prostokat w pozycji nie prostokat.x, prostokat.y tylko (prostokat.x - viewMatrix.x, prostokat.y - viewMatrix.y, width, height). Podczas przemieszczania manewrujesz tylko viewmatrix, fizyka przestaje być zależna od ruchu mapy.

Co do tych tablic, czemu nie zrobisz klasy np
ObiektStatyczny { float x,y,width, height } i nie zrobisz tablicy takich obiektów?

1

całkowicie źle to robisz

powinieneś rozdzielić logikę na świat i widok
teraz przesuwasz całym światem żeby gracz się poruszał

to co powinieneś zrobić to przesunąć gracza i widok (kamerę)

różnica jest znaczna
powiedzmy że masz dużą mapę z milionem elementów
aktualnie w każdej klatce musisz zmienić współrzędne miliona elementów

w przypadku rozdzielenia na świat i widok wystarczy tylko przesunąć gracza i widok (czyli po prostu narysować obiekty wokół gracza)

0

sry, xxx jeszcze nie było Twojego posta jak czytałem temat i odpowiadałem

a do autora - przeczytaj jakiś kurs tworzenia gier, obejrzyj wykłady na youtube na ten temat, przeczytaj jakąś książkę
teraz to wygląda tak jakbyś się nauczył rysować prostokąt i na tej podstawie próbował napisać już grę ;)

a w tyle linijek kodu i przez taki czas spokojnie można by było spokojnie już strzelić jakąś mario-podobną gierkę

1

Dzięki za bardzo za rady. Poczytam, poszukam i zobaczymy jak to będzie. :)

1
Szinek napisał(a)

I jak już wspomniałem: błąd zamienił się w nową funkcjonalność.

To z jednej strony dobrze, z drugiej źle - nie rozwiązałeś problemu i maskujesz go nowym ficzerem; Ty miałeś rozwiązać problem tak, by wszystko działało według wcześniejszych założeń - no ale jeśli Ci to pasuje i tak może zostać to pół biedy;

gdsgdgsd napisał(a)

powiedzmy że masz dużą mapę z milionem elementów

Rany Boskie, to nowy CS ma być...? :]

gdsgdgsd napisał(a)

w przypadku rozdzielenia na świat i widok wystarczy tylko przesunąć gracza i widok (czyli po prostu narysować obiekty wokół gracza)

Tak to powinno wyglądać, planszę wraz z wszelkimi statycznymi elementami musisz narysować raz, a podczas przemieszczania się postaci jedynie przesuwasz sam widok - o wiele szybciej zostanie to wykonane;

Wiem dlaczego tak chcesz to zrobić, jednak wiąże się z tym pewna komplikacja, bo jeśli postać ma być cały czas idealnie na środku ekranu to co, jeśli dojdziesz do końcowej ściany? Czy będzie taka możliwość dojścia do niej? Jeżeli nigdy nie będziesz mógł przesuwać postaci pod krańce ekranu, to żeby dojść do ściany (tam jakaś drabina będzie albo portal czy inne cudo, do którego musisz dojść żeby skończyć level) będziesz musiał prawą granicę planszy przesunąć aż do połowy ekranu, coś jak na poniższym ruysunku:

Problem_1.png

Patrząc na gry, jakie kiedyś robiono na Pegasus'a jest pewna rzecz, którą dobrze by było zaimplementować, mianowicie obszar na ekranie, po którym postać może się poruszać bez przesuwania widoku - jest to funkcjonalność istniejąca w dużej ilości gier na tę konsolę, w której plansza jest większa, niż ekran - jeszcze lepiej można to zauważyć w grach, w których możesz się cofać (w Mario czy Contra nie można); Twoja plansza ma więszą jedynie szerokość, bo wysokość będzie się mieścić w ekranie, więc kamerę będziesz przesuwać jedynie w poziomie; Musisz sobie zaplanować wielkość takiego obszaru i podczas przesuwania postaci sprawdzaj, czy mieści się w tym obszarze, a jeśli nie - przesuwaj kamerę, ale razem z postacią; Jeśli nie za bardzo wiesz o czym piszę, zobacz jak to wygląda w grach na Pegasus'a - przykład: Contra; Wielkość takiego obszaru nie jest duża - mniej więcej 3 - 4 razy szerokość postaci (wysokość Ciebie nie dotyczy, bo nie musisz przesuwać planszy w pionie):

Problem_2.png

Tak to mniej więcej wygląda; Musisz jeszcze wziąć pod uwagę to, że jeśli dojdziesz do którejść ze ścian granicznych planszy to jej granica musi być ustawiona no granicy monitora i wtedy można przesunąć postać aż do niej; Dochodząc do lewej granicy planszy tak samo - przesuwasz widok ile możesz tak, by lewa granica planszy ustawiona była na lewej granicy monitora i wtedy możesz przesunąć postać aż do samej lewej krawędzi; To jest trudniejsze do zaimplementowania (więcej obliczeń), bo gdy dojdziesz do końca planszy to obszar, w którym możesz przesuwać postać bez przesuwania kamery przestaje być brany pod uwagę - w przeciwnym wypadku nie będziesz mógł dojść do ściany (patrz wyżej);

Postaraj się zaplanować grę jeszcze raz, póki jeszcze nie napisałeś tysięcy linii kodu - potem będziesz sie tylko użerał przy wprowadzaniu nowych funkcjonalności;


Dodatkowo zamieszczam rysunek objaśniający zachowanie postaci na planszy dłuższej i wyższej niż szerokość/wysokość ekranu gdyby naszło Cię kiedyś na zmianę wielkości poziomów:

Problem_3.png

Jeśli zaimplementujesz poruszanie się po obszarze (w którym widok/kamera nie przesuwa się) w poziomie, to obsługa osi Y nie powinna sprawić Ci kłopotu;

Jeszcze jedno co zauważyłem - nie przesuwaj wszystkiego o jeden piksel bo strasznie długo to będzie trwało - poruszaj choćby o dwa - zyskasz na czasie; Wprowadź sobie jakiś odstęp czasu w pętli dla rysowania kolejnych klatek, bo FPS'y będą ściśle uzależnione od mocy obliczeniowej (im szybszy komputer tym szybciej rysowane będą klatki);

1 użytkowników online, w tym zalogowanych: 0, gości: 1