ich eine 2D-Fliese Matrix (von Wänden bis jetzt) und für jede Wand ich überprüfen, ob mein Player nächstes Rectangle
(nächste wie in wo es in nächster Frame seine) kollidiert mit dieser Wand, und wenn es so ist, möchte ich, dass mein Spieler direkt daneben steht, ohne hineinzugehen. Hier2D-Physik/Kollision Formel funktioniert nicht wie beabsichtigt
ist die Formel, ich kam mit (dies ist nur für linke und rechte Kollision):
//*move entity
if (KState.Down(Keys.W)) en.AddForce(new Vector2(0, -10));
if (KState.Down(Keys.S)) en.AddForce(new Vector2(0, 10));
if (KState.Down(Keys.A)) en.AddForce(new Vector2(-10, 0));
if (KState.Down(Keys.D)) en.AddForce(new Vector2(10, 0));
foreach(Item i in map.Items)
{
//resolve left-right collision
if (en.NextBody(elapsedTime).Intersects(i.Body))
{
//check distance between top left corners
int distance = (int)Math.Abs(i.Position.X - en.Position.X);
//stop player in his horisontal movement
en.AddForce(new Vector2(-en.Force.X, 0));
//place player next to the wall his about to collide with
en.Position = new Vector2(en.Position.X - distance + i.Body.Width, en.Position.Y);
}
}
//stop player in place
if (KState.Clicked(Keys.Space)) en.AddForce(en.Force*-1);
en.Update(elapsedTime);
**
Was mir dieses Ergebnis gab (beachten Sie, dass fps nicht stabil ist und dass zur Zeit Rechtecke Quadrate 32x32) :
Top Textzeile ist Spieler Rectangle
, und unten ist Rectangle
der Wand, dass Spieler mit dem letzten kollidierte.
Jetzt, wenn der Felsen (Spieler) sich nach links bewegt, halte ich die linke Taste für einige Zeit, und wenn ich nach rechts gehe, halte ich die rechte Taste für einige Zeit.
Problem: Wie Sie in gif sehen können, wenn der Spieler nach links geht, bewegt er 1 Pixel von und zur linken Wand. Und wenn er sich nach rechts bewegt, springt er einmal und bleibt dann direkt neben der rechten Wand. Ich möchte nicht springen, aber ich weiß nicht, wie ich das in der Logik, die ich verwende, beheben kann.
Auch, wenn Sie gute Logik wissen, wie Rectangle
Kollision zu lösen, so dass sie nicht von irgendwelchen Seiten schneiden, würde ich appriciate es mit mir zu teilen.
Edit 1: Ich schaffte es, die Kollision auf das richtige Problem zu lösen. Anstelle des obigen Codes habe ich
int sign = Math.Sign(i.Position.X - en.Position.X);
en.AddForce(new Vector2(-en.Force.X, 0));
//wall is right and player is left
if (sign > 0) en.Position = new Vector2(i.Body.Left - en.Body.Width, en.Position.Y);
//wall is left and player is right
if (sign < 0) en.Position = new Vector2(i.Body.Right, en.Position.Y);
gesetzt, aber das Problem mit der linken Seitenkollision ist das gleiche. Ich versuchte
if (sign < 0) en.Position = new Vector2(i.Body.Right + 1, en.Position.Y);
und if (sign < 0) en.Position = new Vector2(i.Body.Right - 1, en.Position.Y);
nur für den Fall, aber das Problem ist das gleiche (auf "...- 1 ..." Fall Player wird in der Wand stecken).
Bearbeiten 2: Wie @paste angefordert, hier ist der Code für NextBody(float elapsedTime)
von Spielerklasse.
public Rectangle NextBody(float elapsedTime)
{ return new Rectangle((int)(force.X * elapsedTime) + body.X, (int)(force.Y * elapsedTime) + body.Y, body.Width, body.Height); }
Haben Sie eine 'en.SetForce()' Methode? Es kann ein Genauigkeitsproblem geben, wenn ein "gleicher" Betrag von der aktuellen Kraft subtrahiert wird, die Restkraft immer noch in dem "en" -Objekt belässt. Das könnte behoben werden, indem man 'en.SetForce (Vector2.Zero)' ' – paste
anruft. Gut geraten, aber ich habe es überprüft und es war wirklich 0. – Monset
Kannst du deinen' NextBody() 'Code posten? – paste