看了CCPageTurn3D小孩看不良书的例子子 难道不能控制翻页方向么

[转载]源代码分析(3D翻页效果的实现)
找了好久,终于找到了看cocos2d源码CCActionPageTurn3D表示理解不能,找了一篇很好的论文正好把源码解释得一清二楚,论文的链接为:
想像一下这个情景,做这个功能的时候,如果没有这篇论文,我们一般的作法就是按照自己的思路,一帧一帧的把顶点算出来,然后渲染。这样也许可以达到翻页的效果,但是无论从时间上,还是空间上来说,很大的可能,都是不合算的。
所以,我们写程序的时候,往往会把一个稍微有点复杂的问题简单化(这种简单不是因为它真的简单,而是因为我们知识不够,误认为它会很简单),用简单的方法(可能是不合适,错误的方法)做出来,却得到了时间和空间上,复杂的计算结果。
下面只是为了理解而翻译,去除了一些介绍性的废话。
2. 相关的工作
3. 翻一个3D化的页面
正因为翻页是一本书由一个静态模式转换到另一个静态模式的一个动态的动画,所以从很大程度上来说,一本书在静态模式下是怎么表示的,会影响到在翻页过程中去如何表现它。当然,反过来也是一样的。接下来,我们会描述我们是怎么们让一本打开的书,经过一个流畅的翻页过程,变为另一本打开的书。关闭的书可以看成是打开的书的一种特例,我们可以认为它的左边,或者右边页面是不可见的。
3.1 静态模式
图1是一本打开的,3D化形式表现的书,图2是它的横截面。书的横截面可以理解为一本书被拦腰截断,而截断的方向正好垂直于把书的两部分页面联结在一起的轴。在图2中,书的左边部分(我们以后会把它称之为左块),由平行四边形ABCD表示。书的右边部分(我们以后把它称之为右块),由平行四边形EFGC表示。ACBD和EFGC相交于点C。块的宽度(AB或者EF)表示页面的宽度,块的厚度(例如:AB和CD的距离)代表书的每一页的厚度与该块中书的页数的乘积。角DAB和角EFG的大小是预先定义的常数。
4. 翻页过程中页面的变形
我们在第三节中描述了一个可以适应多种变形方式的一个通用的框架。接下来,我们将描述我们是怎样通过一个想像的锥体来对翻动中的顶部页面进行变形的。对于底部的页面也可以用同样的方式来实现。一旦顶部页面和底部页面的曲线形态计算出来以后,其它页面的翻页形态可以根据顶部和底部页面的形态构建出来。
不失一般性,我们假定待翻页的书位于XY平面上,书的下边缘与X轴平行,书的左边缘与Y轴平行(如下图所示)。我们旋转一个刚性的锥体在平面上。轴体的一边(不是中心轴)沿Y轴贴XY平面,把待翻的页面的左边缘紧紧的压在了XY平面上。(看到这里,我觉得可能需要静下心来,慢慢的想像一下我上面说的这个场景,才好继续进行下去,后面的计算都是基于这个场景的。)将页面紧贴着我们放上去的锥体转曲起来,我们便可以得到一个卷曲的页面。我们可以通过改过角θ的大小(慢慢变小),以及Ay的大小(慢慢变小),来得到不同的卷曲的页面,从而模拟出翻页的过程。(这里我们可以这样想像:锥体慢慢发缩,并且慢慢的把锥体向下抽,我们紧贴的页面便可以慢慢的翻过来了。)
特别的,在翻页的开始,我们把锥体的θ角设定为90度,使得沿着它转曲的页面看起来其实是一个平面。然后,我们慢慢地减小θ角的大小,并同时慢慢的把A点沿着Y轴向下移动。随着锥体表面的变化,书的页面开始从XY平面上卷曲起来,页面的右下角最先开始卷曲,并且卷曲程度最高。最后,我们把A无限的向下移,在这个过程接近结束的时候,书的页面又会恢复到平面上。(这里还是有点理解不了,但是cocos2d的源代码只有翻页的前半个过程,没有涉及到这个阶段,所以,对于理解源码来说,这一节的前半段已经足够了。)
正如上图所示,给定一个页面上的点P(Px, Py,
0),我们需要计算它会映射到锥体上的哪一个点。让我们在XY平面上以半径:
画一个圆,该圆和Y轴的交点我们假定为S。从几何上来说,锥体的形状告诉我们,弧SP会和一个和锥体的下表面平行的圆相重合,并且该圆通过点S。假定P点映射到了锥体上的T点,我们会有ST
= SP。我们把上面提到的圆的中心点定义为C,该圆的半径为r,角SCT为β,我们有:
现在,T(Tx, Ty, Tz)可以通过如下步骤计算而来:1, 将点S绕轴(X = 0, Z =
r)旋转角β得到S'(Sx', Sy',
Sz'),然后将点S'绕直线(Y = Sy, Z = 0)旋转角θ。简单来说,T可以通过如下公式计算而来:
(中间有些计算过程如果理解不了的话,需要看一下旋转公式。可以参考&,到这里,我们已经看到了下面程序段中出现的很多公式了)。
通过这个公式,对于书的页面上的每个点(在游戏中,一般是页面网格中的点),我们计算出它在锥体上的对应点。我们便会得到一个卷曲的结果页面。因为该计算过程之间的前后是没有关联性的,我们可以在每一帧中重新计算出所有顶点新的位置。这个算法即没有对页面进行压缩,也没有对页面进行拉伸,非常的自然。(Consequently,
the right angles&at the corners of the pages are
guaranteed to be well preserved.
这句没理解到)。并且,我们可以通过改变θ(t)和Ay(t)来得到不同的翻页动画。例如,当圆锥体退化为圆柱体的时候,书的右边缘(而非右下角)会最先开始卷曲。
下面是一些用该算法卷曲页面的效果图片:
最后,附上源码:
void CCPageTurn3D::update(float time)
& & float tt = MAX(0, time -
& & float deltaAy = (tt * tt
& & float ay = -100 -
& & float deltaTheta = -
(float) M_PI_2 * sqrtf( time) ;
& & float theta = + (float)
M_PI_2 +deltaT
& & float sinTheta =
sinf(theta);
& & float cosTheta =
cosf(theta);
& & for (int i = 0; i
&= m_sGridSize.x; ++i)
& for (int j = 0; j &=
m_sGridSize.y; ++j)
& & & // Get
original vertex
& & & ccVertex3F
p = originalVertex(ccg(i ,j));
& & & float R =
sqrtf((p.x * p.x) + ((p.y - ay) * (p.y - ay)));
& & & float r =
& & & float
alpha = asinf( p.x / R );
& & & float beta
= alpha / sinT
& & & float
cosBeta = cosf( beta );
& & & // If beta
& PI then we've wrapped around the cone
& & & // Reduce
the radius to stop these points interfering with others
& & & if (beta
& & p.x = ( r *
sinf(beta));
& & & else
& & // Force X = 0 to stop
& & // points
& & p.x = 0;
& & & p.y = ( R
+ ay - ( r * (1 - cosBeta) * sinTheta));
& & & // We
scale z here to avoid the animation being
& & & // too
much bigger than the screen due to perspectve transform
& & & p.z = (r *
( 1 - cosBeta ) * cosTheta) / 7;// "100" didn't work for
& &Stop z coord from dropping
beneath underlying page in a transition
& & & // issue
& & & if( p.z
& & p.z = 0.5f;
& & & // Set new
setVertex(ccg(i, j), p);
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。cocos2dx&常见的22种特效&3D特效
//3D晃动的特效
CCActionInterval* shaky3D = CCShaky3D::create(5, CCSize(10, 10), 15, false);
sp-&runAction(shaky3D);
//3D瓷砖晃动特效
CCActionInterval* shakyTiles3D = CCShakyTiles3D::create(5, CCSize(10, 10), 5, false);
sp-&runAction(shakyTiles3D);
//波动特效
CCActionInterval* waves = CCWaves::create(5, CCSize(10, 10), 10, 20, true, true);
sp-&runAction(waves);
//3D波动特效
CCActionInterval* waves3D = CCWaves3D::create(5, CCSize(10, 10), 10, 20);
sp-&runAction(waves3D);
//3D瓷砖波动特效
CCActionInterval* wavesTiles3D = CCWavesTiles3D::create(5, CCSize(10, 10), 10, 20);
sp-&runAction(wavesTiles3D);
//X轴 3D反转特效
CCActionInterval* filpX = CCFlipX3D::create(5);
sp-&runAction(filpX);
//Y轴3D反转特效
CCActionInterval* filpY = CCFlipY3D::create(5);
sp-&runAction(filpY);
//凸透镜特效
CCActionInterval* lens = CCLens3D::create(2, CCSize(10, 10),CCPointMake(240, 160), 240);
sp-&runAction(lens);
//水波纹特效
CCActionInterval* ripple = CCRipple3D::create(5, CCSize(10, 10), CCPointMake(240, 160), 240, 4, 160);
sp-&runAction(ripple);
//液体特效
CCActionInterval* liquid = CCLiquid::create(5, CCSize(10, 10), 4, 20);
sp-&runAction(liquid);
//扭曲旋转特效
CCActionInterval* twirl = CCTwirl::create(50, CCSize(10, 10), CCPointMake(240, 160), 2, 2.5);
sp-&runAction(twirl);
//破碎的3D瓷砖特效
CCActionInterval* shatteredTiles = CCShatteredTiles3D::create(15, CCSize(10, 10), 50, true);
sp-&runAction(shatteredTiles);
//瓷砖洗牌特效
CCActionInterval* shuffle = CCShuffleTiles::create(5, CCSize(50, 50), 50);
sp-&runAction(shuffle);
//部落格效果,从左下角到右上角
CCActionInterval* fadeOutTRTiles = CCFadeOutTRTiles::create(5, CCSize(50, 50));
sp-&runAction(fadeOutTRTiles);
//部落格效果,从右上角到左下角
CCActionInterval* fadeOutBLTiles
= CCFadeOutBLTiles::create(5, CCSize(50, 50));
sp-&runAction(fadeOutBLTiles);
//折叠效果 从下到上
CCActionInterval* fadeOutUpTiles = CCFadeOutUpTiles::create(5, CCSize(10, 10));
sp-&runAction(fadeOutUpTiles);
//折叠效果,从上到下
CCActionInterval* fadeOutDownTiles = CCFadeOutDownTiles::create(4, CCSize(20, 50));
sp-&runAction(fadeOutDownTiles);
//方块消失特效
CCActionInterval* turnOffFiels = CCTurnOffTiles::create(4, CCSize(50, 50));
sp-&runAction(turnOffFiels);
//跳动的方块特效
CCActionInterval* jumpTiles = CCJumpTiles3D::create(5, CCSize(20, 20), 5, 20);
sp-&runAction(jumpTiles);
//分多行消失特效
CCActionInterval* splitCols = CCSplitCols::create(5, 50);
sp-&runAction(splitCols);
//分多列消失特效
CCActionInterval* splitRows = CCSplitRows::create(5, 50);
sp-&runAction(splitRows);
//3D翻页特效
CCActionInterval* pageTurn3D = CCPageTurn3D::create(4, CCSize(20, 20));
sp-&runAction(pageTurn3D);
& 作用:3D翻页特效
参数1:网格大小
& 参数2:特效持续的时间
& 作用:分多行消失特效
& 参数1:行数
& 参数2:特效持续的时间
作用:分多列消失特效
参数1:列数
参数2:特效持续的时间
& 作用:跳动的方格特效
& 参数1:跳动的次数
& 参数2:网格的大小
& 参数3:特效持续的时间
& 作用:方块消失特效
参数1:网格大小
参数2:特效持续的时间
//& & 作用:折叠效果 从上到下
参数1:网格大小
参数2:特效持续的时间
& 作用:折叠效果 从下到上
参数1:网格大小
参数2:特效持续的时间
//& & 作用:部落格效果 ,
从右下角到左下角
参数1:网格大小
参数2:特效持续的时间
& 作用:部落格效果 , 从左下角到右下角
& 参数1:网格大小
& 参数2:特效持续的时间
& 作用:瓷砖的洗牌特效
& 参数1:随机数
& 参数2:网格大小
参数3:特效持续的时间
& 作用:破碎的3D瓷砖特效
& 参数1:范围
& 参数2:是否开启z轴
参数3:网格大小
& 参数4:特效持续的时间
& 作用:扭曲旋转特效
& 参数1:扭曲旋转中心点
& 参数2:扭曲旋转的次数
& 参数3:振幅
& 参数4:网格大小
参数5:特效持续时间
& 作用:液体特效
& 参数1:速率
& 参数2:振幅
& 参数3:网格大小
& 参数4:特效持续时间
& 作用:水波特效
& 参数1:起始位子
& 参数2:半径
& 参数3:速率
参数4:振幅
& 参数5:网格大小
& 参数6:特效持续的时间
作用:&&凸镜特效
& 参数1:凸镜中心点
& 参数2:凸镜半径
& 参数3:网格大小
& 参数4:网格持续时间
& CCActionInterval * flipY3D =
CCFlipY3D::create(4);
& sp-&runAction(flipY3D);
& 作用:x轴3D反转特效
& 参数:特效持续的时间
& 创建一个3D瓷砖波动特效
参数1:波动的速率
//& & 参数2:振幅
参数3:网格大小
参数4:特效持续时间
//& & 创建一个3D波动特效
参数1:波动的速率
参数2:振幅
参数3:网格大小
参数4:特效持续时间
& 创建一个波动特效
& 参数1:波动的速率
& 参数2:振幅
参数3:水平波动
& 参数4:垂直波动
& 参数5:网格大小
& 参数6:特效持续时间
& 作用:创建一个3d瓷砖晃动的特效
参数1:晃动的范围
//& & 参数2:是否有z轴晃动
参数3:&&网格大小
参数4:特效持续的时间
//作用:创建一个3d晃动的特效
& 参数1:晃动的范围
& 参数2:是否有z轴晃动
参数3:&&网格大小
& 参数4:特效持续的时间
1.基本动作InstantAction
&&放置 & Place
&&隐藏 & Hide
&&显示 & Show
&&可见切换 & ToggleVisibility
2.延时动作
&&移动到 & CCMoveTo
&&移动& CCMoveBy
&&跳跃到 & CCJumpTo&
&&跳跃 & CCJumpBy&&&
&&贝塞尔 & CCBezierBy&&
&&放大到 & CCScaleTo&&&设置放大倍数,是浮点型。
&&放大 & CCScaleBy
&&旋转到 & CCRotateTo
&&旋转 & CCRotateBy
&&闪烁 & CCBlink&&&设定闪烁次数
&&色调变化到 & CCTintTo
&&色调变换 & CCTintBy
&&变暗到 & CCFadeTo
&&由无变亮 & CCFadeIn
&&由亮变无 & CCFadeOut
3.组合动作
&&序列 & CCSequence
&&同步 & Spawn
&&重复有线次数 & Repeate
&&动作反向 & Reverse
&&动画 & Animation
&&无限重复 & RepeatForever
4.速度变化
&&EaseIn 由慢至快。
&&EaseOut 由快至慢
&&EaseInOut 由慢至快再由快至慢。
&&EaseSineIn 由慢至快。
&&EaseSineOut 由快至慢
&&EaseSineInOut 由慢至快再由快至慢。
&&EaseExponentialIn 由慢至极快。
&&EaseExponentialOut 由极快至慢。
&&EaseExponentialInOut 由慢至极快再由极快至慢。
&&Speed 人工设定速度,还可通过 SetSpeed 不断调整。
5.扩展动作
&&&延时动作 & Delay ,比如在动作序列中增加一个时间间歇
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。涓婁紶鍙戝竷
禄 CCPageTurn3DAction.m
CCPageTurn3DAction.m ( 鏂囦欢娴忚? )
/* cocos2d for iPhone
* http://www.cocos2d-iphone.org
* Copyright (C) 2009 Sindesso Pty Ltd /
* This prog you can redistribute it and/or modify
* it under the terms of the 'cocos2d for iPhone' license.
* You will find a copy of this license within the cocos2d for iPhone
* distribution inside the &LICENSE& file.
#import &CCPageTurn3DAction.h&
@implementation CCPageTurn3D
* Update each tick
* Time is the percentage of the way through the duration
-(void)update:(ccTime)time
float tt = MAX( 0, time - 0.25f );
float deltaAy = ( tt * tt * 500);
float ay = -100 - deltaAy;
float deltaTheta = - (float) M_PI_2 * sqrtf( time) ;
float theta = /*0.01f*/ + (float) M_PI_2 +deltaT
float sinTheta = sinf(theta);
float cosTheta = cosf(theta);
for( int i = 0; i &=gridSize.x; i++ )
for( int j = 0; j &= gridSize.y; j++ )
// Get original vertex
ccVertex3F p = [self originalVertex:ccg(i,j)];
float R = sqrtf((p.x*p.x) + ((p.y - ay)*(p.y - ay)));
float r = R * sinT
float alpha = asinf( p.x / R );
float beta = alpha / sinT
float cosBeta = cosf( beta );
// If beta & PI then we've wrapped around the cone
// Reduce the radius to stop these points interfering with others
if( beta &= M_PI)
p.x = ( r * sinf(beta));
p.y = ( R + ay - ( r*(1 - cosBeta)*sinTheta));
// We scale z here to avoid the animation being
// too much bigger than the screen due to perspectve transform
p.z = (r * ( 1 - cosBeta ) * cosTheta) / 100;
// Force X = 0 to stop wrapped
p.y = ( R + ay - ( r*(1 - cosBeta)*sinTheta));
p.z = 0.001f;
// Stop z coord from dropping beneath underlying page in a transition
if( p.z&0.001f )
p.z = 0.001f;
// Set new coords
[self setVertex:ccg(i,j) vertex:p];
灞曞紑锛}

我要回帖

更多关于 透过现象看本质的例子 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信