Merge pull request #13336 from zilongshanren/v3

[ci skip]merge v3.7.1 back to v3.
This commit is contained in:
子龙山人 2015-08-12 18:12:25 +08:00
commit da9b894494
17 changed files with 507 additions and 247 deletions

View File

@ -741,6 +741,7 @@ Developers:
dmurtagh
Fixed a bug that UserDefault::getDoubleForKey() doesn't pass default value to Java.
Fixed a compile error when CC_SPRITE_DEBUG_DRAW is on
seobyeongky
Updates spine runtime.

View File

@ -1,10 +1,11 @@
cocos2d-x-3.8 ??
[NEW] ui: Enhance ScrollView with easing out scrolling
[NEW] Animate: Added Animate's getCurrentFrameIndex function
[FIX] renderer: UI component can't click correctly by moving UI and camera far away of origin.
[FIX] JS: Fixed issue of iOS/JS reflection `callStaticMethod` with bool arg
cocos2d-x-3.7.1 ??
cocos2d-x-3.7.1 August.12 2015
[HIGHLIGHT] studio: Added new skeleton animation support and csb parser for cocos v2.3.2 beta
[HIGHLIGHT] studio: Added new skeleton animation support and JSON parser in the web engine
[HIGHLIGHT] studio: Added Skybox csb/JSON parser for cocos v2.3.2 beta
@ -12,21 +13,31 @@ cocos2d-x-3.7.1 ??
[NEW] Node: Added getNodeToParentTransform with selected ancestor
[NEW] studio: Parsed Touch/Click/Event callback in JSON parser
[NEW] web: Added cc.director.setClearColor and support transparent background
[NEW] web: Added Animate's getCurrentFrameIndex function
[REFINE] Widget: Synchronize enable state and bright state for Widget
[REFINE] studio: Optimized JSON parser's performance by removing audio play
[REFINE] studio: Optimized editor related extension data to a component instead of hosting in _userObject
[REFINE] studio: Updated Game3DNodeReader & UserCameraReader
[REFINE] Label: Remove file error notice label from TextBMFontReader
[REFINE] JSB: Add firefox remote debugger support in JS templates
[REFINE] web: Improved color/opacity manipulations in MenuItems
[FIX] Scene: Fixed Scene can't be inherited with std::vector members
[FIX] Sprite: Fixed a compile error when CC_SPRITE_DEBUG_DRAW is on
[FIX] Label: Fixed creation fail if the font(TTF) contains a non-unicode charmap
[FIX] Label: Fixed LabelAtlas rendering error for invalid characters and characters out of boundaries
[FIX] Label: Fixed Mac system font crash issue
[FIX] platform: Fixed building with system prebuilt libs on Linux
[FIX] studio: Fixed ccs.Skin construction issue in JSON parser
[FIX] studio: Fixed Particle3d crash while reading file with error
[FIX] studio: Fixed parser crash when sprite 3d resource isn't correct
[FIX] UI: Fixed CheckBox issue that _isSelected state is updated after event processing callbacks
[FIX] JSB: Fixed JSON parser issue that 3d particle can not be displayed
[FIX] web: Fixed an issue that loading process won't trigger callback problem
[FIX] web: Fixed a bug where not resetting cc.Audio._ignoreEnded when replaying a sound caused it to stay in a "playing" state
[FIX] web: cc.ScrollView and cc.TableView: added check for parent visibility in onTouchBegan method
[FIX] web: Fixed TurnPageDown effect
[FIX] web: Fixed Cocos Studio parser issue that all elements are missing while the timeline action contains rotation
cocos2d-x-3.7final July.21 2015
[REFINE] JS: Improve manual binding code for `retain`, `release`, `onEnter`, `onExit`, `onEnterTransitionDidFinish` and `onExitTransitionDidStart`

View File

@ -105,36 +105,54 @@ void BoneNode::addSkin(SkinNode* skin, bool display)
void BoneNode::removeChild(Node* child, bool cleanup /* = true */)
{
Node::removeChild(child, cleanup);
ssize_t index = _children.getIndex(child);
if (index != cocos2d::CC_INVALID_INDEX)
{
removeFromChildrenListHelper(child);
Node::removeChild(child, cleanup);
}
}
void BoneNode::removeFromBoneList(BoneNode* bone)
{
auto skeletonNode = dynamic_cast<SkeletonNode*>(bone);
if (skeletonNode == nullptr) //not a nested skeleton
if (_rootSkeleton != nullptr)
{
auto skeletonNode = dynamic_cast<SkeletonNode*>(bone);
if (skeletonNode == nullptr) // is not a nested skeleton
{
bone->_rootSkeleton = nullptr;
auto subBones = bone->getAllSubBones();
subBones.pushBack(bone);
for (auto &subBone : subBones)
{
if (subBone->_rootSkeleton == nullptr)
continue;
subBone->_rootSkeleton = nullptr;
_rootSkeleton->_subBonesMap.erase(subBone->getName());
if (bone->_isRackShow && bone->_visible)
auto toremoveIter = _rootSkeleton->_subBonesMap.find(subBone->getName());
if (toremoveIter != _rootSkeleton->_subBonesMap.end())
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
_rootSkeleton->_subBonesMap.erase(toremoveIter);
_rootSkeleton->_subBonesDirty = true;
_rootSkeleton->_subBonesOrderDirty = true;
}
}
}
else
{
_rootSkeleton->_subBonesDirty = true;
_rootSkeleton->_subBonesOrderDirty = true;
}
}
_childBones.eraseObject(bone);
}
void BoneNode::addToBoneList(BoneNode* bone)
{
_childBones.pushBack(bone);
if (bone->_rootSkeleton == nullptr && _rootSkeleton != nullptr)
if (_rootSkeleton != nullptr)
{
auto skeletonNode = dynamic_cast<SkeletonNode*>(bone);
if (skeletonNode == nullptr && bone->_rootSkeleton == nullptr) // not nest skeleton
{
auto subBones = bone->getAllSubBones();
subBones.pushBack(bone);
@ -145,20 +163,18 @@ void BoneNode::addToBoneList(BoneNode* bone)
if (_rootSkeleton->_subBonesMap.find(bonename) == _rootSkeleton->_subBonesMap.end())
{
_rootSkeleton->_subBonesMap.insert(subBone->getName(), subBone);
if (bone->_isRackShow && bone->_visible)
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
}
_rootSkeleton->_subBonesDirty = true;
_rootSkeleton->_subBonesOrderDirty = true;
}
else
CCLOG("already has a bone named %s in skeleton %s", bonename.c_str(), _rootSkeleton->getName().c_str());
}
if (bone->_isRackShow && bone->_visible)
}
else
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
_rootSkeleton->_subBonesDirty = true;
_rootSkeleton->_subBonesOrderDirty = true;
}
}
}
@ -285,11 +301,6 @@ void BoneNode::setDebugDrawEnabled(bool isDebugDraw)
if (_isRackShow == isDebugDraw)
return;
_isRackShow = isDebugDraw;
if (_visible && nullptr != _rootSkeleton)
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
}
}
void BoneNode::setDebugDrawColor(const cocos2d::Color4F &color)
@ -298,12 +309,67 @@ void BoneNode::setDebugDrawColor(const cocos2d::Color4F &color)
updateColor();
}
void BoneNode::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
uint32_t flags = processParentFlags(parentTransform, parentFlags);
// IMPORTANT:
// To ease the migration to v3.0, we still support the Mat4 stack,
// but it is deprecated and your code should not rely on it
_director->pushMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
_director->loadMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
bool visibleByCamera = isVisitableByVisitingCamera();
bool isdebugdraw = visibleByCamera && _isRackShow && nullptr == _rootSkeleton;
int i = 0;
if (!_children.empty())
{
sortAllChildren();
// draw children zOrder < 0
for (; i < _children.size(); i++)
{
auto node = _children.at(i);
if (_rootSkeleton != nullptr && _boneSkins.contains(node)) // skip skin when bone is in a skeleton
continue;
if (node && node->getLocalZOrder() < 0)
node->visit(renderer, _modelViewTransform, flags);
else
break;
}
// self draw
if (isdebugdraw)
this->draw(renderer, _modelViewTransform, flags);
for (auto it = _children.cbegin() + i; it != _children.cend(); ++it)
{
auto node = (*it);
if (_rootSkeleton != nullptr && _boneSkins.contains(node)) // skip skin when bone is in a skeleton
continue;
node->visit(renderer, _modelViewTransform, flags);
}
}
else if (isdebugdraw)
{
this->draw(renderer, _modelViewTransform, flags);
}
_director->popMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
// FIX ME: Why need to set _orderOfArrival to 0??
// Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
// reset for next frame
// _orderOfArrival = 0;
}
void BoneNode::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
{
if (!_isRackShow || nullptr != _rootSkeleton)
return;
_customCommand.init(_globalZOrder, transform, flags);
_customCommand.func = CC_CALLBACK_0(BoneNode::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
@ -479,7 +545,7 @@ void BoneNode::batchBoneDrawToSkeleton(BoneNode* bone) const
}
int count = bone->_rootSkeleton->_batchedVeticesCount;
if (count + 8 >(int)(bone->_rootSkeleton->_batchedBoneVetices.capacity()))
if (count + 8 >(int)(bone->_rootSkeleton->_batchedBoneVetices.size()))
{
bone->_rootSkeleton->_batchedBoneVetices.resize(count + 100);
bone->_rootSkeleton->_batchedBoneColors.resize(count + 100);
@ -501,11 +567,47 @@ void BoneNode::batchBoneDrawToSkeleton(BoneNode* bone) const
#endif //CC_STUDIO_ENABLED_VIEW
}
// call after self visit
void BoneNode::visitSkins(cocos2d::Renderer* renderer, BoneNode* bone) const
{
// quick return if not visible. children won't be drawn.
if (!bone->_visible)
{
return;
}
// IMPORTANT:
// To ease the migration to v3.0, we still support the Mat4 stack,
// but it is deprecated and your code should not rely on it
_director->pushMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
_director->loadMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, bone->_modelViewTransform);
if (!bone->_boneSkins.empty())
{
bone->sortAllChildren();
for (auto it = bone->_boneSkins.cbegin(); it != bone->_boneSkins.cend(); ++it)
(*it)->visit(renderer, bone->_modelViewTransform, true);
}
_director->popMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
// FIX ME: Why need to set _orderOfArrival to 0??
// Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
// reset for next frame
// _orderOfArrival = 0;
}
void BoneNode::setRootSkeleton(BoneNode* bone, SkeletonNode* skeleton) const
{
bone->_rootSkeleton = skeleton;
}
void BoneNode::setLocalZOrder(int localZOrder)
{
Node::setLocalZOrder(localZOrder);
if (_rootSkeleton != nullptr && this->_visible && this->_isRackShow)
_rootSkeleton->_subDrawBonesOrderDirty = true;
if (_rootSkeleton != nullptr)
_rootSkeleton->_subBonesOrderDirty = true;
}
void BoneNode::setName(const std::string& name)
@ -549,11 +651,6 @@ void BoneNode::removeFromChildrenListHelper(Node * child)
if (nullptr != bone)
{
removeFromBoneList(bone);
if (bone->_isRackShow)
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
}
}
else
{
@ -571,10 +668,10 @@ void BoneNode::setVisible(bool visible)
return;
Node::setVisible(visible);
if (_isRackShow && _rootSkeleton != nullptr)
if (_rootSkeleton != nullptr)
{
_rootSkeleton->_subDrawBonesDirty = true;
_rootSkeleton->_subDrawBonesOrderDirty = true;
_rootSkeleton->_subBonesDirty = true;
_rootSkeleton->_subBonesOrderDirty = true;
}
}

View File

@ -109,7 +109,8 @@ public:
virtual void setBlendFunc(const cocos2d::BlendFunc &blendFunc) override;
virtual const cocos2d::BlendFunc & getBlendFunc() const override { return _blendFunc; }
// debug draw show, bone's debugdraw can be draw when bone is visible && enable debug draw
// debug draw show, bone's debugdraw can be draw when bone is visible
// when bone's added to skeleton, DebugDrawEnabled controled by skeleton's DebugDrawEnabled
virtual void setDebugDrawEnabled(bool isDebugDraw);
virtual bool isDebugDrawEnabled() const { return _isRackShow; }
@ -186,10 +187,20 @@ protected:
virtual void onDraw(const cocos2d::Mat4 &transform, uint32_t flags);
// override Node::visit, just visit bones in children
virtual void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags) override;
// a help function for SkeletonNode
// for batch bone's draw to _rootSkeleton
virtual void batchBoneDrawToSkeleton(BoneNode* bone) const;
// a help funciton for SkeletonNode
// @param bone, visit bone's skins
virtual void visitSkins(cocos2d::Renderer* renderer, BoneNode* bone) const;
// a help function for SkeletonNode
// set bone's rootSkeleton = skeleton
void setRootSkeleton(BoneNode* bone, SkeletonNode* skeleton) const;
protected:
cocos2d::CustomCommand _customCommand;
cocos2d::BlendFunc _blendFunc;

View File

@ -101,14 +101,18 @@ cocos2d::Rect SkeletonNode::getBoundingBox() const
SkeletonNode::SkeletonNode()
: BoneNode()
, _subDrawBonesDirty(true)
, _subDrawBonesOrderDirty(true)
, _subBonesDirty(true)
, _subBonesOrderDirty(true)
, _batchedVeticesCount(0)
{
}
SkeletonNode::~SkeletonNode()
{
for (auto &bonepair : _subBonesMap)
{
setRootSkeleton(bonepair.second, nullptr);
}
}
void SkeletonNode::updateVertices()
@ -161,10 +165,7 @@ void SkeletonNode::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& paren
_director->pushMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
_director->loadMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
bool visibleByCamera = isVisitableByVisitingCamera();
int i = 0;
if (!_children.empty())
{
sortAllChildren();
@ -183,7 +184,13 @@ void SkeletonNode::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& paren
(*it)->visit(renderer, _modelViewTransform, flags);
}
if (visibleByCamera)
checkSubBonesDirty();
for (const auto& bone : _subOrderedAllBones)
{
visitSkins(renderer, bone);
}
if (_isRackShow)
{
this->draw(renderer, _modelViewTransform, flags);
// batch draw all sub bones
@ -200,9 +207,6 @@ void SkeletonNode::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& paren
void SkeletonNode::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
{
if (!_isRackShow)
return;
_customCommand.init(_globalZOrder, transform, flags);
_customCommand.func = CC_CALLBACK_0(SkeletonNode::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
@ -218,18 +222,14 @@ void SkeletonNode::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transf
void SkeletonNode::batchDrawAllSubBones(const cocos2d::Mat4 &transform)
{
if (_subDrawBonesDirty)
{
updateAllDrawBones();
}
if (_subDrawBonesOrderDirty)
sortAllDrawBones();
checkSubBonesDirty();
_batchedVeticesCount = 0;
for (const auto& bone : _subDrawBones)
for (const auto& bone : _subOrderedAllBones)
{
batchBoneDrawToSkeleton(bone);
}
cocos2d::Vec3* vetices = _batchedBoneVetices.data();
cocos2d::Color4F* veticesColor = _batchedBoneColors.data();
getGLProgram()->use();
@ -321,37 +321,49 @@ void SkeletonNode::addSkinGroup(std::string groupName, std::map<std::string, std
_skinGroupMap.insert(std::make_pair(groupName, boneSkinNameMap));
}
void SkeletonNode::updateAllDrawBones()
void SkeletonNode::checkSubBonesDirty()
{
_subDrawBones.clear();
// get All Visible SubBones
if (_subBonesDirty)
{
updateOrderedAllbones();
_subBonesDirty = false;
}
if (_subBonesOrderDirty)
{
sortOrderedAllBones();
_subBonesOrderDirty = false;
}
}
void SkeletonNode::updateOrderedAllbones()
{
_subOrderedAllBones.clear();
// update sub bones, get All Visible SubBones
// get all sub bones as visit with visible
std::stack<BoneNode*> boneStack;
for (const auto& bone : _childBones)
{
if (bone->isVisible() && bone->isDebugDrawEnabled())
if (bone->isVisible())
boneStack.push(bone);
}
while (boneStack.size() > 0)
{
auto top = boneStack.top();
_subDrawBones.pushBack(top);
_subOrderedAllBones.pushBack(top);
boneStack.pop();
auto topChildren = top->getChildBones();
for (const auto& childbone : topChildren)
{
if (childbone->isVisible() && childbone->isDebugDrawEnabled())
if (childbone->isVisible())
boneStack.push(childbone);
}
}
_subDrawBonesDirty = false;
}
void SkeletonNode::sortAllDrawBones()
void SkeletonNode::sortOrderedAllBones()
{
std::sort(_subDrawBones.begin(), _subDrawBones.end(), cocos2d::nodeComparisonLess);
_subDrawBonesOrderDirty = false;
std::sort(_subOrderedAllBones.begin(), _subOrderedAllBones.end(), cocos2d::nodeComparisonLess);
}
NS_TIMELINE_END

View File

@ -97,17 +97,19 @@ private:
CC_DISALLOW_COPY_AND_ASSIGN(SkeletonNode);
void checkSubBonesDirty();
// for draw skins as ordered bones' local z
cocos2d::Vector<BoneNode*> _subOrderedAllBones;
void updateOrderedAllbones();
void sortOrderedAllBones();
// for batch draw sub bones
bool _subDrawBonesDirty;
bool _subDrawBonesOrderDirty;
cocos2d::Vector<BoneNode*> _subDrawBones; // for draw faster, cache a list from _subBonesMap, sorted by render order
bool _subBonesDirty;
bool _subBonesOrderDirty;
std::vector<cocos2d::Vec3> _batchedBoneVetices;
std::vector<cocos2d::Color4F> _batchedBoneColors;
int _batchedVeticesCount;
cocos2d::CustomCommand _batchBoneCommand;
void updateAllDrawBones();
void sortAllDrawBones();
void batchDrawAllSubBones(const cocos2d::Mat4 &transform);
void batchSubBone(BoneNode* bone);
};

View File

@ -147,14 +147,10 @@ namespace cocostudio
auto fileData = options->fileData();
std::string path = fileData->path()->c_str();
ParticleSystem3D* ret = NULL;
if(!FileUtils::getInstance()->isFileExist(path))
PUParticleSystem3D* ret = PUParticleSystem3D::create();
if (FileUtils::getInstance()->isFileExist(path))
{
ret = PUParticleSystem3D::create();
}
else
{
ret = PUParticleSystem3D::create(path);
ret->initWithFilePath(path);
}
setPropsWithFlatBuffers(ret, particle3DOptions);

View File

@ -233,16 +233,16 @@ namespace cocostudio
{
labelBMFont->setFntFile(path);
}
else
{
if (!errorContent.empty())
{
errorFilePath = path;
auto label = Label::create();
label->setString(__String::createWithFormat("%s %s", errorFilePath.c_str(), errorContent.c_str())->getCString());
labelBMFont->addChild(label);
}
}
//else
//{
// if (!errorContent.empty())
// {
// errorFilePath = path;
// auto label = Label::create();
// label->setString(__String::createWithFormat("%s %s", errorFilePath.c_str(), errorContent.c_str())->getCString());
// labelBMFont->addChild(label);
// }
//}
std::string text = options->text()->c_str();
labelBMFont->setString(text);

View File

@ -1519,10 +1519,12 @@
if(json["FileData"] && json["FileData"]["Path"])
resFile = resourcePath + json["FileData"]["Path"];
var node;
if(resFile)
var node = null;
if(resFile) {
if(jsb.fileUtils.isFileExist(resFile))
node = jsb.Sprite3D.create(resFile);
else
}
if(null === node)
node = jsb.Sprite3D.create();
if(node) {
@ -1561,9 +1563,12 @@
if(json["FileData"] && json["FileData"]["Path"])
resFile = resourcePath+json["FileData"]["Path"];
if(resFile)
if(resFile){
if(jsb.fileUtils.isFileExist(resFile))
node = jsb.PUParticleSystem3D.create(resFile);
else
}
if(null === node)
node = jsb.PUParticleSystem3D.create();
if(node){

View File

@ -94,22 +94,23 @@ CheckBox* CheckBox::create(const std::string& backGround,
return nullptr;
}
void CheckBox::releaseUpEvent()
void CheckBox::onTouchEnded(Touch *touch, Event *unusedEvent)
{
Widget::releaseUpEvent();
if (_isSelected)
{
setSelected(false);
AbstractCheckButton::onTouchEnded(touch, unusedEvent);
dispatchSelectChangedEvent(false);
}
else
{
setSelected(true);
AbstractCheckButton::onTouchEnded(touch, unusedEvent);
dispatchSelectChangedEvent(true);
}
}
void CheckBox::dispatchSelectChangedEvent(bool selected)
{
EventType eventType = (selected ? EventType::SELECTED : EventType::UNSELECTED);

View File

@ -162,8 +162,8 @@ public:
//override functions
virtual std::string getDescription() const override;
virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override;
protected:
virtual void releaseUpEvent() override;
virtual void dispatchSelectChangedEvent(bool selected) override;

View File

@ -267,6 +267,7 @@ Widget* Widget::getWidgetParent()
void Widget::setEnabled(bool enabled)
{
_enabled = enabled;
setBright(enabled);
}
void Widget::initRenderer()

View File

@ -14,20 +14,17 @@
- [Windows](#windows)
- [Linux](#linux)
- [How to start a new game](#how-to-start-a-new-game)
- [v3.7](#v37)
- [Highlights of v3.7](#highlights-of-v37)
- [v3.7.1](#v371)
- [Highlights of v3.7.1](#highlights-of-v371)
- [Download](#download)
- [The main features in detail:](#the-main-features-in-detail)
- [3D Physics](#3d-physics)
- [3D Navigation mesh](#3d-navigation-mesh)
- [Material system](#material-system)
- [All in one Cocos2d-x](#all-in-one-cocos2d-x)
- [Enhanced Polygon Sprite](#enhanced-polygon-sprite)
- [WebView and VideoPlayer in JS (native and web)](#webview-and-videoplayer-in-js-native-and-web)
- [Nine Patch format support](#nine-patch-format-support)
- [Android Studio support](#android-studio-support)
- [Samsung Enhanced API support](#samsung-enhanced-api-support)
- [SDKBOX](#sdkbox)
- [Skeleton Animation](#skeleton-animation)
- [Get Node's transform to its ancestor](#get-nodes-transform-to-its-ancestor)
- [Set background color for web engine](#set-background-color-for-web-engine)
- [Widget's enable state and bright state](#widgets-enable-state-and-bright-state)
- [Firefox remote debugger support](#firefox-remote-debugger-support)
- [v3.7](#v37)
- [Highlights of v3.7](#highlights-of-v37)
- [The Next Step](#the-next-step)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@ -56,7 +53,8 @@
* gcc 4.9 or newer for Linux
* ndk-r10c for Android
* Visual Studio 2013 or newer for Windows (win32)
* Visual Studio 2013 update4 or newer for Windows Phone 8
* Visual Studio 2013 update4 or newer for Windows 8.1 universal Apps
* Visual Studio 2015 RC or newer and Windows 10.0 (build 10074 or higher) for Windows 10.0 UWP Apps
## How to run tests
@ -121,6 +119,7 @@ Then
* For win32 project, enter `cocos2d-x/build`, and open `cocos2d-win32.sln` or `cocos2d-js-win32.sln`
* For win 8.1 project, enter `cocos2d-x/build`, and open `cocos2d-win8.1-universal.sln` or `cocos2d-js-win8.1-universal.sln`
* For win 10 project, enter `cocos2d-x/build`, and open `cocos2d-win10.sln`
* Select running target
* Click run button
@ -150,6 +149,102 @@ Use Cocos Console to create a new game:
cocos new -l cpp|js|lua MyGame
```
# v3.7.1
## Highlights of v3.7.1
Cocos2d-x v3.7.1 is a stable version based on v3.7. The most important update is that we added skeleton animation support for Cocos 2.3.2Beta.
* [NEW] studio: Added new skeleton animation support and csb parser for cocos v2.3.2 beta
* [NEW] studio: Added new skeleton animation support and JSON parser in the web engine
* [NEW] studio: Added Skybox csb/JSON parser for cocos v2.3.2 beta
* [NEW] studio: Parsed Touch/Click/Event callback in JSON parser
* [NEW] Node: Added getNodeToParentTransform with selected ancestor
* [NEW] web: Added cc.director.setClearColor and support transparent background
* [REFINE] Widget: Synchronize enable state and bright state for Widget
* [REFINE] studio: Optimized JSON parser's performance by removing audio play
* [REFINE] JSB: Add Firefox remote debugger support in JS templates
## Download
[Cocos2d-x v3.7.1](http://www.cocos2d-x.org/filedown/cocos2d-x-3.7.1.zip) including : C++, Lua & JS
## The main features in detail:
### Skeleton Animation
In v3.7.1 and Cocos 2.3.2, we are providing a new skeleton animation system which is different from Armature. The reason is that we abstract ActionTimeline system to support all sort of animations but Armature doesn't support it. To benefit the timeline system and to make skeleton animation system much more compact, we have implemented the new skeleton animation system. From this version, you will be able to edit skeleton animations in Cocos v2.
New skeleton animation system contains `BoneNode`, `SkeletonNode`, `SkinNode`. SkeletonNode is a subclass of BoneNode and extended container functionalities, so it can contain BoneNode and nested SkeletonNode to construct a skeleton.
Features provided:
1. Playable skeleton animation
2. Nested skeleton
3. Skin replacement
4. Time scale control
5. Debug draw
6. Frame event callback
New skeleton animation is also supported by the web engine. We will keep enhancing it in the future versions.
![](https://raw.githubusercontent.com/minggo/Pictures/master/action-timeline.gif)
### Get Node's transform to its ancestor
We have added a new functionality in `getNodeToParentTransform` API of Node, in v3.7.1, you can pass a ancestor as a parameter to get the node's transform related to this specific ancestor. Here is an example:
```
auto parent2 = Node::create();
auto parent1 = Node::create();
auto node = Node::create();
parent2->addChild(parent1);
parent1->addChild(node);
// This will give you the transform of node in parent2's coordinate system
auto transform = node->getNodeToParentTransform(parent2);
```
This API is also usable in the web engine.
### Set background color for web engine
From v3.7.1, you can control the background of your game in the web engine easily. We have provided a new API: `cc.director.setClearColor()`. The color you passed can be non-transparent or with transparency. Note that if the clear color you want is not transparent, it's more efficient than creating a background layer. Take a look at the example:
```
// Solution1: Using colored background layer
var background = cc.LayerColor(cc.color(255, 0, 0));
background.width = cc.winSize.width;
background.height = cc.winSize.height;
// This will give you a red background
scene.addChild(background, 0);
// Solution2: Using setClearColor
// This will give you a red background and much more efficient than solution1
cc.director.setClearColor(cc.color(255, 0, 0));
```
Besides, you can make your background totally tranparent too.
### Widget's enable state and bright state
In the old Widget API design, `setEnabled` only controls whether the widget should respond to user input events, while `setBright` only controls whether the widget's display should be in gray state (which indicates disable) or bright state (which indicates enable). This is very frustrating for our developers. So from v3.7.1, we decided to synchronise bright state with enable state. That means, once your widghet is disabled via `setEnabled(false)`, its display will also change to gray state.
```
// In old version, you will do
widget->setEnabled(false);
widget->setBright(false);
// In v3.7.1, you only need to do
widget->setEnabled(false);
```
### Firefox remote debugger support
In v3.7.1, we have enabled Firefox remote debugger support for JSB projects. You only need to follow [this documentation](http://www.cocos2d-x.org/docs/manual/framework/native/v3/js-remote-debugger/en), and you can debug your JSB projects with your Firefox browser. Note that it permits you to debug JavaScript code in your JSB project, for native code debugging you should still use Xcode or Visual Studio.
![](https://raw.githubusercontent.com/minggo/Pictures/master/js-remote-debug.png)
# v3.7
## Highlights of v3.7
@ -171,92 +266,7 @@ cocos new -l cpp|js|lua MyGame
* console: Supported build & run Android Studio project with cocos console
* SDKBOX: super EASY way to integrate 3rd party SDKs into cocos2d-x
## Download
[Cocos2d-x v3.7](http://www.cocos2d-x.org/filedown/cocos2d-x-3.7.zip) including : C++, Lua & JS
## The main features in detail:
### 3D Physics
It's the physics engine we provided for providing 3D physics game capability, it works great with our current 3D modules, like 3D sprites, 3D Terrain, etc. We used [bullet](http://bulletphysics.org/wordpress/) library as base of 3D physics, encapsulate it into our Cocos 3D physics APIs. You can refer to Physics3DTest test case for its API and usage, we will add documentation into [programmers guide](http://cocos2d-x.org/programmersguide) lately.
![](http://cdn.cocimg.com/bbs/attachment/Fid_41/41_300874_348f31ee628da2b.png)
### 3D Navigation mesh
The navigation mesh system provides simple to use API to find path in a complexe 3D world, you can add mesh with a triangles list, add obstacles. Then you will add agents which can perform a path finding task and move your 3D sprites to a certain place following the path. You can refer to NavmeshTest test case for its API and usage, we will add documentation into [programmers guide](http://cocos2d-x.org/programmersguide) lately.
![](http://cdn.cocimg.com/bbs/attachment/Fid_41/41_300874_6589cbf376a639b.png)
### Material system
Material system is an advanced system which defines all visual informations (it may contain aural or physical informations in the future) of an object. Instead of just plain an simple texture, you can have more than one texture, and much more features like multi-pass rendering. Refer to [the documentation](https://github.com/chukong/programmers-guide/blob/v3.7/chapters/14.md#shaders-and-materials) for more details.
![](http://cdn.cocimg.com/bbs/attachment/Fid_41/41_300874_a94a91aeeaf401d.png)
### All in one Cocos2d-x
After merged Cocos2d-JS into Cocos2d-x, nothing have changed for C++ and Lua developers, but the engine structure may look very strange to JS developers. Don't worry, the upgrade is still very simple, because the project structure remains the same as before. Refer to [this discussion](http://discuss.cocos2d-x.org/t/cocos2d-js-v3-6-1-hot-fix-for-remote-debugger/21524/2) for more informations.
### Enhanced Polygon Sprite
As it's not very easy to used in the previous version, we have refactored the API for Polygon Sprite. It's now becoming a internal feature of 2d Sprite, you can use AutoPolygon to generate polygons for a sprite, then use it to create the sprite directly, very simple to use.
```
auto pinfo = AutoPolygon::generatePolygon("filename.png");
auto spp = Sprite::create(pinfo);
```
Although it do takes time to generate the polygons information, you can cache and reuse it, we also plan to support the polygons information generation in the editor in the future.
![](http://cdn.cocimg.com/bbs/attachment/Fid_41/41_300874_7b5ef9b52f054f3.png)
### WebView and VideoPlayer in JS (native and web)
The WebView and VideoPlayer have finally been ported to JS, and it supports iOS, Android and Web browsers. You can refer to its usage in the test case: [WebViewTest](https://github.com/cocos2d/cocos2d-x/blob/v3/tests/js-tests/src/GUITest/UIWebViewTest/UIWebViewTest.js) and [VideoPlayerTest](https://github.com/cocos2d/cocos2d-x/blob/v3/tests/js-tests/src/GUITest/UIVideoPlayerTest/UIVideoPlayerTest.js).
### Nine Patch format support
The Nine Patch image is a stretchable bitmap image which can be used as the texture of Scale9Sprite. Now Cocos2d-x support creating the Scale9Sprite node directly with a Nine Patch file. More informations about the [Nine Patch format](http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch) and [its tool](http://developer.android.com/tools/help/draw9patch.html). You can also refer to our test case for its usage: [C++](https://github.com/cocos2d/cocos2d-x/blob/v3/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.cpp#L857), [Lua](https://github.com/cocos2d/cocos2d-x/blob/v3/tests/lua-tests/src/CocoStudioTest/CocoStudioGUITest/CocoStudioGUITest.lua#L4020), [JS](https://github.com/cocos2d/cocos2d-x/blob/v3/tests/js-tests/src/GUITest/UIS9NinePatchTest/UIS9NinePatchTest.js)
### Android Studio support
Cocos console now supports compilation and package with Android Studio 1.2, use it with a `--android-studio` flag
```
cocos run/compile -p android --android-studio
```
### Samsung Enhanced API support
Samsung have provided a series of Enhanced API to optimize Cocos2d-x games for Samsung products with Android 5.0+ system. It include some very cool features like: Boost Up API, Power Saving Mode API, Dynamic FPS API, etc. The current API can be found in [this header file](https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/platform/android/CCEnhanceAPI-android.h), we will provide a detailed documentation later.
### Win32 platform resource name become case sensitive
In the previous versions, the resources file name's case is ignored on win32 platform, but not ignored in other platforms. This will lead to some unexpected issues, especially when user develop with win32 platform and pulish to other platforms like Android. In win32, the file name may be found without matching the case, but on other platforms it won't be found. So we decided to make win32 platform's resources case sensitive. Please make sure you are using the correct file name for your resources.
### SDKBOX
SDKBOX is a project that's built by part of the cocos2d-x team, in order to makes integrating 3rd party SDKs super EASY.
With SDKBOX you can integrate services like In App Purchase with one command
```
sdkbox import -b iap
```
Currently supported service including
* [Tune](http://cocos2d-x.org/sdkbox/tune)
* [In App Purchase](http://cocos2d-x.org/sdkbox/iap)
* [AdColony](http://cocos2d-x.org/sdkbox/adcolony)
* [Vungle](http://cocos2d-x.org/sdkbox/vungle)
* [Chartboost](http://cocos2d-x.org/sdkbox/chartboost)
* [Kochava](http://cocos2d-x.org/sdkbox/kochava)
* [Google Analytics](http://cocos2d-x.org/sdkbox/googleanalytics)
* [Flurry Analytics](http://cocos2d-x.org/sdkbox/flurryanalytics)
## The Next Step
# The Next Step
As you can see, in v3.7, we have enhanced our 2d rendering with material system and integrated polygon sprite. More importantly, our 3d features become more and more complete, 3d Physics and Navigation Mesh with the previous Camera, 3d Sprite, 3d Particle System, 3d Light, 3d Terrain, Skybox, now you can really start to use Cocos to make a 3d game.

View File

@ -38,6 +38,8 @@ PUParticleSystem3DTranslator::~PUParticleSystem3DTranslator()
void PUParticleSystem3DTranslator::translate(PUScriptCompiler* compiler, PUAbstractNode *node)
{
if (typeid(*node) != typeid(PUObjectAbstractNode))
return;
PUObjectAbstractNode* obj = reinterpret_cast<PUObjectAbstractNode*>(node);
if(obj->name.empty())

View File

@ -343,14 +343,10 @@ void TestActionTimelineSkeleton::onEnter()
boneDrawsBtn->setPosition(Vec2(VisibleRect::right().x - 30, VisibleRect::top().y - 30));
boneDrawsBtn->setTitleText("Draw bone");
_isAllBonesDraw = true;
skeletonNode->setDebugDrawEnabled(_isAllBonesDraw);
setAllSubBonesDebugDraw(skeletonNode, _isAllBonesDraw);
skeletonNode->setDebugDrawEnabled(true);
boneDrawsBtn->addClickEventListener([skeletonNode, this](Ref* sender)
{
_isAllBonesDraw = !_isAllBonesDraw;
skeletonNode->setDebugDrawEnabled(_isAllBonesDraw);
setAllSubBonesDebugDraw(skeletonNode, _isAllBonesDraw);
skeletonNode->setDebugDrawEnabled(!skeletonNode->isDebugDrawEnabled());
});
@ -553,16 +549,6 @@ std::string TestActionTimelineSkeleton::title() const
return "Test ActionTimeline Skeleton";
}
void TestActionTimelineSkeleton::setAllSubBonesDebugDraw(SkeletonNode* rootSkeleton, bool isShow)
{
auto boneMap = rootSkeleton->getAllSubBonesMap();
for (auto& bonePair : boneMap)
{
bonePair.second->setDebugDrawEnabled(isShow);
}
}
// TestTimelineExtensionData
void TestTimelineExtensionData::onEnter()
{

View File

@ -127,11 +127,8 @@ public:
virtual std::string title() const override;
private:
void setAllSubBonesDebugDraw(cocostudio::timeline::SkeletonNode* rootSkeleton, bool isShow);
bool _changedDisplay;
bool _changedDisplays;
bool _isAllBonesDraw;
};
class TestTimelineExtensionData : public ActionTimelineBaseTest

View File

@ -83,6 +83,134 @@ var LoaderTestLayer = BaseTestLayer.extend({
sprite.y = winSize.height/2;
});
},
onNextCallback: function(){
var parent = this.getParent();
parent.removeChild(this);
parent.addChild(new LoaderCycleLayer());
}
});
var LoaderCycleLayer = BaseTestLayer.extend({
_title:"Failed to load Test",
_subtitle:"",
ctor: function(){
BaseTestLayer.prototype.ctor.call(this);
var index = 0;
var winSize = cc.director.getWinSize();
var t = this,
cb = function(num){
var labelTTF = new cc.LabelTTF(num + " file failed");
labelTTF.x = index++*100 + winSize.width - 150;
labelTTF.y = winSize.height / 2 - 20;
if(num === 1)
labelTTF.setColor(cc.color.GREEN);
else
labelTTF.setColor(cc.color.RED);
t.addChild(labelTTF);
if(index < 4)
t.test(cb);
};
this.createInfo();
this.regLoad();
this.test(cb);
},
regLoad: function(){
cc.loader.register(["_test1"], {
load: function(realUrl, url, res, cb){
cc.loader.cache[url] = {};
setTimeout(function(){
cb && cb(null, cc.loader.cache[url]);
return cc.loader.cache[url];
}, Math.random()*1000);
}
});
cc.loader.register(["_test2"], {
load: function(realUrl, url, res, cb){
cb && cb({});
return null;
}
});
},
list: [
"1._test2",
"1._test1",
"2._test1",
"3._test1",
"4._test1"
],
createInfo: function(){
var winSize = cc.director.getWinSize();
var info1 = new cc.LabelTTF("Load 5 files");
info1.x = winSize.width / 2;
info1.y = winSize.height / 2 + 80;
var info2 = new cc.LabelTTF("1 file does not exist");
info2.x = winSize.width / 2;
info2.y = winSize.height / 2 + 60;
var info3 = new cc.LabelTTF("The other 4 files should be loaded.");
info3.x = winSize.width / 2;
info3.y = winSize.height / 2 + 40;
this.addChild(info1);
this.addChild(info2);
this.addChild(info3);
var info4 = new cc.LabelTTF("test 1");
info4.x = winSize.width / 2 - 50;
info4.y = winSize.height / 2;
var info5 = new cc.LabelTTF("test 2");
info5.x = winSize.width / 2 - 150;
info5.y = winSize.height / 2;
var info6 = new cc.LabelTTF("test 3");
info6.x = winSize.width / 2 + 50;
info6.y = winSize.height / 2;
var info7 = new cc.LabelTTF("test 4");
info7.x = winSize.width / 2 + 150;
info7.y = winSize.height / 2;
this.addChild(info4);
this.addChild(info5);
this.addChild(info6);
this.addChild(info7);
},
test: function(cb){
this.clearRes();
var layer = this;
cc.loader.load(layer.list, function(){
var num = 0;
layer.list.forEach(function(item){
if(!cc.loader.getRes(item)){
num++;
}
});
cb(num);
});
},
clearRes: function(){
this.list.forEach(function(item){
cc.loader.release(item);
});
},
onRestartCallback: function(){
var parent = this._parent;
parent.removeChild(this);
parent.addChild(new LoaderCycleLayer());
},
onBackCallback: function(){
var parent = this._parent;
parent.removeChild(this);
parent.addChild(new LoaderTestLayer());
}
});