溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發(fā)技術 > 
  • 19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、

19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、

發(fā)布時間:2020-08-05 11:58:24 來源:網(wǎng)絡 閱讀:322 作者:danielzzu 欄目:開發(fā)技術
重開發(fā)者的勞動成果,轉(zhuǎn)載的時候請務必注明出處:http://blog.csdn.net/haomengzhu/article/details/30478985

流動的水沒有形狀,漂流的風找不到蹤跡、、、
直睡的陵遷谷變,石爛松枯,斗轉(zhuǎn)星移,整個宇宙在不停的運動著、、、

前面詳細介紹了游戲的基本組成元素--場景、 層、 精靈和渲染樹等, 也詳細介紹了 Node 提供的定時器。
為了讓整個世界運動起來,讓每一個精靈運動,可以利用定時器,不斷修改節(jié)點的屬性,實現(xiàn)簡單的動態(tài)效果。
然而,這種方法會導致為了實現(xiàn)簡單的動態(tài)效果,十分煩 瑣地維護一批定時器。
Cocos2d-x 為了解決這個問題,引入了動作機制。

Action是動作類的基類
所有的動作都派生自這個類,它創(chuàng)建的一個對象代表了一個動作。
動作作用于Node,因此, 任何一個動作都需要由 Node 對象來執(zhí)行。

以下代碼實現(xiàn)了一個精靈用 10秒鐘的時間移動到了點(100, 100):
auto sprite = Sprite::create("sprite.png"); auto action = MoveTo::create(1.0f, Point(0, 0)); sprite->runAction(action);

需要注意的是,一個 Action 只能使用一次,
這是因為動作對象不僅描述了動作,還保存了這個動作持續(xù)過程中不斷改變的一些中間參數(shù)。
對于需要反復使用的動作對象,可以通過 copy 方法復制使用。

Action 作為一個基類,其實質(zhì)是一個接口(即抽象類),
由它派生的實現(xiàn)類(如運動和轉(zhuǎn)動等)才是我們實際使用的動作。

Action 的絕大多數(shù)實現(xiàn)類都派生自 FiniteTimeAction,這個類定義了在有限時間內(nèi)可以完成的動作。
FiniteTimeAction定義了 reverse 方法,通過這個方法可以獲得一個與原動作相反的動作(稱作逆動作),例如隱藏一個精靈后,用逆轉(zhuǎn)動作再顯示出來。
當然,并非所有的動作都有對應的逆動作,
例如類似"放大到"等設置屬性為常量的動作不存在逆動作,而設置屬性為相對值的動作則往往存在相應的逆動作。

由 FiniteTimeAction 派生出的兩個主要類分別是瞬時動作(ActionInstant)和持續(xù)性動作(ActionInterval),
這兩類動作與復合動作配合使用,能得到復雜生動的動作效果。

瞬時動作
瞬時動作是指能立刻完成的動作,是 FiniteTimeAction 中動作持續(xù)時間為 0 的特例。
更準確地說,這類動作是在下一幀會立刻執(zhí)行并完成的動作,如設定位置、設定縮放等。
這些動作原本可以通過簡單地對 Node 賦值完成,但是把它們包裝 
為動作后,可以方便地與其他動作類組合為復雜動作。

一些常用的瞬時動作:
Place
該動作用于將節(jié)點放置到某個指定位置,其作用與修改節(jié)點的 Position 屬性相同。
例如,將精靈放置到屏幕坐標(100, 100) 處,再執(zhí)行曲線運動 curveMove 的代碼如下: 
FiniteTimeAction* placeAction = Place::create(Point(100, 100)); Action* action = Sequence::create(placeAction, curveMove, NULL);
其中 Sequence 又稱為動作序列,是一種復合動作,它在初始化時,會接受多個動作,當它被執(zhí)行時,這些動作會按順序逐個執(zhí)行,形成有序的一列動作。

FlipX 和 和 FlipY
這兩個動作分別用于將精靈沿 X 和 Y 軸反向顯示,其作用與設置精靈的 FlipX 和 FlipY 屬性相同。
將其包裝為動作類也是為了便于與其他動作進行組合。
例如,我們想使精靈從屏幕的一端游動到另一端,然后按原路返回。
為了更自然一點,我們設置一個序列,精靈先執(zhí)行移動的動作,在精靈到達另一端時反向顯示,然后再執(zhí)行移動回起點的動 作,相關代碼如下:
FiniteTimeAction* flipXAction = FlipX::create(true); Action* action = Sequence::create(curveMove, flipXAction, curveMove->reverse(), NULL);
其中 reverse 的作用是取得原動作的逆動作。在這個例子中,精靈沿 X 軸翻轉(zhuǎn)后將會沿原路返回起點。

Show 和 和 Hide
這兩個動作分別用于顯示和隱藏節(jié)點,其作用與設置節(jié)點的 Visible 屬性的作用一樣。
例如,為了使精靈完成運動之后隱藏 起來,我們使用如下代碼: 
FiniteTimeAction* hideAction = Hide::create(); Action* action = Sequence::create(curveMove, hideAction, NULL);

CallFunc
CallFunc 系列動作包括 CallFunc、CallFuncN、__CCCallFuncND,以及 __CCCallFuncO四個動作,
用來在動作中進行方法的調(diào)用(之所以不是函數(shù)調(diào)用,是因為它們只能調(diào)用某個類中的實例方法,而不能調(diào)用普通的 C 函數(shù))。
當某個對象 執(zhí)行 CallFunc 系列動作時,就會調(diào)用一個先前被設置好的方法,以完成某些特別的功能。 

在CallFunc 系列動作的 4 個類中:
CallFunc 調(diào)用的方法不包含參數(shù),
CallFuncN 調(diào)用的方法包含一個 Node*類型的參數(shù), 表示執(zhí)行動作的對象。 
__CCCallFuncND調(diào)用的方法包含兩個參數(shù), 不僅有一個節(jié)點參數(shù), 還有一個自定義參數(shù) (Node*與 void*)。__CCCallFuncO調(diào)用的方法則只包含一個 Ref*類型的參數(shù)。
實際上,CallFunc 系列動作的后綴"N"表示 Node 參數(shù),指的是執(zhí)行動作的對象,
"D"表示 Data 參數(shù),指的是用戶自定義的數(shù)據(jù),"O"表示對象,指的是一個用戶自定義的 Ref參數(shù)。

在不同的情況下,我們可以根據(jù)不同的需求來選擇不同的 CallFunc 動作。
考慮一種情況,我們創(chuàng)建了許多會在屏幕中移動的精靈,希望精靈在移動結束之后就從游戲中刪除。 
為了實現(xiàn)這個效果,我們可以創(chuàng)建一系列動作:首先讓精靈移動,然后調(diào)用一個 removeSelf(Node* nodeToRemove)方法來刪除 nodeToRemove 對象。在 removeSelf 方法中需要訪問執(zhí)行此動作的精靈,因此我們就采用 CallFuncN 來調(diào)用removeSelf 方法。

持續(xù)性動作
持續(xù)性動作是在持續(xù)的一段時間里逐漸完成的動作,如精靈從一個點連續(xù)地移動到另一個點。
與瞬時動作相比,持續(xù)性動作的種類更豐富。
由于這些動作將持續(xù)一段時間,所以大多數(shù)的持續(xù)性動作都會帶有一個用于控制動作執(zhí)行時間的實型參數(shù)duration。
每一種持續(xù)性動作通常都存在兩個不同的變種動作,分別具有 To 和 By 后綴:
后綴為 To 的動作描述了節(jié)點屬性值的絕對變化,例如 MoveTo 將對象移動到一個特定的位置;
而后綴為 By 的動作則描述了屬性值相對的變化,如 MoveBy 將對象移動一段相對位移。

根據(jù)作用效果不同,可以將持續(xù)性動作劃分為以下 4 大類:
位置變化動作
屬性變化動作
視覺特效動作
控制動作

位置變化動作
針對位置(position)這一屬性,引擎為我們提供了 3 種位置變化動作類型。
MoveTo 和 MoveBy:用于使節(jié)點做直線運動。設置了動作時間和終點位置后,節(jié)點就會在規(guī)定時間內(nèi),從當前位置直線移動到設置的終點位置。它們的初始化方法分別為:
static MoveTo* create(float duration, const Point& position); static MoveBy* create(float duration, const Point& deltaPosition);
其中,duration 參數(shù)表示動作持續(xù)的時間,position 參數(shù)表示移動的終點或距離。
對于 MoveTo,節(jié)點會被移動到 position對應的 位置;
對于 MoveBy,節(jié)點會相對之前的位置移動 position的距離。 

JumpTo 和 JumpBy:使節(jié)點以一定的軌跡跳躍到指定位置。它們的初始化方法如下:
static JumpTo* create(float duration, const Point& position, float height, int jumps); static JumpBy* create(float duration, const Point& position, float height, int jumps);
其中 position 表示跳躍的終點或距離,height 表示最大高度,jumps 表示跳躍次數(shù)。

BezierTo 和 BezierBy: 使節(jié)點進行曲線運動, 運動的軌跡由貝塞爾曲線描述。 
static BezierTo* create(float t, const ccBezierConfig& c); static BezierBy* create(float t, const ccBezierConfig& c);
貝塞爾曲線是描述任意曲線的有力工具,
在許多軟件(如 Adobe Photoshop)中,鋼筆工具就是貝塞爾曲線的應用。

每一條貝塞爾曲線都包含一個起點和一個終點。
在一條曲線中,起點和終點都各自包含一個控制點,而控制點到端點的連線稱作控制線。
控制線決定了從端點發(fā)出的曲線的形狀,包含角度和長度兩個參數(shù):角度決定了它所控制的曲線的方向,
即這段曲線在這一控制點的切線方向;長度控制曲線的曲率。控制線越長,它所控制的曲線離控制線越近。
19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、
19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、
使用時我們要先創(chuàng)建 ccBezierConfig 結構體, 設置好終點 endPosition 以及兩個控制點controlPoint_1 和controlPoint_2后,再把結構體傳入 BezierTo 或 BezierBy 的初始化方法中:
ccBezierConfig bezier; bezier.controlPoint_1 = Point(20, 150); bezier.controlPoint_2 = Point(200, 30); bezier.endPosition = Point(160, 30); FiniteTimeAction * beizerAction = BezierTo::create(actualDuration / 4, bezier);


屬性變化動作
屬性變化動作的特點是通過屬性值的逐漸變化來實現(xiàn)動畫效果。 
例如, 下面要介紹的第一個動作 ScaleTo, 它會在一段時間內(nèi)不斷地改變游戲元素的 scale 屬性,
使屬性值平滑地變化到一個新值,從而使游戲元素產(chǎn)生縮放的動畫 效果。 

ScaleTo 和 ScaleBy:產(chǎn)生縮放效果,使節(jié)點的縮放系數(shù)隨時間線性變化。對應的初始化方法為:
static ScaleTo* create(float duration, float s); static ScaleBy* create(float duration, float s);
其中,s 為縮放系數(shù)的最終值或變化量。

RotateTo 和 RotateBy:產(chǎn)生旋轉(zhuǎn)效果。對應的初始化方法為:
static RotateTo* create(float duration, float deltaAngle); static RotateBy* create(float duration, float deltaAngle);
其中 deltaAngle的單位是角度,正方向為順時針方向。

FadeIn 和 FadeOut:產(chǎn)生淡入淡出效果,其中前者實現(xiàn)了淡入效果,后者實現(xiàn)了淡出效果。對應的初始化方法為:
static FadeIn* create(float d); static FadeOut* create(float d);

以下介紹的幾個類似的動作。
FadeTo:用于設置一段時間內(nèi)透明度的變化效果。其初始化方法為:
static FadeTo* create(float duration, GLubyte opacity);
參數(shù)中的 Glubyte 是 8 位無符號整數(shù),因此,opacity 可取 0 至 255 中的任意整數(shù)。
與透明度相關的動作只能應用在精靈(Sprite)上,且子節(jié)點不會受到父節(jié)點的影響。

TintTo 和 TintBy:設置色調(diào)變化。這個動作較為少用,其初始化方法為:
static TintTo* create(float duration, GLubyte red, GLubyte green, GLubyte blue); static TintBy* create(float duration, GLshort deltaRed, GLshort deltaGreen, GLshort deltaBlue);
與 FadeTo 類似,red、green 和 blue的取值范圍也為 0~255。

視覺特效動作
用于實現(xiàn)一些特殊的視覺效果
Blink:使目標節(jié)點閃爍。其初始化方法為:
static Blink* create(float duration, int blinks);
其中,blinks是閃爍次數(shù)。

Animation:播放幀動畫,用幀動畫的形式實現(xiàn)動畫效果。

控制動作
控制動作是一類特殊的動作,用于對一些列動作進行精細控制。
利用這一類動作可以實現(xiàn)一些實用的功能,因此它們是十分常用的。 
這類動作包括 DelayTime、 Repeat 和RepeatForever 等。
DelayTime可以將動作延時一定的時間, 
Repeat可以把現(xiàn)有的動作重復一定次數(shù),
RepeateForever可以使一個動作不斷重復下去。
事實上,控制動作與復合動作息息相關。

復合動作
簡單動作顯然不足以滿足游戲開發(fā)的要求, 在這些動作的基礎上, 
Cocos2d-x 為我們提供了一套動作的復合機制,允許我們組合各種基本動作,產(chǎn)生更為復雜和生動的動作效果。
復合動作是一類特殊的動作,因此它也需要使用 Node 的runAction 方法執(zhí)行。
而它的特殊之處在于,作為動作容器,復合動作可以把許多動作組合成一個復雜的動作。
因此,我們通常會使用一個或多個動作來創(chuàng)建復合動作,再把動作交給節(jié)點執(zhí)行。
復合動作十分靈活,這是由于復合動作本身也是動作,因此也可以作為一個普通的動作嵌套在其他復合動作中。

重復( Repeat/RepeatForever )
有的情況下,動作只需要執(zhí)行一次即可,但我們還常常遇到一個動作反復執(zhí)行的情況。
對于一些重復的動作,我們可以通過 Repeat 與 RepeatForever 這兩個方式重復執(zhí)行: 
static Repeat* create(FiniteTimeAction *action, unsigned int times); static RepeatForever* create(ActionInterval *action);
其中,action參數(shù)表示需要重復的動作,第一個方法允許指定動作的重復次數(shù),第二個方法使節(jié)點一直重復該動
作直到動作被停止。

并列( Spawn )
指的是使一批動作同時執(zhí)行。Spawn 從 ActionInterval 派生而來的,它提供了兩個工廠方法:
static Spawn* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION; static Spawn* createWithTwoActions(FiniteTimeAction *action1, FiniteTimeAction *action2);
其中第一個靜態(tài)方法可以將多個動作同時并列執(zhí)行,參數(shù)表中最后一個動作后需要緊跟 NULL 表示結束。第二個則只能指定兩個動作復合, 不需要在最后一個動作后緊跟 NULL。 
此外, 執(zhí)行的動作必須是能夠同時執(zhí)行的、 繼承自 FiniteTimeAction的動作。
組合后,Spawn 動作的最終完成時間由其成員中最大執(zhí)行時間的動作來決定。

序列( Sequence )
除了讓動作同時并列執(zhí)行,我們更常遇到的情況是順序執(zhí)行一系列動作。
Sequence 提供了一個動作隊列,它會順序執(zhí)行一系列動作。
Sequence 同樣派生自 ActionInterval。
與 Spawn 一樣,Squence 也提供了兩個工廠方法:
static Sequence* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION; static Sequence* createWithTwoActions(FiniteTimeAction *actionOne, FiniteTimeAction *actionTwo);
它們的作用分別是建立多個和兩個動作的順序執(zhí)行的動作序列。
同樣要注意復合動作的使用條件,部分的非延時動作(如RepeatForever)并不被支持。

在實現(xiàn) Sequence 和 Spawn 兩個組合動作類時,有一個非常有趣的細節(jié):
成員變量中并沒有定義一個可變長的容器來容納每一個動作系列, 而是定義了m_pOne和m_pTwo兩個動作成員變量。 如果我們創(chuàng)建了兩個動作的組合, 
那么m_pOne與m_pTwo就分別是這兩個動作本身;
當我們創(chuàng)建更多動作的組合時,引擎會把動作分解為兩部分來看待,
其中后一部分只包含最后一個動作,而前一部分包含它之前的所有動作,

引擎把 m_pTwo 設置為后一部分的動作,把 m_pOne 設置為其余所有動作的組合。
例如,
語句
 sequence = Sequence::create(action1, action2, action3, action4, NULL);
就等價于:
Sequence s1 = Sequence::createWithTwoActions(action1, action2); Sequence s2 = Sequence::createWithTwoActions(s1, action3); sequence = Sequence::createWithTwoActions(s2, action4);

Spawn 與 Sequence 所采用的機制類似,在此就不再贅述了。

采用這種遞歸的方式,而不是直接使用容器來定義組合動作,實際上為編程帶來了極大的便利。
維護多個動作的組合是一個復雜的問題,現(xiàn)在我們只需要考慮兩個動作組合的情況就可以了。

下面是 Spawn 的一個初始化方法,就是利用遞歸的思想簡化了編程的復雜度:
Spawn* Spawn::create(const Vector<FiniteTimeAction*>& arrayOfActions) {     Spawn* ret = nullptr;     do      {         auto count = arrayOfActions.size();         CC_BREAK_IF(count == 0);         auto prev = arrayOfActions.at(0);         if (count > 1)         {             for (int i = 1; i < arrayOfActions.size(); ++i)             {                 prev = createWithTwoActions(prev, arrayOfActions.at(i));             }         }         else         {             // If only one action is added to Spawn, make up a Spawn by adding a simplest finite time action.             prev = createWithTwoActions(prev, ExtraAction::create());         }         ret = static_cast<Spawn*>(prev);     }while (0);      return ret; }

眾所周知,遞歸往往會犧牲一些效率,但能換來代碼的簡潔。

在這兩個復合動作中,細節(jié)處理得十分優(yōu)雅,
所有的操作都只需要針對兩個動作實施,多個動作的組合會被自動變換為遞歸
void Spawn::update(float time) {     if (_one)     {         _one->update(time);     }     if (_two)     {         _two->update(time);     } }  Spawn* Spawn::reverse() const {     return Spawn::createWithTwoActions(_one->reverse(), _two->reverse()); }

延時( DelayTime )
DelayTime 是一個"什么都不做"的動作,類似于音樂中的休止符,
用來表示動作序列里一段空白期,通過占位的方式將不同的動作段串接在一起。
實際上,這與一個定時期實現(xiàn)的延遲沒有區(qū)別,
但相比之下,使用 DelayTime 動作來延時就可以方便地利用動作序列把一套動作連接在一起。
DelayTime 只提供了一個工程方法,如下所示:
static DelayTime* create(float d);
其中僅包含一個實型參數(shù)d,表示動作占用的時間。

變速動作
大部分動作的變化過程是與時間成線性關系的,即一個動作經(jīng)過相同時間產(chǎn)生的變化相同,
例如,MoveBy 會使節(jié)點在同樣長的時間內(nèi)經(jīng)過同樣的位移。
這是因為 Cocos2d-x 把動作的速度變化控制抽離了出來,形成一個獨立的機制。
普通動作配合 變速動作,可以構造出很有趣的動作效果。
與復合動作類似,變速動作也是一種特殊的動作,它可以把任何一種動作按照改變后的速度執(zhí)行。
因此,在初始化變速動作時,需要傳入一個動作。

變速動作包括 Speed 動作與 Ease 系列動作,下面來詳細介紹這些動作。
Speed
Speed 用于線性地改變某個動作的速度,因此,可以實現(xiàn)成倍地快放或慢放功能。
static Speed* create(ActionInterval* action, float speed);
為了改變一個動作的速度,首先需要將
目標動作包裝到 Speed 動作中:
RepeatForever* repeat = RepeatForever::create(animation); Speed* speed = Speed::create(repeat, 1.0f); speed->setTag(action_speed_tag); sprite->runAction(speed);
在上面的代碼中, 我們創(chuàng)建了一個 animation 動作的 CCRepeatForever 復合動作 repeat, 使動畫被不斷地重復執(zhí)行。 然后,我們又使用 repeat 動作創(chuàng)建了一個 CCSpeed 變速動作。
create 初始化方法中的兩個參數(shù)分別為目標動作與變速比率。
設置變速比率為 1,目標動作的速度將不會改變。
最后,我們?yōu)?speed 動作設置了一個 tag 屬性,并把動作交給精靈,讓精靈執(zhí)行變速動作。
此處設置的 tag 屬性與 Node 的 tag 屬性類似,用于從節(jié)點中方便地查找動作。
接下來,在需要改變速度的地方,我們通過修改變速動作的 speed 屬性來改變動作速度。
下面的代碼將會把上面設置的動畫速度變?yōu)樵瓉淼膬杀叮?/span>
Speed * speed = sprite->getActionByTag(action_speed_tag); speed->setSpeed(2.0f);

ActionEase
雖然使用 Speed 能夠改變動作的速度,然而它只能按比例改變目標動作的速度。
如果我們要實現(xiàn)動作由快到慢、速度隨時間改變的變速運動, 
需要不停地修改它的speed屬性才能實現(xiàn), 顯然這是一個很煩瑣的方法。 
下面將要介紹的ActionEase 系列動作通過使用內(nèi)置的多種自動速度變化來解決這一問題。 
ActionEase 系列包含 15 個動作,
它們可以被概括為 5 類動作:指數(shù)緩沖、Sine 緩沖、彈性緩沖、跳躍緩沖和回震緩沖。
每一類動作都有 3 個不同時期的變換:In、Out 和 InOut。

下面使用時間變換圖像表示每組 ActionEase 動作的作用效果,
其中橫坐標表示實際動畫時間,縱坐標表示變換后的動畫時間。
因此,線性動作的圖像應該是一條自左下角到右上角的直線。
19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、
19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、

19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、19、Cocos2dx 3.0游戲開發(fā)找小三之Action:流動的水沒有形狀,漂流的風找不到蹤跡、、、

ActionEase 的使用方法與 Speed 類似。以 Sine 緩沖為例,以下代碼實現(xiàn)了 InSine 變速運動:
EaseSineIn* sineIn = EaseSineIn::create(action); sineIn->setTag(action_sine_in_tag); sprite->runAction(sineIn);

創(chuàng)建自定義動作
為了抽象出獨立的旋轉(zhuǎn)跟蹤動作,根據(jù)精靈的移動路徑設置合適的旋轉(zhuǎn)角度。 
Action 包含兩個重要的方法:step 與 update。
step 方法會在每一幀動作更新時觸發(fā),該方法接受一個表示調(diào)用時間間隔的參數(shù) dt,dt 的積累即為動作運行的總時間。
引擎利用積累時間來計算動作運行的進度(一個從 0 到 1 的實數(shù)),并調(diào)用 update 方法更新動作。
update 方法是 Action 的核心,它由 step 方法調(diào)用,接受一個表示動作進度的參數(shù),
每一個動作都需要利用進度值改變目標節(jié)點的屬性或執(zhí)行其他指令。
自定義動作只需要從這兩個方法入手即可,我們通常只需要修改 update 方法就可以實現(xiàn)簡單的動作。

Action的step和update方法定義:
    //! called every frame with it's delta time. DON'T override unless you know what you are doing.     virtual void step(float dt);      /**      called once per frame. time a value between 0 and 1      For example:      - 0 means that the action just started     - 0.5 means that the action is in the middle     - 1 means that the action is over     */     virtual void update(float time);

讓動作更平滑流暢
如何讓動作看起來更加自然并優(yōu)雅,實際上,這是一個涉及玩家注意力的問題。
對于新出現(xiàn)的變化效果,玩家需要時間轉(zhuǎn)移注意力適應這個變化,
而后如果效果持續(xù)穩(wěn)定、變化不明顯,則會降低玩家的注意力,使玩家感覺疲憊。
在這種情況下,一個冗長的勻速動作效果就會造成游戲不自然不優(yōu)雅。

不妨為動作添加一些變速效果,將玩家有限的注意力集中到我們希望玩家關注的效果上。
進場動作:由快到慢,快速進入后緩慢停下,在停止前給玩家足夠的視覺時間分辨清楚進入的圖像。
出場動作:先慢后快,展示了出場趨勢和方向后快速移出屏幕,不拖泥帶水。
這個變速效果就很自然地交給前面提到的 Ease 系列動作實現(xiàn)了。

針對具體的需求,我們選擇了 EaseExponential 動作來實現(xiàn)變速效果。
以暫停游戲時彈出的菜單為例:
點擊暫停游戲后,菜單從屏幕頂端向下滑出;
點擊恢復游戲后,菜單向上收起。

彈出菜單的代碼如下:
Menu* menu = Menu::create(item0, item1, item2, item3, NULL); menu->alignItemsVerticallyWithPading(5.0f); menu->setPosition(ccp(size.width/2, size.height)); menu->setTag(menu_pause_tag); this->addChild(menu, 5); MoveTo* move = MoveTo::create(0.5f, Point(size.width/2, size.height/2));  Action* action = EaseExponentialOut::create(move); menu->runAction(action);

收起菜單的代碼如下: 
Size size = Director::getInstance()->getWinSize(); Menu* menu = (Menu*)this->getChildByTag(menu_pause_tag); Point point = Point (size.width/2, size.height + menu->getContentSize().height/2); MoveTo* move = MoveTo::create(0.5f, point);  Action* action = EaseExponentialIn::create(move); menu->runAction(action);

郝萌主友情提示:
優(yōu)雅自然的動作,能加強游戲的表現(xiàn)性,能吸引更多的玩家、、、



向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI