Hoạt hình tốt hơn của các yếu tố trong SFML / C ++


7

Đây không phải là về hoạt hình các nhân vật hoặc các yếu tố riêng lẻ, tôi hài lòng với các spriteesheets cho điều đó. Những gì tôi đang tìm kiếm là hình ảnh động của các yếu tố trên màn hình.

Ví dụ, trò chơi của tôi bắt đầu và logo bay từ một hướng ngẫu nhiên, sau đó xoay hoặc một cái gì đó và dừng lại ở một vị trí, sau đó một nhân vật trò chơi (một hoặc nhiều) đến từ một bên và thực hiện một số hành động.

Tôi chưa thực hiện nhiều dự án, tôi chỉ viết một trò chơi hoàn chỉnh, vì vậy tôi không biết liệu tôi đã trả lời đúng câu hỏi chưa.

Những gì tôi đã làm là cung cấp cho phần tử vị trí ban đầu và cuối cùng và làm cho nó di chuyển tương ứng và sử dụng các cờ trạng thái để kiểm tra trạng thái của nó. Vấn đề là khi tôi muốn di chuyển nó theo nhiều cách. Tất nhiên, tôi chỉ có thể sử dụng các biến trạng thái và làm cho nó di chuyển, nhưng tôi đã nghĩ rằng phải có một phương pháp tao nhã cho nó

EDIT: Tôi đang xem hoạt hình như trong World of Goo, v.v.

Câu trả lời:


4

Điều này có vẻ như bạn muốn thao tác vị trí và xoay của các đối tượng theo thời gian. AFAIK sfml không cung cấp chức năng này ngay lập tức, nhưng nó khá dễ dàng và đơn giản để tự thực hiện việc này.

Tôi đã từng xây dựng một giải pháp tương tự cho một mô phỏng ba chiều, nhưng nó sẽ dịch tốt sang một ứng dụng đồ họa 2D.

Đầu tiên bạn có hai khái niệm: Manipulatorvà theo ManipulatorManager. Manipulatorlà một lớp cơ sở trừu tượng cho tất cả các loại thao tác của một đối tượng cụ thể, ví dụ như một sprite. Thao tác có thể là tất cả các thuộc tính như vị trí hoặc xoay, di chuyển trên một đường dẫn hoặc bất cứ thứ gì tương tự. Các Managerđồng hồ trạng thái của Manipulatorsvà cập nhật chúng mỗi khung.

Giao diện cho trình thao tác trông giống như thế:

class Manipulator {
public:
    Manipulator(float expiration_time) : expiration_time(expiration_time);
    bool is_expired() { return expiration_time < 0.f; }
    void update(float dt) { this->expiration_time -= dt; }
protected:
    float expiration_time;
}

Một triển khai của lớp này là cái SimpleLineManipulatorcó ảnh hưởng đến vị trí của một sprite trong một thời gian nhất định trên một đường thẳng:

class SimpleLineManipulator {
    SimpleLineManipulator(Sprite *spr, Vector2f begin, Vector2f end, float expiration_time);
    ...
private:
    Sprite* sprite;
    Vector2f begin, end;
    float total_time; // initialized with expiration_time
}

Và đây là cách phương thức cập nhật trông như thế nào (nơi diễn ra hầu hết các công việc):

void SimpleLineManipulator::update(float dt) {
    Manipulator::update(dt);
    Vector2f position = lerp(end, begin, total_time/expiration_time);
    spr->SetPosition(position.x, position.y);
}

Tất cả bạn phải làm bây giờ là gọi update()phương thức mỗi khung. Thật dễ dàng để thực hiện một trình điều khiển xoay hoặc trình điều khiển hoạt động trên một đường dẫn (một danh sách các vị trí). Bây giờ bạn cũng có thể kết hợp các thao tác này để tạo hiệu ứng kết hợp.

Tôi hy vọng tôi có thể phác thảo kiến ​​trúc một cách rõ ràng. Mạnh dạn hỏi :)


Đó là một lời giải thích khá tốt! Cảm ơn bạn. Chỉ cần một câu hỏi nhanh, các lớp phần tử có nên kế thừa từ lớp Manipulator không?
tecfreak

1

Constantinius đã cung cấp một điểm khởi đầu tốt từ nơi bạn có thể bắt đầu với mã hóa thực tế, nhưng trong trường hợp bạn muốn biết về những gì bạn đang làm ở đây nói chung, tôi muốn thêm một vài từ.

Dịch các đối tượng theo thời gian từ điểm A đến điểm B được thực hiện bằng cách áp dụng hàm f (x) vào vị trí của đối tượng, trong đó x có thể là bất cứ thứ gì, từ đơn giản là vị trí hiện tại của sprite đến khoảng thời gian trôi qua giữa hai khung, v.v.

Quá trình này thường được thực hiện thông qua sự trợ giúp của một trường con của phân tích số được gọi là nội suy.

Một ví dụ phổ biến sẽ là nội suy tuyến tính. Nếu bạn biết điểm bắt đầu không đổi A và điểm kết thúc B, một hàm có thể chỉ đơn giản là f (t) = A + (B - A) * (t_max - t), trong đó

  • t là thời gian trôi qua kể từ khi đối tượng bắt đầu từ điểm A
  • t_max là thời gian bạn muốn đối tượng thực hiện cho đến khi đến đích
  • 0 <= t <= t_max.

Như bạn thấy, hàm đang trả về một vectơ, vì vậy bạn có thể áp dụng nó vào vị trí của đối tượng của bạn mà không gặp vấn đề gì.

Tất nhiên đây chỉ là một giới thiệu sơ bộ để có thể cho bạn nếm một chút máu và đánh thức sự quan tâm của bạn, do đó tôi sẽ chuyển hướng bạn đến Google nếu bạn muốn biết thêm về nó.


Cảm ơn câu trả lời của bạn! Tôi đã suy nghĩ những gì lerp trong câu trả lời của Constantinius và bạn đã đánh đúng vào điểm đó!
tecfreak
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.