Làm thế nào tôi có thể thực hiện cập nhật khung độc lập?


7

Chỉnh sửa: Tôi đã khắc phục sự cố bằng cách thực hiện bước nhảy được sửa đổi và thêm vào, và tốc độ chỉ bằng tốc độ nhảy * t. Đây là những gì tôi có ngay bây giờ:

if (GUI->Space && grounded){
    jumpvelocity = -185.f * 2  / gravity;
    grounded = false;

}

if(!grounded ){
    if(jumpvelocity < terminaly){
        jumpvelocity += 185.f * t * 4  / gravity;
        yvelocity = jumpvelocity * t;
    }
    else{
        jumpvelocity = terminaly;
        yvelocity = jumpvelocity * t / gravity;
    }
}
else{
    yvelocity = 0.f;
    jumpvelocity = 0.f;
}

Cảm ơn đã giúp đỡ.

Tôi đang cố gắng để làm cho trọng lực của tôi để làm việc. Mã tôi có cho đến nay là

if (jumpvelocity < 0){
   yvelocity = jumpvelocity * t *2/gravity;
    jumpvelocity += 185.f*t * 2 / gravity;
}

else if(!grounded ){
    if(yvelocity < terminaly)
        yvelocity += t / gravity;
    else
        yvelocity = terminaly;
}

Trọng lực lên cao, làm cho cao hơn rơi xuống và nhảy chậm hơn. Giá trị mặc định của nó là 1. Jumpvelocity được đặt thành 185 khi người chơi muốn nhảy. Vấn đề của tôi là bạn rơi chậm hơn ở tốc độ khung hình chậm hơn, nhưng bạn nhảy với tốc độ tương tự như thể nó là tốc độ khung hình cao hơn. Làm thế nào tôi có thể làm cho nó khung độc lập? T là thời gian đồng bằng.


Bạn có thể hiển thị mã nơi Velocity được sử dụng để sửa đổi vị trí không?
Jordaan Mylonas

Vì vậy, nhận xét của bạn ... vấn đề là gì? Nó hoạt động chính xác theo cùng một cách cho x và y.
Kỹ sư

Tôi đang sử dụng SFML vì vậy nó chỉ là bạn.Move (xvelocty, yvelocity).
dùng975989

Mã cập nhật của bạn vẫn hoàn toàn có tất cả các vấn đề tôi đã chỉ ra. Bạn không tính trung bình jumpvelocityvới giá trị trước đó của nó khi cập nhật yvelocity, gây ra lỗi chính xác sẽ trở nên tồi tệ hơn ở tốc độ khung hình thấp hơn. Những gì bạn gọi yvelocitythực sự nên là ymovementvì nó là một vận tốc nhân với thời gian. Bạn đang cập nhật jumpvelocitykhi nhân vật không còn chạm đất, không có ý nghĩa vật lý. Kiểm tra của bạn terminalyđược thực hiện trước khi cập nhật, gây ra jumpvelocitylớn hơn terminalyvà xấu đi ở tốc độ khung hình thấp hơn.
sam hocevar

Câu trả lời:


13

Trên mỗi vòng lặp chính:

  1. Kiểm tra bộ đếm thời gian hệ thống của bạn và lưu trữ dưới dạng currentTime(ví dụ: SDL_GetTicks ())
  2. timeDelta = currentTime - lastTime
  3. Chuyển đổi timeDeltathành giây (thường là tính bằng ms hoặc ns), lưu trữ dưới dạngtimeDeltaSeconds
  4. For each entity in entities: entity.position = velocityInUnitsPerSecond * timeDeltaSeconds
  5. lastTime = currentTime (cũng có thể được thực hiện trước bước 1 thay vì ở đây)

... Bạn sẽ cần điều chỉnh các số hiện tại của mình thành đơn vị mỗi giây, tức là chúng sẽ có ý nghĩa ở 1FPS. Ví dụ: nếu bạn dự đoán vận tốc ngang của nhân vật là 2 pixel mỗi phần mười giây, thì bây giờ bạn cần đặt nó là 20 pixel mỗi giây. Bằng cách đó, ở trên sẽ làm việc chính xác.

Đối với một số ứng dụng, tốt hơn là sửa dấu thời gian của bạn với một số tiền nhất định. Trong trường hợp này , timestep != timeDelta. Thứ hai là lượng thời gian hệ thống đã thực sự trôi qua; trước đây là số tiền bạn muốn tiêu thụ từ bộ tích lũy thời gian của bạn mỗi khi bạn áp dụng các cập nhật logic trong trò chơi của mình. Điều này hỗ trợ tích hợp khi bạn đang sử dụng các bộ giải lặp như những công cụ tìm thấy trong các công cụ vật lý nổi tiếng, bởi vì các dấu thời gian phải bằng nhau khi thực hiện phép tính. Trong trường hợp này, vì bạn không chỉ đơn giản là sử dụng hết thời gian bạn còn lại trên mỗi tích tắc, bạn sẽ có các phân số thời gian còn lại và bạn cần tích lũy những thứ này để sử dụng cho các lần đánh sau. Để biết thêm về điều này, hãy đọc Fix Your Timestep của Glenn Fiedler.


Xin lỗi, tôi không chắc làm thế nào để trả lời một câu trả lời, nhưng tôi đã có một dấu thời gian được đặt ở vị trí 1/60 giây hoặc thấp hơn tùy thuộc vào giá trị được trả về. Xvelocity của tôi hoạt động tốt và độc lập với khung (200.f * t), nhưng tốc độ của tôi thì không.
dùng975989

Bạn không muốn velocityInUnitsPerSecondnhưng vận tốc trung bình trong khung thời gian đã trôi qua. Nếu vận tốc không đổi, thì mã của bạn là chính xác. Nếu vận tốc thay đổi tuyến tính, như trường hợp của trọng lực, thì giá trị đó là 0.5 * (OldVelocity + NewVelocity). Mặt khác, bạn có thể cần tích hợp trên một dấu thời gian nhỏ hơn để tránh các vấn đề chính xác.
sam hocevar

0

Dường như không jumpvelocitycần thiết chút nào. Nhảy có nghĩa là ngay lập tức thiết lập vận tốc đến một giá trị nhất định: một khi bàn chân không còn chạm đất, điều duy nhất có thể thay đổi vận tốc là trọng lực (và sức cản không khí, mà bạn thực hiện bằng vận tốc cuối).

Một nhận xét khác: phân chia điểm nổi là cực kỳ chậm. Tôi đề nghị bạn lưu trữ 1.0f / gravitythay vì gravity.

Cuối cùng, có khả năng cho một khung hình yvelocitycó thể lớn hơn terminaly.

Đề xuất của tôi:

if (GUI->Space && grounded) {
    yvelocity = 185.f;
    grounded = false;
} else if (!grounded ) {
    yvelocity += t * inv_gravity;
    if (yvelocity > terminaly)
        yvelocity = terminaly;
}

Và hãy nhớ rằng những điều sau đây là không chính xác:

ypos += t * yvelocity;

Bạn cần phải làm:

ypos += t * 0.5f * (old_yvelocity + yvelocity);
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.