# Cocos2d
我們遊戲是以Cocos 旗下的兩種遊戲引擎為基礎
| | Cocos2d-x | Cocos2d-js |
| -------- | -------- | -------- |
| 程式語言 | C++11 | Javascript |
| 我們的產品 | APP(iOS & Andorid) | WEB |
## Director
Cocos2D 的運作概念是由一個 Director 去控制許多場景 (Scene), 每個場景可以有許多的圖層 (Layer), 每個圖層可以包含許多的角色 (Sprite) 及其他元件等等. Director 並且還負責執行遊戲迴圈(Director::mainLoop())及所有的繪圖工作. Director 一次只能執行一個場景 (Scene), 場景即顯示在螢幕上的畫面。
:::info
每幀都會呼叫一次Director::mainLoop()(預設fps: 60).
:::
## Node
Node 是cocos2d-x遊戲引擎中的重要元素,是其他重要遊戲元素的父類別,例如,Scene,Layer和Sprite. Node包含了一些基本的屬性, 節點相關, Action的執行以及定時器等相關操作.
### Node 屬性
#### Position(位置), Anchor Point(錨點)與座標系統
原點在螢幕的左下角, X軸從螢幕左側向右側延伸, Y軸從螢幕底部向頂部延伸

- **Position(位置)**: (default: x=0, y=0), position of node in its parent's coordinate system.
- **Anchor Point(錨點)**: (default: x=0, y=0), Anchor Point就像一枚圖釘, 將圖片釘在螢幕上. 而Anchor Point就是圖片的坐標. 當然可以釘在圖片的左下角(0, 0), 右上角(1, 1), 或者中心(0.5,0.5)都可以.
#### ContentSize(内容大小), Scale(縮放比例)
- **ContentSize**: (default: width=0, height=0),
- **Scale**: (default: x=1, y=1), Scale數字越大則圖片看起來越大, 但若圖片本身解析度不夠, 則會明顯變糊.
:::danger
設定Scale不會影響Content Size的大小.
:::
#### Rotation(旋轉)
設置節點的旋轉角度(in degrees). (default: 0), 正順, 負逆時針旋轉.
#### Visible(可見度), Opacity(透明度), Color
- **Visible(可見度)**: (default: true), true代表可見, false代表看不見(不被渲染)
- **Opacity(透明度)**: (default: 255), 值0~255之間. 0表示透明, 255則不透明.
- **Color**: (default: Color3B::WHITE)
:::danger
當Node 的Opacity屬性設置為0時,在場景中是不可見的,但是其visible為true,也就是說仍然被渲染. 而當我們將visible設置為fasle時,儘管該Node 不可見,但其實其opacity為255. 所以Opacity屬性只與精靈的透明度有關而Visible則是與需要被渲染有關.
:::
:::info
當我們要傳遞透明度/或顏色給子節點時, 必須要設定
```c++=
virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled);
virtual void setCascadeColorEnabled(bool cascadeColorEnabled);
```
:::
#### LocalZOrder
呈現節點內容的先後順序. 預設的zOrder為0. 數字越大越上層, 若數字相同則越後面加入的元件在越上層.
#### Tag, Name
- **Tag**: 節點編號, (default: **Node::INVALID_TAG**)
- **Name**: 節點名稱
:::danger
如果 Tag 或者是 Name 若不是獨一無二的, 則
```c++=
virtual Node * getChildByTag(int tag) const;
virtual Node* getChildByName(const std::string& name) const;
```
只會回傳最早找到的 Node
:::
### Node 的操作
#### 設置父節點 Parent
```c++=
virtual void setParent(Node* parent);
virtual Node* getParent();
virtual void removeFromParent();
virtual void removeFromParentAndCleanup(bool cleanup); //true if all actions and callbacks on this node should be removed
```
#### 管理子節點 Child
```c++=
//添加子節點
virtual void addChild(Node * child);
virtual void addChild(Node * child, int localZOrder);
virtual void addChild(Node* child, int localZOrder, int tag);
virtual void addChild(Node* child, int localZOrder, const std::string &name);
//取得子節點
virtual Node* getChildByTag(int tag) const;
virtual Node* getChildByName(const std::string& name) const;
virtual Vector<Node*>& getChildren(); //取得所有子節點
virtual ssize_t getChildrenCount() const; //子節點總數
//删除子節點
virtual void removeChild(Node* child, bool cleanup = true);
virtual void removeChildByTag(int tag, bool cleanup = true);
virtual void removeChildByName(const std::string &name, bool cleanup = true);
virtual void removeAllChildren(); //刪除所有子節點
virtual void removeAllChildrenWithCleanup(bool cleanup); //cleanup為true則刪除子節點的所有動作
```
#### 其他操作管理
```c++=
virtual void onEnter(); //事件呼叫的時間點在 Node 被創建加入時.
virtual void onEnterTransitionDidFinish(); //事件呼叫的時間點在 Node 被創建加入完後.
virtual void onExitTransitionDidStart(); //事件呼叫的時間點在 Node離開舞台前.
virtual void onExit(); //事件呼叫的時間點在 Node被移除時.
```
::: danger
如果要複寫這四個事件, 一定要記得呼叫父節點的相關事件, 不然會許多物件的狀態會出錯.
ex. 繼承 Layer 的客製化 CustomLayer
```c++=
void CustomLayer::onEnter {
Layer::onEnter();
... Code ...
}
```
:::
### Action(動作相關)
https://docs.cocos.com/cocos2d-x/manual/zh/actions/
### Schedule
```c++=
/**
* 定时器管理schedule
* setScheduler
* scheduleUpdate : 默认定时器
* schedule : 自定义定时器
* scheduleOnce : 一次性定时器
*/
//设置一个调度器对象,来调度所有的“update”和定时器
//如果你设置了一个新的调度器,則之前创建的timers/update将会被删除。
virtual void setScheduler(Scheduler* scheduler);
virtual Scheduler* getScheduler(); //得到调度器对象
//开启默认定时器.刷新次数为60次/秒.即每秒60帧.
//与update(float delta)回调函数相对应.
//给予定时器优先级priority.其中priority越小,优先级越高
void scheduleUpdate(void);
void scheduleUpdateWithPriority(int priority);
void unscheduleUpdate(void); //取消默认定时器
virtual void update(float delta); //update为scheduleUpdate定时器的回调函数.
//设置自定义定时器.默认为每秒60帧.
//interval : 每隔interval秒,执行一次.
//repeat : 重复次数.
//delay : 延迟时间,即创建定时器delay后开始执行.
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
void schedule(SEL_SCHEDULE selector, float interval);
void schedule(SEL_SCHEDULE selector); //默认为每秒60帧
void scheduleOnce(SEL_SCHEDULE selector, float delay); //只执行一次,delay秒后执行
void unschedule(SEL_SCHEDULE selector); //取消一个自定义定时器
void unscheduleAllSelectors(void); //取消所有定时器
void resume(void); //恢复所有定时器和动作
void pause(void); //暂停所有定时器和动作
```
## Scene(場景), Layer(圖層), Sprite
https://www.twblogs.net/a/5b7c97202b71770a43dbb5b8
## ClippingRectangleNode
矩形遮罩, 遮罩本身不會被渲染, 只所有放在此遮罩上且在範圍的物件才看得見.

如上圖, 此遮罩上有兩個Child node, 藍色Node都在範圍內所以完全可見. 紅色Node 部分超過範圍所以部分可見.
## Cocos 第三方遊戲工具
### TexturePacker
TexturePacker是一款把許多圖片拼接為一張大圖的工具. 設計師制作遊戲的時候, 為了提高圖片載入渲染速度, 往往把很多小圖拼接成一張大圖, 一次載入, 減少I/O, 提高渲染速度.
https://www.codeandweb.com/texturepacker
:::danger
大圖片不能超過2048 * 2048
:::
### Spine
使用spine來做骨骼動畫.
http://esotericsoftware.com/spine-in-depth