C# Monogame & Farseer Physics: Сблъсъци

Аз съм начинаещ. Използвам Monogame и Farseer Physics Library в C#. (последни версии)

В моята игра, всеки път, когато моят ball (кръг) удари corner of a rectangle (или дори друг кръг), трябва да промени посоката само по оста Y.

Въпреки това, той не само променя посоката по оста Y (както е предвидено), но също така се премества малко надясно (или съответно наляво), в зависимост от това как сте ударили ъгъла (или друг кръг) . Сякаш някаква сила се прилага върху топката, карайки я да се движи и по оста X.

http://i.imgur.com/rEbNTua.png?1

Това движение е готино и всичко останало и има много смисъл, но в моята игра не е, затова искам да се отърва от него.

Как е възможно ? Предполагам, че трябва да променя някои стойности по подразбиране.

Ето как изглежда моето кодиране:

BallBody.BodyType = BodyType.Dynamic;
BlockBody.BodyType = BodyType.Static;
Ball.LinearVelocity = new Vector(0,-1); // ball going up
BallBody.OnCollision += Ball_OnCollision;

public bool Ball_OnCollision(Fixture f1, Fixture f2, Contact contact)
{
    // if the Ball (f1), collides with the Block (f2)
    if (f2.Body == BlockBody)
    // change the direction of the Ball on Y-Axis
    Ball.LinearVelocity = new Vector(0,-1);
    return true;
}

Също така при високи скорости това се случва:

въведете описание на изображението тук

Въпреки че топката никога не може да премине през блока (тунелиране), искам да знам как мога да поправя това, така че топката никога да не влиза в зоната на блока?


person dimitris93    schedule 28.11.2014    source източник


Отговори (1)


За съжаление, това е изненадващо трудно да се направи с Box2D. Най-доброто, което успях да направя, когато се опитах, беше да запиша скоростта на топката, когато контактът започне, и след това, когато контактът приключи, ръчно да задам скоростта на това, което искам. Това работи добре, когато топката започва и завършва контакт само с един блок наведнъж, но в някои случаи топката може да започне да докосва два блока в една и съща времева стъпка. Ще трябва да погледнете подредбата на блоковете, които е докоснал, и да изчислите сами под какъв ъгъл очаквате да отскочи. В крайна сметка просто се отказах и не си направих труда да отразявам този случай.

person iforce2d    schedule 28.11.2014
comment
за топката би трябвало да е невъзможно да докоснеш два правоъгълника едновременно, защото кръгът докосва долната страна на правоъгълник с точно 1 пиксел точност, а 2 правоъгълника никога не са в един и същи пиксел едновременно, вярно ли е? - person dimitris93; 28.11.2014
comment
Искам да знам ПРЕДВАРИТЕЛНО кога се случва сблъсъкът (1 кадър преди това), така че имам нужда от функция OneFrameBeforeCollision, а не OnCollision, предполагам? как мога да внедря нещо подобно? Има някои свойства на Body.CollisionCategories (Categorie.Cat1, Categorie.Cat2, ..., Categorie.Cat31) знаете ли дали някои от тези 31 правят това, което търся, по-лесно? Не мога да намеря никаква документация за тях. Дори не знам какво правят и дали помагат по някакъв начин на моя случай. - person dimitris93; 28.11.2014
comment
Топката може лесно да докосне два блока едновременно, ако удари място, където два блока се допират един друг, и ги припокрие. За съжаление не е възможна предварителна проверка с Box2D, тъй като няма да има смисъл - как може физическият двигател да разбере дали ще приложите сила преди следващата времева стъпка и ще промените посоката на нещо... - person iforce2d; 28.11.2014
comment
два блока се допират един друг, но моите блокове никога не се докосват един друг, нали? всеки блок започва в края на другия мисля - person dimitris93; 28.11.2014
comment
Е, дори ако има празнина между тях, пак можете да поставите кръг, така че да припокрива два блока едновременно, нали? - person iforce2d; 29.11.2014
comment
Предполагам, че си прав, трябва да го направя ръчно, така че да удари само 1 блок наведнъж, защото не искам да удари 2, постигнах огромен напредък досега, благодаря много - person dimitris93; 29.11.2014