CCNode 布局扩展


给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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值