cocos2d-x 3.x(C++)实现屏幕震动效果

源码下载

1.新建一个ShakeLayer类文件

分别在项目中添加:ShakeLayer.h,ShakeLayer.cpp文件

2.在ShakeLayer.h文件中写如代码如下:

#ifndef __SHAKELAYER_HEAD__
#define __SHAKELAYER_HEAD__

#include "cocos2d.h"
//声明一个结构体类型FPoint
struct FPoint {
    float x;
    float y;
};
class ShakeLayer:public cocos2d::Layer
{
public:
    ShakeLayer();
    ~ShakeLayer();
    CREATE_FUNC(ShakeLayer);
    static cocos2d::Scene* createScene();
    virtual bool init();
public:
    void loadBg();
public:
    void ShakeScreen();                         //屏幕震动函数
    void UpdateShakeScreen(float delta_time);   //屏幕震动的调度
    void clickEventFun();                       //按钮点击事件
public:
    FPoint shake_offset_;                       //偏移量
    float since_last_frame_;                    
    int current_shake_frame_;           
    bool shake_screen_; 
};

#endif

3.ShakeLayer.cpp添加代码如下:

#include "ShakeLayer.h"
#include "ui/cocosGUI.h"
USING_NS_CC;
using namespace ui;
const float kShakeFPS = 30.f;       //震动频率控制系数
const int kShakeFrames = 20;        //总判断次数
ShakeLayer::ShakeLayer()
{
    //构造函数对其进行初始化
    shake_offset_.x = 0;
    shake_offset_.y = 0;
    since_last_frame_ = 0;
    current_shake_frame_ = 0;
    shake_screen_ = false;
}
ShakeLayer::~ShakeLayer()
{
    this->removeAllChildren();
}
//创建震动层的场景(布景层是不可能脱离场景而单独存在的)
Scene* ShakeLayer::createScene()
{
    //1.创建一个场景
    Scene* shakeScene = Scene::create();
    //2.创建一个层
    ShakeLayer* layer = ShakeLayer::create();
    //3.将帮助层添加到新建的场景
    shakeScene ->addChild(layer);
    //4.返回这个场景
    return shakeScene;
}
//主函数
bool ShakeLayer::init()
{
    if (!Layer::init())
    {
        return false;
    }
    //添加背景
    loadBg();
    return true;
}
//添加背景
void ShakeLayer::loadBg()
{
    //添加一个自定义类型的时间调度器((每隔0.1秒)刷新一次)
    schedule(schedule_selector(ShakeLayer::UpdateShakeScreen),0.1);

    Size winSize = Director::getInstance()->getWinSize();
    Sprite* bgSpr = Sprite::create("Scene/shake.png");
    bgSpr->setPosition(Vec2(winSize.width/2,winSize.height/2));
    addChild(bgSpr);

    Button* btn_shake = Button::create("Scene/btn.png");
    btn_shake->setPosition(Vec2(winSize.width/2,winSize.height/2));
    addChild(btn_shake);
    //点击按钮开始震动
    btn_shake->addClickEventListener(CC_CALLBACK_0(ShakeLayer::clickEventFun,this));
}
void ShakeLayer::clickEventFun()
{
    ShakeScreen();
}
void ShakeLayer::ShakeScreen()
{
    shake_offset_.x = 0.f;                  //x轴抖动偏移量
    shake_offset_.y = 0.f;                  //y轴抖动偏移量
    since_last_frame_= -1.f;        //控制震动的频率(每经过几次kSpeed帧,进行一次有效震动)
    current_shake_frame_ = 0;       //判断震动的总次数(总共是kShakeFrames=20次)
    shake_screen_ = true;           //是否震动                              
}
void ShakeLayer::UpdateShakeScreen(float delta_time)
{
    if (!shake_screen_) return;
    if (since_last_frame_ == -1.f)since_last_frame_ = 0.f;
    else
    {
        since_last_frame_ += delta_time;
    }
    static const float kSpeed = 1.0 / kShakeFPS;
    printf("kSpeed=%f,since_last_frame_=%f\n", kSpeed,since_last_frame_);
    while (since_last_frame_ >= kSpeed)
    {
        since_last_frame_ -= kSpeed;
        if (current_shake_frame_ + 1 == kShakeFrames)
        {
            shake_screen_ = false;
            shake_offset_.x = 0;                    //x轴抖动偏移量
            shake_offset_.y = 0;                    //y轴抖动偏移量
            break;
        }
        else
        {
            ++current_shake_frame_;             //判断震动次数+1
            shake_offset_.x = rand() % 2 == 0 ? (10.f + rand() % 5) : (-10.f - rand() % 5);
            shake_offset_.y = rand() % 2 == 1 ? (10.f + rand() % 5) : (-10.f - rand() % 5);
        }
        printf("current_shake_frame_ = %d\n", current_shake_frame_);
    }
    this->setPosition(Vec2(shake_offset_.x, shake_offset_.y));
}

4.验证效果:

两种方式:

第一种:

在新建项目的AppDelegate.cpp中引入头文件:

#include "ShakeLayer.h"

找到

    auto scene = HelloWorldScene::createScene();
    director->runWithScene(scene);

改为

    auto scene = ShakeLayer::createScene();
    director->runWithScene(scene);

第二种:

在当前场景中添加ShakeLayer层:
在当前场景的头文件中引入

#include "ShakeLayer.h"

在当前场景的init()中:

ShakeLayer* shake_layer = ShakeLayer::create();
this->addChild(shake_layer);

点击震动按钮看一下震动效果吧!!!
先自我满足一下,如有更好方法!请不吝赐教,感激不尽。
源码下载点这里哦!

############################################写于——扬扬在路上

你可能感兴趣的:(cocos2d-x游戏学习)