Game Studio
Liên kế mạng xã hội

Game Studio


Xử Lý Sự Kiện Trong Cocos2d-x 3.x.x

Giới thiệu

Một game hoàn chỉnh không thể thiếu sự tương tác của người chơi. Trong cocos2d-x có những cơ chế gì, những hỗ trợ gì đễ giúp cho người chơi có thể tương tác, thao tác. Bài viết này tôi và các bạn sẽ cùng tìm hiểu về xử lý sự kiện trong Cocos2d-x.

Tiền đề bài viết

Bài viết này là bài viết nằm trong những loạt bài viết của tôi về tổng quan làm game 2D sử dụng Cocos2d-x 3.4, nhằm tìm hiểu những vẫn để cơ bản về xử lý sự kiện trong game với Cocos2d-x 3.4.

Đối tượng hướng đến

Bài viết này tôi hướng đến những lập trìnhviên mới bắt đầu, hay những ai yêu thích tìm hiểu và học tập làm game 2D bằng Cocos2d-x.

Cơ chế Event Dispactch là gì?

Là một cơ chế được Cocos2d-x xây dựng dùng để trả lời các sự kiện của người dùng.

Nhiệm vụ cơ bản của cơ chế Event Dispacth.

  • Event listen: Nhận hay lắng nghe sự kiện của người chơi và đóng gói sự kiện đó thành một mã.
  • Event dispacth: Thông báo về loại sự kiện của người dùng là loại sự kiện nào.
  • Event object: Những đối tượng nào trong game có chứa thông tin về sự kiện này.

Để trả lời lại các sự kiện của người chơi, trước tiên bạn phải tạo ra một Event Listener. Có năm loại Event Listener trong Cocos2d-x.

  • EventListenTouch: Phản ứng với các sự kiện chạm cảm ứng.
  • EventListenKeyboard: Phản ứng với các sự kiện bàn phím
  • EventListenAcceleration: Phản ứng với các gia tốc sự kiện.
  • EventListenMouse: Phản ứng với các sự kiện từ con chuột.
  • EventListenCustom: Phản ứng với các sự kiện tùy chỉnh.

Touch Event

Touch Event là sự kiện quan trọng nhất trong game di động, nó dễ tạo ra và cung cấp nhiều chức năng. Khi bạn chạm vào một màn hình(Cảm ứng) của một điện thoại di động, lúc này điện thoại sẽ nhận sự kiện này và xử lý nó. Có thể thao tác của bạn sẽ được trả lời hay không được đáp ứng nhưng ở bên dưới vẫn có một cái gì đó xảy ra.

Dưới đây là cách mà bạn tạo ra một Touch Event đơn giản.

  1. // Khởi tạo một Touch event
  2. // Xử lý Touch event của người chơi tại một điểm
  3. auto listener = EventListenerTouchOneByOne::create();
  4.  
  5. // Khi bạn nhấn xuống.
  6. listener1->onTouchBegan = [](Touch* touch, Event* event){
  7. // Nơi chưa đoạn code của bạn.
  8. return true;
  9. };
  10.  
  11. // Khi bạn vừa nhấn xuống và di chuyển.
  12. listener1->onTouchMoved = [](Touch* touch, Event* event){
  13. // Nơi chứa đoạn code của bạn.
  14. };
  15.  
  16. // Khi bạn thả ra.
  17. listener1->onTouchEnded = [=](Touch* touch, Event* event){
  18. // Nơi chứa đoạn code của bạn.
  19. };
  20.  
  21. // Thêm Touch Event vào cơ chế Event Dispatch.
  22. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

Như bạn thấy ở trên có tới 3 sự kiện. Mỗi sự kiện trên có một khoảng thời gian riêng biệt.

  • onTouchBegin sự kiện được kích hoạt khi bạn nhấn xuống.
  • onTouchMoved sự kiện được kích hoạt nếu bạn di chuyển các đối tượng và vẫn nhấn xuống.
  • onTouchEnded sự kiện được kích hoạt khi bạn thả tay ra khỏi màn hình cảm ứng.

Keyboar Event

Với các game trên desktop, bạn có thể muốn sử dụng bàn phím cơ học để thao tác với trò chơi của bạn.

  1. // Khởi tạo một keyboar event.
  2. auto listener = EventListenerKeyboard::create();
  3. listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
  4. listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);
  5.  
  6. // Thêm keyboar event vào cơ chế event dispatcher.
  7. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
  8.  
  9. // Thực hiện các chức năng của keyboar event thông qua gọi hàm nguyên mẫu.
  10. void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
  11. {
  12. // Nơi chứa đoạn code của bạn.
  13. }
  14.  
  15. void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
  16. {
  17. // Nơi chứa đoạn code của bạn.
  18. }

Hàm CC_CALLBACK_2 có chức năng gọi một hàm có hai tham số. Tương tự CC_CALLBACK_0 CC_CALLBACK_1 là gọi một hàm không có tham số và gọi một hàm có một tham số.

Acceleromenter Event

Một vài thiết bị được trang bị với một gia tốc. Một gia tốc là một cảm biến do g-force để xác định sự thay đổi hướng hay cân bằng của thiết bị. Acceleromenter event xảy ra khi người chơi di chuyển điện thoại của bạn, hay làm cho điện thoại mất cân bằng. Một số game đua xe trên điện thoại di động hiện nay hay sử dụng loại sự kiện này để tạo một cảm giác giống như thật.

  1. // Kích hoạt accelerometer trên thiết bị.
  2. Device::setAccelerometerEnabled(true);

Trước khi sử dụng Acceleromenter Event, bạn cần phải kích hoạt nó trên các thiết bị.

  1. // Khởi tạo một accelerometer event.
  2. auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(
  3.   AccelerometerTest::onAcceleration, this));
  4.  
  5. // Thêm acceleromenter event vào cơ chế event dispatcher.
  6. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
  7.  
  8. // Thực hiện các chức năng của accelermonter thông qua gọi các hàm nguyên mẫu.
  9. void AccelerometerTest::onAcceleration(Acceleration* acc, Event* event)
  10. {
  11. // Đoạn code của bạn được chứa ở đây.
  12. }

Mouse Event

Là thao tác của người chơi khi sử dụng mouse(chuột).

  1. // Khởi tạo một mouse event.
  2. auto mouseListener = EventListenerMouse::create();
  3.  
  4. // Một số loại mouse event.
  5. mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
  6. mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
  7. mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);
  8. mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll, this);
  9.  
  10. // Thêm mouse event vào cơ chế event dispatcher.
  11. _eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);
  12.  
  13. // Thực hiện các chức năng của mouse envent bằng cách gọi hàm nguyên mẫu.
  14. void MouseTest::onMouseDown(Event *event)
  15. {
  16. EventMouse* e = (EventMouse*)event;
  17. string str = "Mouse Down detected, Key: ";
  18. str += tostr(e->getMouseButton());
  19. // ...
  20. }
  21.  
  22. void MouseTest::onMouseUp(Event *event)
  23. {
  24. EventMouse* e = (EventMouse*)event;
  25. string str = "Mouse Up detected, Key: ";
  26. str += tostr(e->getMouseButton());
  27. // ...
  28. }
  29.  
  30. void MouseTest::onMouseMove(Event *event)
  31. {
  32. EventMouse* e = (EventMouse*)event;
  33. string str = "MousePosition X:";
  34. str = str + tostr(e->getCursorX()) + " Y:" + tostr(e->getCursorY());
  35. // ...
  36. }
  37.  
  38. void MouseTest::onMouseScroll(Event *event)
  39. {
  40. EventMouse* e = (EventMouse*)event;
  41. string str = "Mouse Scroll detected, X: ";
  42. str = str + tostr(e->getScrollX()) + " Y: " + tostr(e->getScrollY());
  43. // ...
  44. }

Thiết lập Event cho đối tượng vào Event Dispatcher

Việc bạn thiết lập một sự kiện cho một đối tượng vào Event Dispatcher trong Cocos2d-x rất dễ dàng.
 

  1. // Thêm một sự kiện cho một đối tượng sprite1 vào event dispatcher.
  2. eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);

Một sự kiện chỉ có thể đăng ký một lần cho một đối tượng. Vậy nếu bạn cần thiết lập một sự kiện cho nhiều đối tượng thì sao? Bạn hãy sử dụng clone() .

  1. // Một sự kiện cho một đối tượng sprite1 vào event dispatcher.
  2. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
  3.  
  4. // Thêm vào cũng sự kiện đó nhưng cho đối tượng sprite2 vào event dispatcher.
  5. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
  6.  
  7. // Thêm tiếp cũng sự kiện đó nhưng là cho đối tượng sprite3 vào event dispatcher.
  8. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);

Xóa bỏ Event trong cơ chế Event Dispatcher

Bạn có thể xóa bỏ một Listener Event bằng cách sau:

  1. // Xóa một listener event.
  2. _eventDispatcher->removeEventListener(listener);

Bạn cũng có thể xỏa bỏ hết toàn bộ Listener Event trong cơ chế Event Dispatcher.

  1. // Xóa bỏ toàn bộ các listener event trong cơ chế Event Dispatcher.
  2. _eventDispatcher->removeAllEventListeners();

Chú ý: Với một đối tượng Menu, khi bạn xóa bỏ toàn bộ cácListener Event thì Menu cũng không thể hoạt động. Ví dụ như trên thiết bị di động cảm ứng Menu cần Touch Event để người chơi thao tác với Menu đó.

Tham khảo