`
liuqf
  • 浏览: 10337 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

转 cocos2d-x 贝塞尔曲线之游戏应用

 
阅读更多

一.贝赛尔曲线简介
贝塞尔曲线是应用于二维图形应用程序的数学曲线。曲线的定义有四个点:起始点、终止点(也称锚点)以及两个相互分离的中间点。滑动两个中间点,贝塞尔曲线的形状会发生变化 

p0起点,p3是终点,p1,p2是控制点
http://en.wikipedia.org/wiki/B%C3%A9zier_curve 

二.游戏应用

我们可能需要在游戏中模拟导弹或箭的移动轨迹,用才cocos2d-x下的bezier可以轻松的模拟出来
cocos2d-x下为我们提供了两个action CCBezierBy和CCBezierTo,使用也很简单,只需要填充结构体:

        ccBezierConfig tr0;    
        tr0.endPosition=ccp(280, 240);
        tr0.controlPoint_1=ccp(40, 400);
        tr0.controlPoint_2=ccp(280, 80);

        CCActionInterval* bezierForward = CCBezierBy::create(1.f, tr0);

我们只需要提供两个控制点和一个终点位置就可以了,这里要注意的是
CCBezier这个action是以当前位置为起始点的,两个控制点和终点都是相对于起始点的偏移值
如:tr0.endPosition = ccp(280,240); 是相对于起始点的偏移

三. 游戏实例
我们来模拟一个射箭游戏,屏幕中心点是一个人,点击屏幕任何位置,会朝这个点击位置射一支箭,箭到达指定点后抖动一会(播放一个抖动动画),然后消失


p0是箭的发射位置,p3是箭的目标点,p1,p2是控制飞行轨迹的控制点,p1p0p3组成了箭的角度,假设我们有十六个方向的箭,即360.f/16= 22.5度一个方向




第一步:存贮箭的飞行动画和抖动动画到CCAnimationCatch中,后面播放动画时通过名字来获得动画

    // 存贮箭的飞行动画,箭有多少个方向,就存贮多少个动画
    for (int i = 0; i < mDirections; ++i)
    {
        // 箭飞行动画 
        CCArray* spriteFramesArray = CCArray::create(flyFrames);

        // 从图片中每一帧的位置来生成CCSpriteFrame
        for ( int j = 0; j < flyFrames; ++j )
        {
            CCSpriteFrame* frame = CCSpriteFrame::create(pTexture, 
                CCRectMake(j * frame_width, i * frame_height, frame_width, frame_height));
            spriteFramesArray->addObject(frame);
        }

        //以键值形式存贮动画到CCAnimationCatch中
        float frameTime = 1.f / (mSpeed * flyFrames);
        CCAnimation* animation = CCAnimation::create(spriteFramesArray, frameTime);

        String name = getArrowAnimateName(i);
        CCAnimationCache::sharedAnimationCache()->addAnimation(animation, name.c_str());

        spriteFramesArray->removeAllObjects();
        spriteFramesArray->release();
    }

    // 同理存贮箭的抖动动画
    .




第二步:获得射箭目标点,用贝塞尔曲线模拟箭的飞行轨迹
      首先,要求出箭的射击方向,从CCAnimationCatche中取出对应的飞行动画,我们有16个方向的动画,下面是写的一个简单的求射箭角度和方向的函数:

#define EPSION 0.0001f 
#define IS_EQUAL(val1, val2)  (fabs((val1) - (val2)) <= EPSION)
const int mDirections = 16;

/** 更新方向,传入起始点和终止点,利用actan来获得射箭的弧度,然后转换为角度
    
*/
int ArrowDirection::updateDirection(const cocos2d::CCPoint& ptRole, const cocos2d::CCPoint& ptTarget)
{
    CCPoint sub = ccpSub(ptTarget, ptRole);

    if (IS_EQUAL(sub.x, 0.f) && IS_EQUAL(sub.y, 0.f))
        return -1;

    if (IS_EQUAL(sub.y, 0.f) && sub.x > 0)
    {
        mDegree = 90.f;
    }
    else if (IS_EQUAL(sub.y, 0.f) && sub.x < 0)
    {
        mDegree = 180.f;
    }
    else
    {
        // 弧度转角度
        float radians = atanf(sub.x/sub.y);
        mDegree = CC_RADIANS_TO_DEGREES(radians);

        if (sub.x >= 0 && sub.y >= 0 )          // 第一象限
        {

        }
        else if (sub.x >= 0 && sub.y <= 0)      // 第二象限
        {
            mDegree += 180.f;
        }
        else if (sub.x <= 0 && sub.y <= 0)      // 第三象限
        {
            mDegree += 180.f;
        }
        else                                   // 第四象限
        {
            mDegree += 360.f;
        }
    }

    if (mDegree < 0.f)
        mDegree = 0.f;
    if (mDegree > 360.f)
        mDegree = 0.f;

    float single = (float)360 / 16;
    for (int i = 0; i < mDirections; ++i)
    {
        if (mDegree >= i * single && mDegree <= (i+1) * single)
            return mDirections;
    }

    return mDirections - 1;
}



      有了角度和动画就好办了,我们已经知道了目标点,哈哈,可以让箭一边播放飞行动画一边沿着贝塞尔曲线移动就OK了

    // 播放箭飞行动作
    String name = getArrowAnimateName(dir);
    cocos2d::CCAnimation* animation = CCAnimationCache::sharedAnimationCache()->animationByName(name.c_str());

    CCAnimate* animate = CCAnimate::actionWithAnimation(animation);
    mSprite->runAction(animate);

    // 填充bezier
    ccBezierConfig cfg;
    cfg.controlPoint_1 = ccp(0, control_height);
    cfg.controlPoint_2 = ccp(ptRelativeTarget.x, ptRelativeTarget.y + control_height);
    cfg.endPosition = ptRelativeTarget;

    // 沿着贝塞尔曲线移动
    CCActionInterval* bezierForward = CCBezierBy::create(2.f, cfg);
    CCActionInterval* seq = (CCActionInterval*)CCSequence::create(bezierForward, 
                                                        CCCallFuncND::create(this, callfuncND_selector(ArrowDirection::arrowFlyOverCallBack), this),
                                                        NULL);

    mSprite->runAction(seq);

我们为action序列添加了回调函数ArrowDirection::arrowFlyOverCallBack 箭飞行完毕后进入下一阶段
 

第三步:箭到达目标点,播放抖动动画

在上一阶段的回调函数中先停止所有动画

sprite->stopAllActions();


然后播放抖动动画,抖动动画再加一个回调函数

CCAnimate* animate = CCAnimate::actionWithAnimation(animation);
sprite->runAction(CCRepeatForever::create(animate));

CCActionInterval* delay = CCDelayTime::create(pArrowDir->getArrowShakeTime());
CCActionInterval* seq = (CCActionInterval*)CCSequence::create(delay, 
                                                              CCCallFuncND::create(pArrowDir, callfuncND_selector(ArrowDirection::arrowDisappearedCallBack), pArrowDir),
                                                              NULL);

sprite->runAction(seq);


第四步:播放完毕,清除箭
在上一阶段回调中删除自己

removeFromParentAndCleanup(true);


-------------------------------------------------------------------------------
调试帮助
1.光看是不够的,要看箭的飞行轨迹,还是要画出来,在CCNode的派生类中重载draw()函数,在里面画贝塞尔曲线

void ArrowDirection::draw()
{
    if (mDrawBezier)
    {
        CCPoint control1 = ccpAdd(mBezierStartPoint, mBezierConfig.controlPoint_1);
        CCPoint control2 = ccpAdd(mBezierStartPoint, mBezierConfig.controlPoint_2);
        CCPoint end = ccpAdd(mBezierStartPoint, mBezierConfig.endPosition);

        // 画控制点
        ccDrawLine(mBezierStartPoint, control1);
        ccDrawLine(control2, end);

        // 画贝塞尔曲线
        ccDrawCubicBezier(mBezierStartPoint, mBezierConfig.controlPoint_1, mBezierConfig.controlPoint_2, mBezierConfig.endPosition, 100);
    }
}

更多画法参考cocos2d-x粒子DrawPrimitivesTest

 

原文地址:http://www.cppblog.com/wc250en007/archive/2012/08/24/188048.html

分享到:
评论

相关推荐

    Cocos2d-x 闪电特效

    在Cocos2d-x中,可以使用`ccBezierConfig`结构体和`addBezierAt`函数来创建和控制贝塞尔曲线路径。 其次,颜色的变化也是闪电效果的关键部分。闪电通常从白色渐变到黄色再到暗红色,这可以通过在OpenGL中使用顶点...

    Cocos2D-X开发学习笔记-动作类之基础动作的使用示例(下)

    Cocos2D-X是一款流行的开源游戏开发框架,尤其在2D游戏领域有着广泛的应用。它提供了丰富的API和功能,使得开发者能够轻松创建出各种复杂的2D游戏。在Cocos2D-X中,动作(Actions)是游戏对象行为的核心组成部分,...

    cocos2d-x 自学文档

    cocos2d-x 是一个开源的游戏开发框架,它基于C++,广泛应用于移动游戏开发。以下是一些cocos2d-x的关键知识点: 一、运动中的加速度 在cocos2d-x中,我们可以利用Ease系列的方法来实现物体的加速度或减速度效果。...

    Cocos2D-X开发学习笔记-渲染框架之图形的绘制

    Cocos2D-X是一款强大的跨平台2D游戏开发框架,基于C++,并提供了Lua和JavaScript等脚本语言接口。本教程将深入讲解Cocos2D-X中的渲染框架,特别是如何进行图形的绘制,这对于创建游戏场景、角色动画以及用户界面至关...

    Cocos2d-x 3.2 大富翁游戏项目开发-第八部分 角色按路径行走

    在本教程中,我们将深入探讨如何使用Cocos2d-x 3.2框架来实现大富翁游戏中的角色按预设路径行走的功能。Cocos2d-x是一个强大的、开源的游戏开发框架,支持多种平台,包括iOS、Android以及桌面系统。在大富翁游戏中,...

    Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_1

    在本教程中,我们将深入探讨如何在Cocos2d-x 3.2框架下开发大富翁游戏项目,特别是关注如何获取角色在游戏地图上的移动路径。Cocos2d-x是一个开源的游戏开发库,它基于C++,并支持多种平台,如iOS、Android和Windows...

    Cocos2D游戏之旅:贝塞尔曲线画心形——源代码和工具

    在这个“Cocos2D游戏之旅:贝塞尔曲线画心形”中,我们将深入探讨贝塞尔曲线这一重要的图形绘制技术及其在Cocos2D中的应用。 首先,让我们理解什么是贝塞尔曲线。贝塞尔曲线是一种在计算机图形学中广泛使用的参数...

    Cocos2D-X2.2.3学习笔记10(几何图形)

    Cocos2D-X是一款强大的开源游戏开发框架,广泛应用于2D游戏、实验性的教育软件以及交互式应用的创建。在Cocos2D-X2.2.3版本中,开发者可以利用其丰富的图形库来创建各种复杂的几何图形,从而实现丰富的视觉效果。本...

    cocos2d-iphone 手指画线

    在iOS游戏开发中,Cocos2d-iPhone是一个广泛使用的2D游戏引擎,它允许开发者构建高质量的游戏和交互式应用程序。本项目“cocos2d-iphone 手指画线”专注于实现用户通过手指在屏幕上绘制线条的功能。这种功能常见于...

    cocos2d二维码 cpp

    本文将深入探讨如何在Cocos2d环境中使用C++实现二维码功能,以及与之相关的贝塞尔曲线技术。 首先,让我们关注标题中的“cocos2d二维码 cpp”。这表明我们要讨论的是如何在Cocos2d-x项目中利用C++代码生成二维码。...

    2dx3.0不规则按钮

    "2dx3.0不规则按钮"就是这样一个概念,它允许开发者在Cocos2d-x 3.0框架下创建非矩形形状的按钮,提升游戏或者应用的视觉效果和用户体验。 Cocos2d-x是一个流行的开源2D游戏引擎,广泛应用于跨平台游戏开发。在...

    贝塞尔曲线编辑器——个人版

    贝塞尔曲线是计算机图形学中的基本元素,广泛用于2D和3D图形的设计,如游戏开发、网页设计以及动画制作软件。 Cocos Creator 是一个跨平台的游戏开发框架,它支持JavaScript和Cocos-JS编程语言,提供了丰富的图形和...

    cocos2dx.  关键帧动画

    Cocos2d-x是一款开源的、跨平台的2D游戏开发框架,广泛应用于移动设备上的游戏开发。在Cocos2d-x中,关键帧动画(Keyframe Animation)是一种强大的动画技术,它允许开发者通过设置一系列特定时间点的关键状态来创建...

    Cocos瞬间动作

    Cocos2d-x是一个开源的、跨平台的2D游戏开发框架,广泛应用于移动设备上的游戏开发。瞬间动作是Cocos2d-x动作系统的一部分,它提供了一种高效且灵活的方式来控制游戏场景中的节点(Node)行为。 在Cocos2d-x中,每...

    BezierCurvePathCreater:用于创建贝塞尔曲线路径,可匀速运动 - 基于CocosCreator_2.2.2 - Used to create a Bezier curve path with uniform motion Based on CocosCreator_2.2.2

    用于创建贝塞尔曲线路径,可匀速运动 - Used to create a Bezier curve path with uniform motion 更新日志: 2020.2.7: 新添加三阶贝塞尔曲线 平滑度自定义 该工程基于cocos creator 2.2.2版本! (可以直接在上面...

    DrawPicture

    【DrawPicture】是一款基于cocos2d-x框架的简单绘图应用,版本为2.0.4。cocos2d-x是一个开源的...通过这个小demo,开发者不仅可以学习到如何在cocos2d-x中创建互动的绘图应用,还能深入了解游戏引擎的基本工作原理。

    Cocos2d开发教程

    Cocos2d是一款广泛应用于游戏开发和图形界面设计的开源框架,特别适合于iOS平台。这个教程主要针对Cocos2d在iOS 4版本的使用,对于初学者和希望提升Cocos2d技能的开发者来说,是一份非常有价值的资源。 一、Cocos2d...

    Levelhelper 文档

    LevelHelper是一款专为cocos2d和cocos2d-x游戏开发设计的工具,用于简化关卡设计和管理。LevelHelperLoader是LevelHelper的核心类,它负责加载、管理和释放关卡资源。以下是对LevelHelperLoader及其相关功能的详细...

    cocos捕鱼达人路线编辑器

    6. **兼容性**:由于基于Cocos2d框架,这款编辑器与Cocos2d-x或Cocos Creator等开发工具紧密结合,保证了路线数据在游戏中的无缝集成。 在实际开发中,"fish"这个文件可能包含了路线编辑器的示例数据或者预设的鱼类...

    bezier曲线生成演示

    贝塞尔曲线(Bezier Curve)是一种在计算机图形学中广泛应用的参数曲线,由法国工程师皮埃尔·贝塞尔在1962年提出。这种曲线在2D和3D建模、动画、CAD、游戏开发等领域有着重要的作用,因为它具有易于控制且平滑连续...

Global site tag (gtag.js) - Google Analytics