12/08/2018, 13:25

Phát triển game dựa trên game engine đa nền tảng cocos2d-x (P3)

Sau khi đã qua 2 bài giới thiệu về cocos2d-x, cũng như các thành phần cơ bản trong game : Phần 1 : https://viblo.asia/ThanhTa/posts/jaqG0lrxGEKw. Phần 2 : https://viblo.asia/ThanhTa/posts/NPVMaDb2RQOk. Trong bài này, chúng ta sẽ đi vào chi tiết dối tượng Sprite, cách khởi tạo, cũng như ...

Sau khi đã qua 2 bài giới thiệu về cocos2d-x, cũng như các thành phần cơ bản trong game :

  • Phần 1 : https://viblo.asia/ThanhTa/posts/jaqG0lrxGEKw.
  • Phần 2 : https://viblo.asia/ThanhTa/posts/NPVMaDb2RQOk.

Trong bài này, chúng ta sẽ đi vào chi tiết dối tượng Sprite, cách khởi tạo, cũng như thuộc tính của Sprite.

Tuỳ vào mục đích sử dụng Sprite mà ta có những cách khởi tạo khác nhau. Bạn có thể tạo 1 Sprite từ nhiều loai resource khác nhau, ví dụ như: PNG, JPEG, TIFF... Chúng ta sẽ cùng bàn lần lượt qua từng cách và ưu nhược điểm của nó.

1. Creating a Sprite

Một Sprite có thể được tạo từ resource là PNG hoặc JPEG, TIFF

auto mySprite = Sprite::create("mysprite.png");

i1.png

Đoạn code trên thực hiện tạo 1 Sprite từ file mysprite.png. Kết quả thu được là 1 Sprite có kích thước bằng với kích thước của ảnh và bao trọn ảnh. Nếu ảnh có kích thước 200 x 200 thì kết quả Sprite có kích thước 200 x 200.

2. Creating a Sprite with a Rect

Trong ví dự trước, Sprite được tạo ra có cùng kích thước với ảnh gốc. Vậy nếu bạn muốn tạo 1 Sprite chỉ với 1 phần của ảnh thì sao ? Bạn chỉ cần chỉ định phạm vi - Rect : với 4 giá trị origin x, origin y, awidth và height - trong câu lệnh khởi tạo :

auto mySprite = Sprite::create("mysprite.png", Rect(0,0,40,40));

i4.png

Rect được tính từ góc trên bên trái. Bạn có thể thấy đây là điểm trái ngược với anchor point của screen - Với screen anchor point là điểm phía dưới bên trái. Kết quả Sprite được tạo ra chỉ là 1 phần của ảnh. Trong trường hợp này Sprite có kích thước 40 x 40, bắt đầu từ góc trên bên trái.

Nếu bạn không chỉ định Rect, thì Cocos2d-x mặc định sử dụng chiều rồng và chiều dài của ảnh mà bạn chỉ định. Các bạn có thể quan sát ví dụ bên dưới. Nếu chúng ta sử dụng một ảnh có kích thước 200 x 200, kết quả nhận được sau khi thực hiện 2 câu lệnh là như nhau.

auto mySprite = Sprite::create("mysprite.png");

auto mySprite = Sprite::create("mysprite.png", Rect(0,0,200,200));

3. Creating a Sprite from a Sprite Sheet

Sprite Sheet là một cách nhóm nhiều sprite vào trong 1 file duy nhất. Nó giúp giảm tổng thế kích thước file so với từng file cho mỗi Sprite. Điều đó dồng nghĩa với việc bạn giảm thể được đáng kể memory cần sử dung, kích thước file và thời gian load file vào memory.

Trong lần đầu nạp sprite sheet vào bộ nhớ, nó sẽ được lưu tại SpriteFrameCache - đây là lớp lưu trữ các đối tượng SpriteFrame.

Đây là ví dụ về sprite sheet :

3_1.png

Nhìn vào ví dụ bên dưới, chúng ta có thể thấy vì sao Sprite Sheet lại giúp giảm kích thước file, cũng như bộ nhớ cần thiết để lưu trữ khi so với việc tách riêng từng Sprite:

spritesheet.png

Ở đây, chúng ta đã giảm thiểu không gian thừa giữa những Sprite và hợp nhất vào 1 file.

Loading a Sprite Sheet

Để load sprite sheet vào trong SpriteFrameCache, chúng ta sử dụng câu lệnh

// load the Sprite Sheet
auto spritecache = SpriteFrameCache::getInstance();

// the .plist file can be generated with any of the tools mentioned below
spritecache->addSpriteFramesWithFile("sprites.plist");

Kết quả của khối lệnh này là sprite sheet đã được load vào SpriteFrameCache, và chúng ta có thể tạo các Sprite từ đó.

Creating a Sprite từ SpriteFrameCache

Sprite được lấy từ SpriteFrameCache:

// Our .plist file has names for each of the sprites in it.  We'll grab
// the sprite named, "mysprite" from the sprite sheet:
auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");

i3.png

Creating a Sprite từ SpriteFrame

Ngoài ra ta có thể lấy đối tượng SpriteFrame từ SpriteFrameCache, và sau đó tạo Sprite từ SpriteFrame. Ví dụ:

// this is equivalent to the previous example,
// but it is created by retrieving the SpriteFrame from the cache.
auto newspriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Blue_Front1.png");
auto newSprite = Sprite::createWithSpriteFrame(newspriteFrame);

i3 (1).png

Chúng ta có thể dùng nhiều công cụ khác nhau để tạo sprite sheet :

  • Cocos Studio
  • ShoeBox
  • Texture Packer
  • Zwoptex

4.Scale9Sprite

Sau khi trải qua 3 cách tạo Sprite ở trên, có vẻ như mọi thứ khá dễ dàng. Nhưng các bạn chú ý rằng cho dù là dùng sprite sheet hay chỉ dùng 1 ảnh, thì Sprite được tạo ra có kích thước nhỏ hơn hoặc bằng với ảnh gốc. Vậy câu hỏi đặt ra là nếu bạn cần tạo 1 Sprite mà có kích thước lớn ảnh gốc, mà không bị vỡ hình thì phải làm sao ? Ví dụ với ảnh dứoi dây

NlmWK.png

Các bạn nghĩ sao ? Nếu ta phóng to ảnh trên ra, thì 1 điều chắc chắn rằng 4 góc bo tròn của ảnh sẽ bị vỡ. It is problem. :#). Rõ ràng việc phóng to 1 hình chữ nhật sẽ dễ dàng hơn rất nhiều lần. Một giải pháp được dưa ra là chia ảnh trên thanh 9 phần, để đảm bảo việc co dãn chỉ áp dụng với các khối chữ nhật, các khối còn lại sẽ được giữ nguyên. Chúng ta cùng quan sát ảnh minh hoạ

Scale9.png

Với cách chia như vậy thì việc co, giãn sẽ được thực hiện như sau :

Scale9-Work.png

Và đó chính là Scale9Sprite             </div>
            
            <div class=

0