Nếu người xây dựng xây dựng tòa nhà theo lối lập trình viên viết chương trình, thì sau đó chim gõ kiến sẽ đến với việc phá hủy nền văn minh. Eric S. Raymond
STDIO Bài biết này trong loạt bài viết trong chương trình Tự Học Cocos2d-x 3.x.x. Scene là một thành phần luôn luôn có trong project trò chơi, scene là gì? làm sao để có thể khởi tạo một scene, bài viết giới thiệu về khái niệm, cách chuyển Scene này qua Scene khác và một số hiệu ứng chuyển Scene.
Nội dung bài viết

Giới thiệu

Hãy tưởng tượng rằng game của bạn đang làm là một bộ phim, bạn đã có đầy đủ cốt truyện, cách bố trí,... Công việc của bạn lúc này là cần phải quay cảnh phim và những cảnh phim này được tập hợp thành bộ phim của bạn. Scene chính là những cảnh quay trong game. Trong bài viết này tôi và các bạn sẽ tìm hiểu về Scene trong Cocos2d-x 3.4.

Tiền đề bài viết

Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x 3.x.x được tài trợ bởi STDIO.

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

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

Scene là gì?

Scene là một cảnh game, nó chứa đựng những Sprites, Lables, Nodes và tất cả các đối tượng khác mà trò chơi của bạn cần. Có trác nhiệm điều hành logic của trò chơi, Render lên Screen (Màn hình hiển thị) các nội dụng cần thiết cho từng Scene mà bạn đã thiết kế. Bạn cần ít nhất một Scene để bắt đầu trò chơi của bạn. Một game của bạn có thể có rất nhiều Scene, nhưng mà trong một thời điểm nhất định chỉ có một Scene được hoạt động.

Khởi tạo Scene

// www.stdio.vn
// Khởi tạo Screne có tên là gameScene.
Auto gameScene= Scene::create();

Ví dụ về Scene

Cocos2d-x sử dụng hệ tọa độ Oxy với gốc tọa độ O(0,0) nằm tại góc bên trái phía dưới Screen. Vì vậy, khi thiết kế các thành phần của Scene bạn nên chú ý tới điều này để sao cho thiết lập vị trí của các các thành phần trong game phù hợp.

ss_1

Để thêm một Sprite, Lable, hay một đối tượng vào Screne bạn sử dụng phương thức addChild() API.

// www.stdio.vn
// www.stdio.vn/users/index/11/truong-dat
// Khởi tạo một Scene có tên là gameScene.
auto gameScene = Scene::create();

// Lấy kích thước của màn hình.
// Với mỗi Platform thì sẽ có kích thước màn hình khác nhau, khi bạn trò chơi của bạn được build 
// qua nhiều nền tảng, bạn không thể áp dụng kích thước "cứng" của một số thiết bị nào đó. 
// Việc bạn lấy kích thước màn hình sẽ giúp bạn có thể thiết lập vị trí với các flotform khác.
Size visibleSize = Director::getInstance()->getVisibleSize();

// Khởi tạo Sprite.
// Sprite boar.
auto board = Sprite::create("spr_board.png");
board->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));
board->setScale(0.5);
gameScene->addChild(board, 1);

// Sprite title zero
auto titleZero = Sprite::create("spr_title_zero.png");
titleZero->setPosition(Point(board->getPositionX(), 
                       board->getPositionY() + board->getContentSize().height/8));
titleZero->setScale(0.5);
gameScene->addChild(titleZero , 1);

// Menu.
// Menu item play button.
auto playButton = MenuItem::create("spr_btn_play.png", "spr_btn_play_press.png",
                                   CC_CALLBACK_1(MenuGame::playGameCallback, this)));
playButton->setPosition(Point(board->getPositionX(),
                        board->getPositionY() - board->getContentSize().height / 8));
playButton->setScale(0.5);

// Menu item training.
auto trainingButton = MenuItem::create("spr_btn_training.png", "spr_btn_training_press.png ",
                                      CC_CALLBACK_1(MenuGame::trainingGameCallback, this)));
trainingButton->setPosition(Point(board->getPositionX() + board->getContentSize().width / 8,
                            board->getPositionY() + board->getContentSize().height / 4));
trainingButton->setScale(0.5);
 
// Menu item about.
auto aboutButton = MenuItem::create("spr_btn_about.png", "spr_btn_about_press.png ",
                                      CC_CALLBACK_1(MenuGame::aboutGameCallback, this)));
aboutButton->setPosition(Point(board->getPositionX() + board->getContentSize().width / 8 + trainingButton->getContentSize().width/2,
                         board->getPositionY() + board->getContentSize().height / 4));
aboutButton->setScale(0.5);

// Khởi tạo Menu.
auto menu = Menu::create(playButton, trainingButton, aboutButton, NULL);
// Thêm menu vào Scene hiện tại.
gameMenu->addChild(menu, 1);

Ở đoạn code trên tôi cố gắng hiện thực lại Scene Menu Game của game Zero.

ss_2

Scene Graph

Là một cấu trúc dữ liệu để sắp xếp những đối tượng mà bạn cần trên Scene của bạn. Đây là một điều quan trọng vì bạn cần phải chắc chắn rằng kết quả nhận được thỏa mãn với mục đích của bạn khi thiết kế game.

ss_3

Đưới đây là Scene Graph của mục Ví dụ về Scene.

ss_4

Một số cách chuyển đổi giữa các Scene

runWithScene 

Được sử dụng cho Scene đầu tiên trong game của bạn.

// runWithScene.
Director::getInstance()->runWithScene(gameScene);

replaceScene 

Đối với Scene còn lại (Ngoại trừ Scene đầu tiên ra) thì ta dùng phương thức replace để thay thế Scene mới cho Scene hiện tại.

Khi bạn thay thế một scene bằng một Scene khác, các Scene mới được load vào bộ nhớ Ram trước khi Scene cũ được giải phóng. Vì vậy, việc chuyển đổi giữa các Scene dễ bị crash liên quan tới việc không đủ bộ nhớ. Bạn nên kiểm tra thường xuyên việc thay đổi giữa các Scene khi game cần nhiều bộ nhớ.

// replaceScene.
Director::getInstance()->replaceScene(gameScene);

pushScene và popScene

Scene cũ được thay bằng Scene mới mà không phải giải phóng Scene cũ ra khởi bộ nhớ.

Ưu điểm

 Việc chuyển sang Scene mới sẽ nhanh hơn do không phải khởi tạo lại vùng nhớ cho Scene mới và giải phóng vùng nhớ Scene cũ.

Nhược điểm

Chiếm một lượng lớn bộ nhớ Ram và có thể làm cho game của bạn bị crash. Bạn phải nhớ chính xác có bao nhiêu Scene để việc pushSence popScene sao cho phù hợp với mục đích của bạn.

Ta nên dùng PushScene và PopScene lúc nào?

ss_5

 Giả sử game của bạn hiện tại Scene đang chạy là Scene Play, bạn muốn game của bạn chuyển sang Scene Pause và không thay đổi đến trạng thái hiện tại của trò chơi. Lúc này bạn sẽ sử dụng pushScene để chuyển sang Scene Pause và bạn dùng popScene để chuyển sang Scene Play. Một điều bạn phải luôn nhớ là phải đủ bộ nhớ để cùng lúc chứa 2 Scene và tránh làm dụng sử dụng pushScene và popScene.

// pushScene.
Director::getInstance()->pushScene(gameScene);

// popScene.
Director::getInstance()->popScene(gameScene);

Hiệu ứng chuyển Scene

Cocos2d-x còn cung cấp những hiệu ứng chuyển Scene. Điều này có thể giúp game của bạn đẹp hơn và bắt mắt hơn. Nhưng bạn cũng cần chú ý, không nên làm dụng các hiệu ứng nhất là các hiệu ứng cần nhiều thời gian vì rất dễ gây cho người chơi có cảm giác khó chịu.

ss_6

// Khởi tạo một Scene có tên là gameScene.
auto gameScene = Scene::create();

// Hiệu ứng chuyển Scene Transition Fade.
Director::getInstance()->replaceScene(TransitionFade::create(0.5, gameScene, Color3B(0,255,255)));

// Hiệu ứng chuyển Scene FlipX
Director::getInstance()->replaceScene(TransitionFlipX::create(2, gameScene));

// Hiệu ứng chuyển Scene Transition Slide In
Director::getInstance()->replaceScene(TransitionSlideInT::create(1, gameScene) );

Tổng kết

Trong bài viết này tôi đã giới thiệu các khái niệm, các thành phần và một số thao tác cơ bản với Scene trong Cocos2d-x 3.x.x. Mọi thắc mắc bạn có thể bình luận tại bài viết hoặc liên hệ với Trương Đạt.

Tham khảo

http://www.cocos2d-x.org

Bạn cần hỗ trợ các dự án kết nối không dây?

Quí doanh nghiệp, cá nhân cần hỗ trợ, hợp tác các dự án IoT, kết nối không dây. Vui lòng liên hệ, hoặc gọi trực tiếp 0942.111912.

  • TỪ KHÓA
  • Arduino
  • ESP32
  • ESP8266
  • Wifi
  • Bluetooth
  • Zigbee
  • Raspberry Pi
THẢO LUẬN
ĐÓNG