0

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 :

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.

I. Create 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, width 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 😃)

Scale9Sprite *mysprite = [Scale9Sprite spriteWithFile:@"CCControlButton.png" capInsets:CGRectMake(12, 12, 56, 56)];

// Change the content size of the sprite and it'll be stretch automatically
[mysprite setContentSize:CGSizeMake(299, 134)];

II. Sprite's properties

1. Anchor Point và Position

Về cơ bản Sprite có thuộc tính Anchor Point giống với những gì đã được trình bày trong phần 2. Những thuộc tính như scale, position, rotation, skew sẽ phụ thuộc vào việc bạn thiết lập anchor point cho Sprite. Mặc định anchor point của Sprite có giá trị (0.5, 0.5)

Việc setting Position rất đơn giản:

// DEFAULT anchor point for all Sprites
mySprite->setAnchorPoint(0.5, 0.5);

// bottom left
mySprite->setAnchorPoint(0, 0);

// top left
mySprite->setAnchorPoint(0, 1);

// bottom right
mySprite->setAnchorPoint(1, 0);

// top right
mySprite->setAnchorPoint(1, 1);

Kết quả thu được là các trạng thái khác nhau:

i6.png

2. Rotation

Việc thay đổi thuộc tính rotation của Sprite bằng cách truyền vào góc có giá trị âm hoặc dương. Với giá trị dương thì Sprite sẽ quay theo chiều kim đồng hồ, ngược lại giá trị âm sẽ quay theo chiều ngược chiều kim đồng hồ. Mặc định góc quay là 0.

// rotate sprite by +20 degrees
mySprite->setRotation(20.0f);

// rotate sprite by -20 degrees
mySprite->setRotation(-20.0f);

// rotate sprite by +60 degrees
mySprite->setRotation(60.0f);

// rotate sprite by -60 degrees
mySprite->setRotation(-60.0f);

i8.png

3. Scale

Ta có thể thay đổi Sprite theo cả 2 chiều với cùng 1 giá trị, hoặc chỉ thay đổi 1 chiều. Ví dụ:

// increases X and Y size by 2.0 uniformly
mySprite->setScale(2.0);

// increases just X scale by 2.0
mySprite->setScaleX(2.0);

// increases just Y scale by 2.0
mySprite->setScaleY(2.0);

i5.png

4. Skew

// adjusts the X skew by 20.0
mySprite->setSkewX(20.0f);

// adjusts the Y skew by 20.0
mySprite->setSkewY(20.0f);

i7.png

5. Color và Opacity

Đây là 2 thuộc tính không phụ thuộc vào anchor point.

  • Color: Chúng ta có thể thay đổi màu sắc của Sprite bằng cách truyền vào các đối tượng Color3B. Nó 1 đối tượng bao gồm các giá trị RGB. Mỗi 1 RGB là 3 byte có giá trị từ 0 - 255. Cocos2d-x cũng định nghĩa sẵn 1 số màu như : Color3B::White hay Color3B::Red.
// set the color by passing in a pre-defined Color3B object.
mySprite->setColor(Color3B::WHITE);

// Set the color by passing in a Color3B object.
mySprite->setColor(Color3B(255, 255, 255)); // Same as Color3B::WHITE

i10.png

  • Opacity: Giá trị opacity của Sprite nằm trong giới hạn 0 - 255. Nếu giá trị bằng 0 đồng nghĩa với việc nó bị trong suốt hoàn toàn.
// Set the opacity to 30, which makes this sprite 11.7% opaque.
// (30 divided by 256 equals 0.1171875...)
mySprite->setOpacity(30);

i11.png

III. Polygon Sprite

Một Polygon Sprite cũng là 1 Sprite, nó được dùng để hiển thị ảnh 2d. Tuy nhiên, không giống với Sprite, nó là 1 hình chữ nhật được tạo bởi 2 hình tam giác, đối tượng PolygonSprite được tạo bởi một loạt hình tam giác.

Tại sao lại sử dụng Polygon Sprite ? Đơn giản là vấn đề hiệu suất. Khi bạn tạo 1 Sprite, toàn bộ ảnh gốc sẽ được load vào memory. Tại thời điểm này các bạn chú ý rằng sẽ có nhiều điểm trên ảnh không nhất thiết cần phải load vào memory, ví dụ như các điểm lân cận biên ảnh. Các bạn có thể nhìn vào ảnh minh hoạ

polygonsprite.png

VỚi hình bên trái, một Sprite được draw trong 1 hình chữ nhật - được tạo bởi 2 hình tam giác.

Bên phải, một PolygonSprite được vẽ bởi nhiều hình tam giác nhỏ.

Nhìn vào đây ta có thể thấy nhiều điểm dư thừa xung quanh character đã không được vẽ, đồng nghĩa với việc load sprite sẽ nhanh hơn rất nhiều.

Cocos2d-x cung cấp 1 helper class là AutoPolygon, để tạo ra PolygonSprite. Ví dụ:

// Generate polygon info automatically.
auto pinfo = AutoPolygon::generatePolygon("filename.png");

// Create a sprite with polygon info.
auto sprite = Sprite::create(pinfo);

Trong phần tiếp theo chúng ta sẽ đi chi tiết hơn Actions trong cocos2d-x. Thank for reading ! See u soon.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí