Nhân vật bật khỏi mặt đất do trọng lực


7

Thực hiện lực hấp dẫn trong trò chơi, nhân vật tiếp tục nảy lên xuống một chút khi anh ta chạm đất, khi gỡ lỗi nhân vật về cơ bản là nảy lên và xuống khỏi mặt đất. Không hoàn toàn chắc chắn làm thế nào để giải quyết vấn đề bất kỳ trợ giúp ở đây sẽ được đánh giá rất cao.

Giá trị không đổi

private float gravity = 0.09f;

thêm vào vận tốc nếu nhân vật ở trên mặt đất

if (!isOnGround)
 velocity.Y += gravity;

thêm các ký tự vận tốc tổng thể vào vị trí tổng thể.

position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

Một phần của phương pháp va chạm xác định xem nhân vật có ở trên mặt đất hay không.

for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    // If this tile is collidable,
                    TileCollision collision = Level.GetCollision(x, y, tileMap);
                    if (collision != TileCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = Level.GetBounds(x, y);
                        Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                        float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

                        if (depth != Vector2.Zero)
                        {
                            float absDepthX = Math.Abs(depth.X);
                            float absDepthY = Math.Abs(depth.Y);

                            // Resolve the collision along the shallow axis.
                            if (absDepthY <= absDepthX || collision == TileCollision.Platform)
                            {
                                // If we crossed the top of a tile, we are on the ground.
                                if (previousBottom <= tileBounds.Top)
                                    isOnGround = true;

1
Tại sao không sử dụng một động cơ vật lý hiện có? Farseer mất khoảng một ngày để cảm thấy thoải mái và có thể làm bất cứ điều gì bạn cần.
ClassicThunder

Câu trả lời:


12

Tôi e rằng tôi chưa hiểu đầy đủ về mã va chạm của bạn: nếu có lỗi ngoài một pixel ở đâu đó, sẽ rất khó để phát hiện ra. Nhưng mã vật lý của bạn cần một vài sửa chữa:

  • cập nhật vận tốc nên phụ thuộc vào dấu thời gian, ngay cả khi trọng lực là một hằng số
  • vận tốc dọc nên được đặt thành không nếu trên mặt đất
  • thêm vào vận tốc tổng thể của người dùng là không chính xác; đó là vận tốc trung bình trong khoảng thời gian của khung hình cuối cùng cần được thêm vào. Bài viết này nên giải thích tại sao .

Dẫn đến đoạn mã sau:

Vector2 oldvelocity = velocity;

if (!isOnGround)
    // This will require tweaking the gravity value
    velocity.Y += gravity * (float)gameTime.ElapsedGameTime.TotalSeconds;
else
    velocity.Y = 0.0;

position += 0.5 * (oldvelocity + velocity)
                * (float)gameTime.ElapsedGameTime.TotalSeconds;

+1 Đối với bit về việc sử dụng tích hợp Verlet so với tích hợp Euler. Tôi đã luôn bỏ qua hoặc quên về điều này trước đây.
David Gouveia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.