CCNode 布局扩展
2012-12-18 14:20
239 查看
给CCNode做了扩展,方便界面布局
让技术开发讨论更纯粹!CocoaChina问答荣誉每周、每月龙虎榜!在第一次用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"
typedefenum
{
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 = [selfposition];
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 = [selfedgeOfParentNode: referNode ofAnchor: edge] - margin - selfHeight
/ 2;
self.position =CGPointMake(oldPositon.x,
centerY + (self.anchorPoint.y -0.5)
* selfHeight);
break;
casekCCNodeAnchorLeft:
centerX = [selfedgeOfParentNode: referNode ofAnchor: edge] + margin + selfWidth
/ 2;
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorBottom:
centerY = [selfedgeOfParentNode: referNode ofAnchor: edge] + margin + selfHeight
/ 2;
self.position =CGPointMake(oldPositon.x,
centerY + (self.anchorPoint.y -0.5)
* selfHeight);
break;
casekCCNodeAnchorRight:
centerX = [selfedgeOfParentNode: referNode ofAnchor: edge] - margin - selfWidth
/ 2;
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorHorizontalCenter:
centerX = [selfedgeOfParentNode: referNode ofAnchor: edge];
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorVerticalCenter:
centerY = [selfedgeOfParentNode: 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 = [selfedgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfHeight
/ 2;
self.position =CGPointMake(oldPositon.x,
centerY + (self.anchorPoint.y -0.5)
* selfHeight);
break;
casekCCNodeAnchorLeft:
centerX = [selfedgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfWidth
/ 2;
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorBottom:
centerY = [selfedgeOfSiblingNode: referNode ofAnchor: edge] + margin + selfHeight
/ 2;
self.position =CGPointMake(oldPositon.x,
centerY + (self.anchorPoint.y -0.5)
* selfHeight);
break;
casekCCNodeAnchorRight:
centerX = [selfedgeOfSiblingNode: referNode ofAnchor: edge] - margin - selfWidth
/ 2;
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorHorizontalCenter:
centerX = [selfedgeOfSiblingNode: referNode ofAnchor: edge];
self.position =CGPointMake(centerX + (self.anchorPoint.x -0.5)
* selfWidth, oldPositon.y);
break;
casekCCNodeAnchorVerticalCenter:
centerY = [selfedgeOfSiblingNode: 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:kCCNodeAnchorCenterInmargin:0];
}
@end
相关文章推荐
- android百分比库扩展,支持布局宽高比及子控件宽高比设置,支持布局圆角、圆形及描边,屏幕适配好帮手
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展
- iOS:UICollectionView流式布局及其在该布局上的扩展的线式布局
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android ListView功能扩展,实现高性能的瀑布流布局
- [网摘]Div+CSS布局的扩展技巧和用法24则
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展
- iOS 自动布局扩展应用:代码中动态调整布局常量
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android ListView 功能扩展,实现高性能的瀑布流布局
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Android 百分比布局库(percent-support-lib) 解析与扩展