Phương pháp hiệu quả để liên tục cập nhật chuyển động trong một trò chơi phòng thủ tháp?


8

Chúng tôi là bốn chàng trai làm một trò chơi Tower Defense như một dự án ở lớp một tại một trường đại học. Trò chơi sẽ thực sự đơn giản!

  • Ba tòa tháp khác nhau
  • Ba quái vật khác nhau
  • Một bản đồ (có thể thêm một số nếu chúng ta có thời gian)

Trò chơi phải hướng đối tượng.

Cấu trúc lớp như sau

  • Trò chơi - Vẽ đồ họa, vv
  • Cấp độ - Mỗi cấp độ là một đối tượng của lớp này. Mỗi cấp có số lượng đối tượng sóng hữu hạn (trong danh sách)
  • Wave - Chứa danh sách các vật thể quái vật.
  • Quái vật - Đây là một siêu lớp. Chúng tôi tạo các lớp con cho các loại quái vật khác nhau
  • Tháp - Siêu tới tháp. Có các lớp con cho từng loại tháp.

Chúng tôi đang suy nghĩ về cách giải quyết vấn đề mà nhiều đối tượng phải làm công cụ, cùng một lúc, ví dụ, di chuyển một pixel theo một hướng.

Những gì chúng tôi đã đưa ra là ý tưởng thực hiện Timer lớp av, để kiểm soát khi các đối tượng làm việc. Tôi không chắc đây là cách tốt nhất để làm điều đó. Ai đó có thể đưa ra một số ý tưởng tốt về cách giải quyết trường hợp cập nhật liên tục?

Câu trả lời:


12

Hoàn thành mã hóa trò chơi mô tả một vòng lặp Cập nhật tốt. Nó chỉ đơn giản là một vòng lặp while chạy trong lớp chính của bạn thực hiện các thao tác sau (nhiều hơn hoặc ít hơn):

while( game.isRunning )  
{  
  GetInput();
  Update( dt );
  Render();
}

Bạn vượt qua trong một dt (thời gian delta) tùy thuộc vào việc bạn muốn trò chơi của mình chạy ở tốc độ khung hình cố định hay thay đổi. Đối với tốc độ khung hình cố định, điều này là không cần thiết.

Bây giờ để làm những gì bạn muốn làm khá dễ dàng là sử dụng khái niệm vectơ 2D, trong đó một vectơ đại diện cho vị trí của quái vật (x, y) và vectơ vận tốc đại diện cho hướng mà quái vật đang đi (tính theo đơn vị / giây ).

Vì vậy, để tạo ra quái vật với tốc độ khác nhau, tất cả những gì bạn cần làm là thay đổi vectơ vận tốc thành bất cứ điều gì bạn muốn và để hàm monster.update () xử lý nó cho bạn.

Ví dụ:

Monster monster = new Monster();
monster.position = new Vector2( 0, 0 );
monster.velocity = new Vector2( 1, 0 );   // Every frame I want the monster 
                                          // to move 1 unit to the right

Và phương pháp cập nhật của bạn sẽ như thế này (với tốc độ khung hình cố định là 60 khung hình mỗi giây):

monster.position += monster.velocity * ( 1.0f / 60.0f ); // The ( 1.0f / 60.0f ) would  
                                                         // be dt if it was passed into the Update() method

Đây được gọi là phương pháp cập nhật Euler và đây là phương pháp rất dễ dàng và đơn giản để thực hiện các phương trình chuyển động.

Hi vọng điêu nay co ich.


+1 cho lời giải thích tuyệt vời. Tôi muốn nói rằng đáng để đề cập rằng "thời gian thay đổi" không phải là cách tiếp cận duy nhất (mặc dù sở thích cá nhân của tôi) về thời gian của các vòng cập nhật, thời gian thay đổi so với thời gian cố định thường được tranh luận ở những nơi như thế này và đáng giá tìm kiếm :)
Zaky Đức

3

Về cơ bản, tôi sử dụng một vòng lặp cập nhật và không phải là một hệ thống dựa trên sự kiện.

Để cập nhật quái vật, bạn có thể lặp lại một danh sách các quái vật và cập nhật chúng trong vòng cập nhật với, hãy nói, monster.update()

Nếu một con quái vật phải đi bộ, nó phải cập nhật vị trí của nó. Vì vậy, trong phương pháp cập nhật, tôi tính toán vị trí mới trên cơ sở thời gian đã trôi qua, được lưu trữ trong lớp 'bộ đếm thời gian riêng biệt.

Đó phải là tất cả những thứ 'đi bộ';)


Chúng tôi có phương pháp cho phong trào quái vật. Điều đó là đủ đơn giản. Vấn đề là làm thế nào để quái vật di chuyển, và tháp bắn, khi chúng có "tốc độ" khác nhau ...
Øyvind

1
@ Yvind: Chỉ cần chuyển thời gian trôi qua làm tham số cho phương thức cập nhật. Sau đó, một con quái vật có thể tính toán vị trí mới của nó bằng cách di chuyển elapsedTime * movementPerSecond. Hoặc bạn có thể có thời gian hồi chiêu trên tháp bắn súng, if(cooldown > 0){ cooldown -= elapsedTime } else { cooldown = X, shoot(); }v.v.
bummzack

2

Tôi cho rằng nó sẽ đáp ứng mục đích của nó cho một dự án uni, nhưng trong một trò chơi thực sự, tôi sẽ có một lớp quái vật cụ thể, và thay vì phân lớp cho các loại, có các loại quái vật khác nhau được mô tả trong các tệp dữ liệu. Tốc độ, điểm máu, khả năng chống chịu với các loại sát thương và họa tiết khác nhau có thể được mô tả hoàn hảo trong các tệp, nó sẽ giúp bạn dễ dàng thêm các loại quái vật mới vào trò chơi của mình và bạn sẽ không phải biên dịch mỗi khi bạn muốn làm như vậy

Dù sao, về phong trào. Cung cấp cho tất cả các đối tượng "di chuyển" của bạn một biến tốc độ khác nhau. Mỗi khung trong logic trò chơi của bạn, bạn lặp qua tất cả các đối tượng có thể di chuyển đó và làm một cái gì đó như

object.x += Math.cos(object.angle) * object.speed * timeSinceLastIteration;
object.y += Math.sin(object.angle) * object.speed * timeSinceLastIteration;

Điều này áp dụng cho quái vật, tên lửa từ tháp, v.v ...

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.