Odbicie kulki od klocka

  2 posts   Feedicon  
Replies: 1 - Last Post: September 02, 2010 06:11
by: kingpig
showing 1 - 2 of 2
 
Posted: September 02, 2010 04:20 by kingpig
Pytanie zadane na forum szóstego semestru

Witam. Robię sobie gierkę na wzór KBounce i mam problem. Jak sprawdzić, jakie powinno nastąpić odbicie (pionowe czy poziome) przy zderzeniu kulki ze ścianką? Dostępne dane to położenie kulki i klocka, wielkość kulki i klocka, wektor przesunięcia kulki.
Narazie robię to tak że gdy kulka spotyka się z klockiem to sprawdzam odległość po X i Y pomiędzy środkiem kulki i klocka i w zależności od tego która odległość jest większa wyznaczam odbicie. Problem jest taki że wektor przesunięcia kulki ma maksymalnie 4px (kulka 14px, klocek 20x20px) i czasem cuda się dzieją. Ma ktoś pomysł?

 
Posted: September 02, 2010 06:11 by kingpig
Siłowałem się z tym problemem, kiedy pisałem prostą gierkę platformową. Trzeba było sprawdzać czy trójkąt (dla sprawdzania kolizji wpisywany w kwadrat):
  • uderza w ścianę (odpowiednik Twojego odbicia poziomego): zerowanie wektora ruchu horyzontalnego
  • uderza w podłogę: zerowanie wektora grawitacji


Funkcja wykrywająca kolizje:
void 
object::findCollisions(object *objCol)
{
  //if difference between positions is smaller or equal
  //to sum of halfs of dimensions
  if(( abs(position.x - objCol->position.x)<=
	   (dimensions.x/2+objCol->dimensions.x/2) ) &&
	 ( abs(position.y - objCol->position.y)<=
	   (dimensions.y/2+objCol->dimensions.y/2) ) &&
	 //and objCol is not an object itself
	 (objCol != ((object*)this)) && 
	 //and objCol is not a ghost
	 !objCol->ghost)
	{
	  processCollision(objCol);
	}

  if(objCol -> hasChild())
	findCollisions((object*)(objCol -> child));

  if( objCol -> hasParent() && !(objCol -> isLast()) )
	findCollisions((object*)(objCol -> next));
}


Jest to proste sprawdzanie, czy 2 prostokąty nachodzą na siebie (mapa zbudowana jest ze stykających się ze sobą czworokątów):

[http://kingpig.org/prawiegry/imagesLinked/tangbang.png]


Dla KBounce również można to zastosować.

Funkcja sprawdzająca rodzaj kolizji pomiędzy bohaterem a prostokątną przeszkodą (wywoływana przez klasę bohatera):
  • objCol - z czym zdrzerza się trójkąt

being::processCollision(object *objCol)
{
  //difference between objects - to reduce positions
  float diffX, diffY;
  diffX = 0;
  diffY = 0;
  
  //when you are a being and you are hitting wall
  //you have to move back :-)
  if (typeid(*objCol) == typeid(block))
	{
	  //only when hitting in walls coordination's changes are necessary
	  
	  //if moving in right direction
	  if(velocity.x > 0)
	{
	  //if wall's left vertical line is between being's vertical lines
	  if(giveMaxX() >= objCol->giveMinX() && giveMinX() < objCol->giveMinX())
		diffX = objCol -> giveMinX() - giveMaxX() + 1;
	}
	  else
	//if moving in left direction
	if(velocity.x < 0)
	  {
		//if wall's right vertical line is between being's vertical lines
		if(giveMinX() <= objCol->giveMaxX() && giveMaxX() > objCol->giveMaxX())
		  diffX = objCol -> giveMaxX() - giveMinX() - 1;
	  }
	  
	  //wall's horizontal line is between being's horizontal lines
	  if(giveMaxY() >= objCol->giveMinY() && giveMinY() < objCol -> giveMinY())
	{
	  diffY = objCol -> giveMinY() - giveMaxY() + 1;
	}
	  
	  position.x += diffX;

	  if(diffY)
	{
	  velocity.y = 0;
	  position.y += diffY;
	}
	}
}


GiveMaxY, GiveMinY, GiveMaxX, GiveMaxX zwracają szukane współrzędne krawędzi horyzontalnych/wertykalnych (funkcje wywoływane na rzecz przeszkody i bohatera).

Także działa rozpoznawanie, czy trójkąt ma się cofnąć w pionie czy poziomie (czy kulka wpadła na ścianę horyzontalną czy wertykalną) Jedyne co mi nawala (pamiętałem jak to naprawić ale już zapomniałem), to zatrzymywanie się bohatera, kiedy wpadnie na róg bloku (przeszkody). Wtedy cofanie następuje w obu kierunkach i trójkąt się trzęsie.

Jeśli opiszesz wpiszesz swoją kulkę w kwadrat, ten sposób może być dobry.
Replies: 1 - Last Post: September 02, 2010 06:11
by: kingpig
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20120127.ac94057)
 
 
Close
loading
Please Confirm
Close