Làm cách nào tôi có thể chuyển tiếp đầu vào bàn phím của GLFW sang một đối tượng khác?


9

Tôi gặp sự cố khi cố gắng thực hiện các sự kiện bàn phím trong một lớp khác với GLFW3. Vấn đề tôi gặp phải là GLFW3 sử dụng hàm tĩnh cho đầu vào như được hiển thị:

static UI u;
...
...
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    u.controls(window, key, action);
}

ucũng là tĩnh và các điều khiển giữ đầu vào cho các khóa WSAD (cách duy nhất tôi có thể nhận các sự kiện chính). Từ đây, nhấn một phím sẽ hiển thị phím nào được nhấn trong cửa sổ giao diện điều khiển. Rắc rối tôi gặp phải là cố gắng sử dụng phím được nhấn để thao tác một biến trong lớp khác.

Tôi có một lớp khác gọi là MainMothy có chức năng update().Có cách nào để tôi có thể sử dụng lớp UI của mình trong hàm này không?

Câu trả lời:


16

Bạn đang sử dụng sai phương pháp với lớp UI tĩnh. Cách thông thường để "bật lại" từ một cuộc gọi lại tĩnh đến một chức năng cá thể là lưu trữ thứ gì đó có khả năng thực hiện bước nhảy ở một nơi có thể truy cập được từ cuộc gọi lại tĩnh.

Hầu hết các API, như GLFW và Win32 bản địa, yêu cầu các loại gọi lại tĩnh này cung cấp một cách để tạo liên kết ở trên. Các cửa sổ GLFW có một khối lưu trữ có kích thước con trỏ mà bạn có thể gán cho: con trỏ người dùng . Bạn có thể nhận hoặc đặt con trỏ người dùng này khi cần thiết.

Một mô hình rất phổ biến là có một số loại Gamelớp có các phương thức như "HandleKeyPress (Khóa phím)" hoặc không có gì. Khi chương trình bắt đầu, bạn tạo Gameđối tượng và thực hiện tất cả khởi tạo GLFW, sau đó nhét Gamecon trỏ vào bộ lưu trữ dữ liệu người dùng:

int main () {
  GLFWindow * window = ... create GLFW window ...
  Game game(... game constructor parameters ...);

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Sau đó, cuộc gọi lại bàn phím của bạn (và tất cả các cuộc gọi lại tĩnh khác) có thể giải nén Game *khỏi bộ lưu trữ con trỏ người dùng và chuyển tiếp tới nó:

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
  Game * game = reinterpret_cast<Game *>(glfwGetWindowUserPointer(window);
  game->HandleKeyDown(...);
}

Các HandleKeyDownphương pháp trên Gamedụ có thể chuyển tiếp cùng với đối tượng giao diện người dùng của bạn nếu cần thiết (hoặc, nếu bạn thực sự chỉ cần đầu vào bàn phím cho các đối tượng giao diện người dùng bạn chỉ có thể nhét một con trỏ đến đối tượng giao diện người dùng của bạn trong việc lưu trữ của người dùng, tuy nhiên, nhồi nhét một cái gì đó giống như trò chơi hoặc một cái gì đó cấp cao hơn thường tốt hơn vì bạn chỉ có một con trỏ trên mỗi cửa sổ để sử dụng).


0

Cách mà tôi có được bây giờ là sử dụng một đối tượng singleton, khi tôi cần truy cập vào lớp, tôi chỉ có thể truy xuất con trỏ đến singleton:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    InputManager * in_manager = InputManager::get_instance();
    in_manager->handle_key_press( params)
}

Một số như thế.

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.