So sánh layer và node trong cocos2d năm 2024

CodeLearn is an online platform that helps users to learn, practice coding skills and join the online coding contests.

Links

Learning

Training

Fights

Information

About Us

Terms of Use

Help

Help

Discussion

Powered by CodeLearn © 2024. All Rights Reserved. rev 2/5/2024 5:31:56 PM

Thời gian qua nhanh quá mà chả làm được cái gì, chán ghê. Cũng tại mình vừa vấp phải mấy vấn đề khó giải quyết trong cocos2dx - V3 nên tìm hiểu mãi mới ra. Trong bài này mình cũng trình bày luôn vấn đề đó là gì. Bây giờ chúng ta cùng tiếp tục bài trước về Physics nhé

Ở bài trước chúng ta đã tạo mới 1 Project Ball rồi đúng không, bây giờ là phần code thể hiện physics trong đó.

Let's go!

Các bạn theo đường dẫn sau: Q/android/project/ball/class, mở file HelloWorldScene.h lên. Code của file đó sẽ như vầy:

ifndef __HELLOWORLD_SCENE_H__

define __HELLOWORLD_SCENE_H__

include "cocos2d.h"

USING_NS_CC;

class HelloWorld : public cocos2d::Layer

{

public:

Sprite* _ball;

PhysicsWorld* m_world;

void setPhyWorld[PhysicsWorld* world]{ m_world = world; };

static cocos2d::Scene* createScene[];

virtual bool init[];

virtual void onAcceleration[Acceleration* acc, Event* unused_event];

bool onContactBegin[const PhysicsContact &contact];

CREATE_FUNC[HelloWorld];

};

endif // __HELLOWORLD_SCENE_H__

Các bạn không phải sửa đổi gì nhé, mình sẽ giải thích 1 chút về mấy thứ "là lạ trong đó"cho mọi người"

Sprite* _ball; // là 1 con trỏ kiểu Sprite tên là _ball, con trỏ này để quản lý cái gọi là quả bóng trong chương trình chúng ta.

PhysicsWorld* m_world; // Con trỏ kiểu PhysicsWorld tên m_world, gán cho nó các thuộc tính vật lý

void setPhyWorld[PhysicsWorld* world]{ m_world = world; }; //hàm gán thuộc tính vật lý cho m_world,

virtual void onAcceleration[Acceleration* acc, Event* unused_event]; // hàm này liên quan tới gia tốc kế thì phải bool onContactBegin[const PhysicsContact &contact]; // Hàm này để phát hiện va chạm giữa 2 quả bóng

Tiếp đến các bạn mở file HelloWorldScene.cpp lên nào [file nguồn các bạn down ở bên dưới nhé, vì mình dán vào đây thì bài dài dòng quá], trong đó bạn chú ý một số đoạn sau,

Trong hàm tạo Scene : Scene* HelloWorld::createScene[]{}

auto scene = Scene::createWithPhysics[]; // Câu lệnh này tạo 1 Scene gắn thuộc tính Physics ---

auto layer = HelloWorld::create[]; // Tạo 1 layer của lớp HelloWorld

layer->setPhyWorld[scene->getPhysicsWorld[]]; // đặt thuộc tính Physics cho biết m_world của đối tượng layer,

scene->getPhysicsWorld[] //nghĩa là lấy Physics của scene rồi gán cho m_world của layer

tiếp theo, hàm init[]

_ball = Sprite::create["Ball.jpg", Rect[0, 0, 52, 52]]; // Tạo 1 quả bóng nằm trong hình vuông 52 pixel

_ball->setPosition[Point[400,600]]; // đặt ở vị trí 400, 600

auto ballBody = PhysicsBody::createCircle[_ball->getContentSize[].width / 2]; // Tạo 1 khung body có đặc tính vật lý để phát hiện va chạm, khung này dạng tròn có đường kính = nội dung của _ball chia 2.

ballBody->setContactTestBitmask[0x1]; // Cái này rất quan trọng, nếu ko có thì hàm onContactBegin ko có tác dụng, tìm trên mạng mãi mới sửa được lỗi này

_ball->setPhysicsBody[ballBody]; // Gán body cho _ball

this->addChild[_ball]; // thêm vào layer HelloWorld đã tạo ở trên

ball2 được tạo ra tương tự

tiếp theo, đoạn này sẽ tạo ra 1 khung bao quanh màn hình, khi quả bóng chạm vào sẽ dừng lại. nó giống một bức tường [ 1 cái hộp ] vậy thôi, không cần giải thích nhiều nhé, cứ code mà đập thôi

auto edgeSp = Sprite::create[];

auto boundBody = PhysicsBody::createEdgeBox[visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3];

edgeSp->setPosition[Point[visibleSize.width / 2, visibleSize.height / 2]];

edgeSp->setPhysicsBody[boundBody];

this->addChild[edgeSp];

edgeSp->setTag[0];

Tiếp theo, quan trọng nè

auto Listener = EventListenerPhysicsContact::create[]; // Biến này để "lắng nghe" các tương tác vật lý xảy ra

Listener->onContactBegin=CC_CALLBACK_1[HelloWorld::onContactBegin,this]; // gọi hàm onContactBegin, hàm này sẽ xử lý khi va chạm xảy ra, hàm này là hàm chồng lên[ gọi là hàm overide của 1 hàm mẫu đã có của thư viện - bạn nào học C++ sẽ hiểu rõ].

_eventDispatcher->addEventListenerWithSceneGraphPriority[contactListener, this];

// dòng này để xử lý ông Listener bên trên kia,

Túm lại đoạn trên đây để phát hiện ra tương tác giữa 2 quả bóng bạn tạo ra, rồi gọi hàm onContactBegin để xử lý.

Bạn mới học thì cứ dập khuôn từng đoạn code, tạm thời đừng hỏi sao phải viết thế, viết khác được không [ Haizzz, ko biết giải đáp thế nào nhỉ]. Viết khác được, nhưng hãy nắm chắc cái ban đầu đi đã rồi phát triển sau.

Bây giờ tới hàm onContactBegin{}, format của nó chắc chắn phải viết như sau, sau đó thêm gì thì thêm vào trong 2 dấu ngoặc

bool HelloWorld::onContactBegin[const PhysicsContact &contact]

{

return true;

}

thêm đoạn này vào để xóa 2 quả bóng khi chạm nhau

auto ObjA = [Sprite*]contact.getShapeA[]->getBody[]->getNode[];

auto ObjB = [Sprite*]contact.getShapeB[]->getBody[]->getNode[];

this->removeChild[ObjB,true];

this->removeChild[ObjA,true];

tiếp theo, hàm này this->setAccelerometerEnabled[true]; // Gia tốc kế của máy điện thoại

Chạy thử nhé, các bạn đừng quên lệnh này nhé

cocos run -s q:android/project/ball -p win32

Nếu bạn thấy 2 quả bóng đập vào nhau và biến mất là đã thành công

Bạn thử bỏ dòng lệnh ballBody->setContactTestBitmask[0x1]; đi xem, 2 quả bóng có va vào nhau nhưng ko có gì xảy ra phải không. Hehe, mỗi dòng lệnh này mà mình tìm kiếm mất gần tuần. HIX

Vấn đề Physic đã giải quyết xong

Nâng cao lên 1 chút nào

Xóa dòng this->setAccelerometerEnabled[true]; và layer->setPhyWorld[scene->getPhysicsWorld[]];, Xóa tiếp hàm onAcceleration, kết quả ko đổi đúng ko, tốc độ rơi vẫn thế [trên win], 2 quả bóng chạm nhau vẫn biến mất. Lệnh này hình như thiết lập gia tốc kế. Các bạn thử thiết lập và xoay màn hình điện thoại xem nhé. Quả bóng sẽ lăn theo hướng rơi xuống cạnh đáy màn hình

Nhưng thử xóa dòng _ball->setPhysicsBody[ballBody]; ball2->setPhysicsBody[ball2Body]; Bạn sẽ thấy 2 quả bóng đứng im luôn. Có thể thấy hàm này giống như việc đặt vào quả bóng 1 khối lượng nào đó vậy [ chắc tương đương với bán kính]. Quên mất vật nặng nhẹ đều rơi như nhau với gia tốc G mà

Bây giờ thêm lại 2 lệnh setPhysicsBody bên trên, rồi thêm dòng lệnh sau: scene->getPhysicsWorld[]->setGravity[Vect[0.0f,-5000.0f]]; Bạn sẽ thấy quả bóng rơi rất nhanh, đó, chỗ này chính là thiết lập gia tốc trọng lực, sét càng cao thì rơi càng nhanh.

Như vậy qua bài này, bạn đã biết làm thế nào để thiết lập 1 Physics cơ bản cho chương trình rồi nhé. Sang phiên bản mới [ mình đang xài V3 RC2] bạn chỉ cần nắm mấy lệnh cơ bản sau

Chủ Đề