Search…

Tạo Hiệu Ứng Rung Chuyển Trong Game Cocos2d-x 2.2.5

27/09/20203 min read
Phân tích hướng xử lý và cài đặt hiệu ứng rung chuyển trong Cocos2d-x.

Cocos2d-x là 1 trong những engine mạnh để phát triển game hiện nay. Mặc dù thư viện này đã hỗ trợ một hệ thống các thành phần hỗ trợ đồ sộ, tuy nhiên do đặc thù dự án mà có những thành phần hỗ trợ sẵn không thể đáp ứng được.

Đặt vấn đề dự án cần tạo hiệu ứng rung chuyển bàn chơi trong một thời gian ngắn, hiệu ứng được tạo ra giống như mặt đất rung chuyển khi xảy ra động đất. Cocos2d-x đã cung cấp lớp CCActionInterval để phát triển hành động cho những đối tượng Cocos2d-x. Hành động này diễn ra trong một khoảng thời gian nhất định, vì vậy hiệu ứng này được mở rộng từ CCActionInterval

Hiện thực

#ifndef __SHAKEACTION_H__
#define __SHAKEACTION_H__

#include "cocos2d.h"
using namespace cocos2d;

namespace stdio {
namespace effect {
    
// utils
inline float randFloat(float minValue, float maxValue)
{
    float randomNumber = ((float)rand()/(float)RAND_MAX);
    
    return randomNumber*(maxValue-minValue) + minValue;
}
// ~utils
    
class ShakeAction : public CCActionInterval
{
public:
    ShakeAction();
    
    static ShakeAction*         create(float duration, 
					float strengthX, float strengthY, 
					int numFramesPerShake = 1, 
					float maxAngle = 0.0f);
										
    bool                        initWithDuration(float duration, 
					float strengthX, float strengthY, 
					int numFramesPerShake, float maxAngle);
    
    virtual void                startWithTarget(CCNode *pTarget);
    virtual void                update(float dt);
    virtual void                stop(void);
    
protected:
    float                       _initialPosX, _initialPosY;
    float                       _initialRotation;
    float                       _strengthX, _strengthY;
    float                       _maxAngle;
    int                         _numFramesPerShake;
    int                         _frameCounter;
};

} // ~effect
} // ~stdio

#endif //__SHAKEACTION_H__
  • Dòng 11-16: hàm sinh số ngẫu nhiên trong khoảng cho trước.
  • Dòng 24: phương thức tạo đối tượng ShakeAction.
  • Dòng 29: phương thức khởi tạo đối tượng ShakeAction.
  • Dòng 33: phương thức này được Cocos2d-x tự động gọi khi đối tượng chạy hành động được dùng để lưu lại trạng thái của đối tượng được chạy.
  • Dòng 34: phương thức được gọi trong mỗi frame, trạng thái của đối tượng được cập nhật trong phương thức này.
  • Dòng 35: phương thức được gọi khi hành động chạy xong, dùng khôi phục lại trạng thái ban đầu của đối tượng.
  • Dòng 38: biến thành viên lưu vị trí của đối tượng trước khi thực hiện hành động.
  • Dòng 39: biến thành viên lưu góc quay của đối tượng nhằm giúp cho hiệu ứng thêm chân thực, không chỉ tác động tới độ dời mà còn góc xoay của đối tượng.
  • Dòng 40: độ dời tối đa theo 2 trục của đối tượng.
  • Dòng 41: độ xoay tối đa của đối tượng.
  • Dòng 42: biến để tính toán tần số rung của đối tượng, biến này càng lớn tần số rung của đối tượng càng nhỏ.
  • Dòng 43: biến tạm để lưu số frame đã được render.

Dưới đây là phần hiện thực của hiệu ứng:

#include "ShakeAction.h"

namespace stdio {
namespace effect {
        
ShakeAction::ShakeAction()
    :_strengthX(0.0f),
    _strengthY(0.0f),
    _initialPosX(0.0f),
    _initialPosY(0.0f),
    _initialRotation(0.0f),
    _maxAngle(0.0f),
    _frameCounter(0),
    _numFramesPerShake(0)
{
}

ShakeAction* ShakeAction::create(float duration, 
					float strengthX, float strengthY, 
					int numFramesPerShake, float maxAngle)
{
    ShakeAction *pAction = new ShakeAction();
    pAction->initWithDuration(duration, strengthX, strengthY, 
				numFramesPerShake, maxAngle);
    pAction->autorelease();
    
    return pAction;
}

bool ShakeAction::initWithDuration(float duration, 
					float strengthX, float strengthY, 
					int numFramesPerShake, float maxAngle)
{
    if (CCActionInterval::initWithDuration(duration))
    {
        _strengthX = strengthX;
        _strengthY = strengthY;
        
        _numFramesPerShake = numFramesPerShake;
        _maxAngle = maxAngle;
        
        return true;
    }
    
    return false;
}

void ShakeAction::update(float dt)
{
	_frameCounter--;
    
	if(_frameCounter <= 0)
	{
		_frameCounter = _numFramesPerShake;
        
        float randX = randFloat(-_strengthX, _strengthX);
        float randY = randFloat(-_strengthY, _strengthY);
        
        CCPoint currentPos = m_pTarget->getPosition();
        m_pTarget->setPosition(ccpAdd(currentPos, ccp(randX, randY)));
        m_pTarget->setRotation(CCRANDOM_MINUS1_1()*_maxAngle);
	}
}

void ShakeAction::startWithTarget(CCNode *pTarget)
{
    CCActionInterval::startWithTarget( pTarget );
    
    _initialPosX = pTarget->getPosition().x;
    _initialPosY = pTarget->getPosition().y;
    _initialRotation = pTarget->getRotation();
}

void ShakeAction::stop(void)
{
    m_pTarget->setPosition(ccp(_initialPosX, _initialPosY));
    m_pTarget->setRotation(_initialRotation);
    
    CCActionInterval::stop();
}

} // ~effect
} // ~stdio
IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024