Chuyển động mượt mà trong một trò chơi dựa trên gạch


8

Làm thế nào chúng ta có thể làm cho nhân vật của chúng ta di chuyển trơn tru trên gạch? Anh ta di chuyển ngói bằng ngói, nhưng điều đó có vẻ không chuyên nghiệp. Ngoài ra, khi bạn giữ các phím mũi tên, anh ta sẽ kéo qua màn hình. Làm thế nào chúng ta có thể ngăn chặn điều đó xảy ra?


Bạn đang sử dụng số nguyên cho chuyển động của người chơi. Thay vào đó hãy thử sử dụng phao.
Mokosha

1
Tốt nhất là bạn giảm mã của mình xuống mức tối thiểu cần thiết để trình bày / truyền đạt vấn đề / câu hỏi của bạn. Ngoài ra, bạn có thể quan tâm đến câu hỏi này .
kevintodisco

1
Tôi loại bỏ những phần không cần thiết trong câu hỏi của bạn. Tốt nhất là đi đến điểm và không thêm mã bổ sung hoặc lông tơ khác.
MichaelHouse

Câu trả lời:


6

Chuyển động trơn tru có thể đạt được theo một số cách. Và nó thực sự phụ thuộc vào loại chuyển động bạn muốn cho phép.

  • Phong trào vẫn bị hạn chế trong gạch. Loại này là dễ nhất để làm những việc như phát hiện va chạm và kiểm tra chuyển động khác. Đối với loại chuyển động này, bạn chỉ cần nội suy vị trí theo thời gian khi bạn chuyển đổi giữa các ô. Nó có thể đơn giản như việc thêm một cái gì đó như sau vào vòng lặp cập nhật.

Mã giả:

 if(GetDistance(position, targetposition) > minDistance) {
     position = MoveTowards(position, targetposition, deltatime);
 }

Trường hợp MoveTowardschỉ cần vị trí hiện tại và thêm một phần khoảng cách giữa nó và vị trí mục tiêu.

  • Di chuyển không bị hạn chế đối với gạch. Điều này nhận được nhiều khó khăn hơn để thực hiện. Về cơ bản với phương pháp này, bạn chỉ cần lưu trữ vị trí và cập nhật nó thông qua vận tốc. Đó là, thay đổi vị trí theo thời gian.

Giữ phím mũi tên để di chuyển nhân vật cũng có thể được thực hiện theo một vài cách khác nhau. Có khả năng những gì bạn đang làm là một cái gì đó như:

if(keydown(left))
   tilePosition.X--;

Điều này thực sự sẽ khiến nhân vật zip trên màn hình. Vì bạn sẽ cập nhật vị trí nhiều lần trong một giây. Một cách tốt hơn để thực hiện điều này sẽ là thêm một độ trễ. Cái gì đó như

if(keydown(left)) {
    if(leftKeyHeldTimer > movementDelay) {
        tilePosition.X--;
        leftKeyHeldTimer = 0;
    } else {
        leftKeyHeldTimer+= deltaTime;
    }
}

Điều này sẽ thêm một bộ đếm thời gian trễ và chỉ cập nhật vị trí ô vuông khi movementDelaygiá trị đã được đáp ứng.


0

Tôi có thể xác định hai vấn đề. Cái đầu tiên liên quan đến chuyển động mượt mà và cái thứ hai liên quan đến nhân vật tắt màn hình.

Để tạo chuyển động trơn tru, bạn có thể sử dụng một kỹ thuật gọi là Nội suy tuyến tính hoặc (LERP) để chuyển động trơn tru. Về cơ bản cách thức hoạt động của nó là giữa điểm bắt đầu và điểm kết thúc của bạn, bạn tính toán một tập hợp các khoảng cách nhỏ để mô phỏng chuyển động trơn tru và chậm lại khi điểm cuối gần đạt được.

Ví dụ đơn giản nhất của chức năng này sẽ là:

//point1 is the current position, will be starting position on first call
//point2 is the target position
//epsilon is the % of the distance between current and target you want
//to cover per game physics loop (a fixed realworld time based loop).
//The smaller the % the "smoother" the motion.

float lerp(float point1, float point2, float epsilon)
{
    return point1 + epsilon * (point2 - point1);
}

Khi nhân vật di chuyển đến gần điểm 2, nó sẽ dần dần chậm lại. Lưu ý mặc dù họ sẽ không bao giờ thực sự chạm vào điểm 2 nhưng lại vô cùng gần gũi. Bạn sẽ cần phải sửa lỗi này và nếu người chơi nhỏ hơn một khoảng cách vô cùng nhỏ so với điểm 2, chúng ta có thể xem xét người chơi đang ở điểm 2.

Vấn đề thứ hai bạn đề cập có liên quan đến nhân vật của bạn bay ngoài màn hình. Đây là kết quả của đầu vào được đọc mỗi lần làm mới vòng lặp trò chơi kết hợp với chuyển động tức thời giữa các ô.

Lý tưởng nhất để giải quyết điều này, trong mã của bạn, bạn cần phải quyết định

  1. Mất bao nhiêu thời gian trong thế giới thực để nhân vật di chuyển từ điểm 1 đến điểm 2.
  2. Đặt Lerp của bạn để chạy giữa điểm 1 và hai trong khoảng thời gian này
  3. Đọc lại đầu vào một khi điểm 2 đã đạt được để quyết định đi đâu
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.