给CCNode做了扩展,方便界面布局
在第一次用cocos2d开发的时候,就感觉界面的布局一点儿都不方便,只能硬生生的去设置每一个精灵的位置。
而自己以前有过QT的开发经验,深感里面的Anchor Layout功能特别好使。简单的思考了一下,通过给CCNode类添加一个
分类,就把AnchorLayout功能给移植到cocos2d-iphone中了。
AnchorLayout的思路就是为一个Node定义Top, Left, Bottom, Right, HorizontalCenter, VerticalCenter几个参考点,
一个Node的某个参考点可以参照另一个Node的某个参照点,从而实现快速确定一个Node的位置。被参照的Node必须是
已经确定位置了的。
两个Node必须为父子关系,或是兄弟关系。
使用时#import "CCNode+AnchorLayout.h"
例如:
[nodeA addAnchor: kCCNodeAnchorLeft referTo: nodeB edge: kCCNodeAnchorRight margin: 20];
上面代码行的作用是将nodeA放在nodeB的右边,间距为20.
[nodeA addAnchor: kCCNodeAnchorLeft referTo: nodeB edge: kCCNodeAnchorLeft margin: 0];
上面代码行的作用是将nodeA与nodeB左对齐。
[nodeA centerIn: nodeB];
上面代码行的作用是将nodeA放在nodeB的中心。
这里就不再多举例了,要想了解更多,可以去google "qt anchor layout",或是看这里"http://doc.qt.digia.com/qt/qml-anchor-layout.html"
下面请看代码:
CCNode+AnchorLayout.h
#import "CCNode.h"
typedef enum
{
kCCNodeAnchorLeft,
kCCNodeAnchorRight,
kCCNodeAnchorTop,
kCCNodeAnchorBottom,
kCCNodeAnchorHorizontalCenter,
kCCNodeAnchorVerticalCenter,
kCCNodeAnchorCenterIn
}CCNodeAnchorT;
@interface CCNode (AnchorLayout)
//limitations:
//1. node should be added into node graph
//2. the referNode should be positioned
//3. if you need to set anchorPoint and scale, please do so before calling these methods
- ( void) addAnchor: ( CCNodeAnchorT)selfEdge referTo: ( CCNode*)referNode edge: ( CCNodeAnchorT)edge margin: ( CGFloat)margin;
- ( void) centerIn: ( CCNode*)outerNode;
@end
CCNode+AnchorLayout.m
#import "CCNode+AnchorLayout.h"
@implementation CCNode (AnchorLayout)
#pragma mark - private methods
- ( CGFloat) edgeOfParentNode: ( CCNode*)node ofAnchor: ( CCNodeAnchorT)anchor
{
CGSize size = [node contentSize];
switch (anchor)
{
casekCCNodeAnchorTop :
return size. height * node. scaleY;
casekCCNodeAnchorLeft :
return 0.0;
casekCCNodeAnchorBottom :
return 0.0;
casekCCNodeAnchorRight :
return size. width * node. scaleX;
casekCCNodeAnchorHorizontalCenter :
return size. width * node. scaleX / 2;
casekCCNodeAnchorVerticalCenter :
return size. height * node. scaleY / 2;
default:
return 0.0;
}
}
- ( CGFloat) edgeOfSiblingNode: ( CCNode*)node ofAnchor: ( CCNodeAnchorT)anchor
{
CGPoint nodePosition = [node position];
CGPoint nodeCenter = CGPointMake(nodePosition. x + ( 0.5-node. anchorPoint. x) * node. contentSize. width * node. scaleX, nodePosition. y+ ( 0.5-node. anchorPoint. y) * node. contentSize. height * node. scaleY);
switch (anchor)
{
casekCCNodeAnchorTop :
return nodeCenter. y + 0.5 * node. contentSize. height * node. scaleY;
casekCCNodeAnchorLeft :
return nodeCenter. x - 0.5 * node. contentSize. width * node. scaleX;
casekCCNodeAnchorBottom :
return nodeCenter. y - 0.5 * node. contentSize. height * node. scaleY;
casekCCNodeAnchorRight :
return nodeCenter. x + 0.5 * node. contentSize. width * node. scaleX;
casekCCNodeAnchorHorizontalCenter :
return nodeCenter. x;
casekCCNodeAnchorVerticalCenter :
return nodeCenter. y;
default:
break;
}
return 0.0;
}
#pragma mark - public methods
- ( void) addAnchor:( CCNodeAnchorT)selfEdge referTo:( CCNode *)referNode edge:( CCNodeAnchorT)edge margin:( CGFloat)margin
{
CGPoint oldPositon = [ self position];
CGFloat centerX = 0.0;
CGFloat centerY = 0.0;
CGFloat selfWidth = self. contentSize. width * self. scaleX;
CGFloat selfHeight = self. contentSize. height * self. scaleY;
if ( self. parent == referNode)
{
//parent-child relationship
switch (selfEdge)
{
casekCCNodeAnchorTop :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge] - margin - selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorLeft :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge] + margin + selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorBottom :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge] + margin + selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorRight :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge] - margin - selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorHorizontalCenter :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorVerticalCenter :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge];
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorCenterIn :
centerX = [ selfedgeOfParentNode : referNode ofAnchor :kCCNodeAnchorHorizontalCenter ];
centerY = [ selfedgeOfParentNode : referNode ofAnchor :kCCNodeAnchorVerticalCenter ];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
default:
break;
}
}
else if ( self. parent == referNode. parent)
{
//two nodes are siblings
switch (selfEdge)
{
casekCCNodeAnchorTop :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorLeft :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorBottom :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorRight :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorHorizontalCenter :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorVerticalCenter :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge];
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorCenterIn :
centerX = [ selfedgeOfSiblingNode : referNode ofAnchor :kCCNodeAnchorHorizontalCenter ];
centerY = [ selfedgeOfSiblingNode : referNode ofAnchor :kCCNodeAnchorVerticalCenter ];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
default:
break;
}
}
else
{
//not allowed
NSAssert ( NO , @"The two nodes must be parent-child or siblings!" );
}
}
- ( void) centerIn:( CCNode *)outerNode
{
[ selfaddAnchor : kCCNodeAnchorCenterInreferTo : outerNode edge :kCCNodeAnchorCenterIn margin : 0 ];
}
@end
而自己以前有过QT的开发经验,深感里面的Anchor Layout功能特别好使。简单的思考了一下,通过给CCNode类添加一个
分类,就把AnchorLayout功能给移植到cocos2d-iphone中了。
AnchorLayout的思路就是为一个Node定义Top, Left, Bottom, Right, HorizontalCenter, VerticalCenter几个参考点,
一个Node的某个参考点可以参照另一个Node的某个参照点,从而实现快速确定一个Node的位置。被参照的Node必须是
已经确定位置了的。
两个Node必须为父子关系,或是兄弟关系。
使用时#import "CCNode+AnchorLayout.h"
例如:
[nodeA addAnchor: kCCNodeAnchorLeft referTo: nodeB edge: kCCNodeAnchorRight margin: 20];
上面代码行的作用是将nodeA放在nodeB的右边,间距为20.
[nodeA addAnchor: kCCNodeAnchorLeft referTo: nodeB edge: kCCNodeAnchorLeft margin: 0];
上面代码行的作用是将nodeA与nodeB左对齐。
[nodeA centerIn: nodeB];
上面代码行的作用是将nodeA放在nodeB的中心。
这里就不再多举例了,要想了解更多,可以去google "qt anchor layout",或是看这里"http://doc.qt.digia.com/qt/qml-anchor-layout.html"
下面请看代码:
CCNode+AnchorLayout.h
#import "CCNode.h"
typedef enum
{
kCCNodeAnchorLeft,
kCCNodeAnchorRight,
kCCNodeAnchorTop,
kCCNodeAnchorBottom,
kCCNodeAnchorHorizontalCenter,
kCCNodeAnchorVerticalCenter,
kCCNodeAnchorCenterIn
}CCNodeAnchorT;
@interface CCNode (AnchorLayout)
//limitations:
//1. node should be added into node graph
//2. the referNode should be positioned
//3. if you need to set anchorPoint and scale, please do so before calling these methods
- ( void) addAnchor: ( CCNodeAnchorT)selfEdge referTo: ( CCNode*)referNode edge: ( CCNodeAnchorT)edge margin: ( CGFloat)margin;
- ( void) centerIn: ( CCNode*)outerNode;
@end
CCNode+AnchorLayout.m
#import "CCNode+AnchorLayout.h"
@implementation CCNode (AnchorLayout)
#pragma mark - private methods
- ( CGFloat) edgeOfParentNode: ( CCNode*)node ofAnchor: ( CCNodeAnchorT)anchor
{
CGSize size = [node contentSize];
switch (anchor)
{
casekCCNodeAnchorTop :
return size. height * node. scaleY;
casekCCNodeAnchorLeft :
return 0.0;
casekCCNodeAnchorBottom :
return 0.0;
casekCCNodeAnchorRight :
return size. width * node. scaleX;
casekCCNodeAnchorHorizontalCenter :
return size. width * node. scaleX / 2;
casekCCNodeAnchorVerticalCenter :
return size. height * node. scaleY / 2;
default:
return 0.0;
}
}
- ( CGFloat) edgeOfSiblingNode: ( CCNode*)node ofAnchor: ( CCNodeAnchorT)anchor
{
CGPoint nodePosition = [node position];
CGPoint nodeCenter = CGPointMake(nodePosition. x + ( 0.5-node. anchorPoint. x) * node. contentSize. width * node. scaleX, nodePosition. y+ ( 0.5-node. anchorPoint. y) * node. contentSize. height * node. scaleY);
switch (anchor)
{
casekCCNodeAnchorTop :
return nodeCenter. y + 0.5 * node. contentSize. height * node. scaleY;
casekCCNodeAnchorLeft :
return nodeCenter. x - 0.5 * node. contentSize. width * node. scaleX;
casekCCNodeAnchorBottom :
return nodeCenter. y - 0.5 * node. contentSize. height * node. scaleY;
casekCCNodeAnchorRight :
return nodeCenter. x + 0.5 * node. contentSize. width * node. scaleX;
casekCCNodeAnchorHorizontalCenter :
return nodeCenter. x;
casekCCNodeAnchorVerticalCenter :
return nodeCenter. y;
default:
break;
}
return 0.0;
}
#pragma mark - public methods
- ( void) addAnchor:( CCNodeAnchorT)selfEdge referTo:( CCNode *)referNode edge:( CCNodeAnchorT)edge margin:( CGFloat)margin
{
CGPoint oldPositon = [ self position];
CGFloat centerX = 0.0;
CGFloat centerY = 0.0;
CGFloat selfWidth = self. contentSize. width * self. scaleX;
CGFloat selfHeight = self. contentSize. height * self. scaleY;
if ( self. parent == referNode)
{
//parent-child relationship
switch (selfEdge)
{
casekCCNodeAnchorTop :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge] - margin - selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorLeft :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge] + margin + selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorBottom :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge] + margin + selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorRight :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge] - margin - selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorHorizontalCenter :
centerX = [ self edgeOfParentNode: referNode ofAnchor: edge];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorVerticalCenter :
centerY = [ self edgeOfParentNode: referNode ofAnchor: edge];
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorCenterIn :
centerX = [ selfedgeOfParentNode : referNode ofAnchor :kCCNodeAnchorHorizontalCenter ];
centerY = [ selfedgeOfParentNode : referNode ofAnchor :kCCNodeAnchorVerticalCenter ];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
default:
break;
}
}
else if ( self. parent == referNode. parent)
{
//two nodes are siblings
switch (selfEdge)
{
casekCCNodeAnchorTop :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorLeft :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorBottom :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfHeight / 2;
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorRight :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfWidth / 2;
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorHorizontalCenter :
centerX = [ self edgeOfSiblingNode: referNode ofAnchor: edge];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, oldPositon. y);
break;
casekCCNodeAnchorVerticalCenter :
centerY = [ self edgeOfSiblingNode: referNode ofAnchor: edge];
self. position = CGPointMake(oldPositon. x, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
casekCCNodeAnchorCenterIn :
centerX = [ selfedgeOfSiblingNode : referNode ofAnchor :kCCNodeAnchorHorizontalCenter ];
centerY = [ selfedgeOfSiblingNode : referNode ofAnchor :kCCNodeAnchorVerticalCenter ];
self. position = CGPointMake(centerX + ( self. anchorPoint. x - 0.5) * selfWidth, centerY + ( self. anchorPoint. y - 0.5) * selfHeight);
break;
default:
break;
}
}
else
{
//not allowed
NSAssert ( NO , @"The two nodes must be parent-child or siblings!" );
}
}
- ( void) centerIn:( CCNode *)outerNode
{
[ selfaddAnchor : kCCNodeAnchorCenterInreferTo : outerNode edge :kCCNodeAnchorCenterIn margin : 0 ];
}
@end
1630

被折叠的 条评论
为什么被折叠?



