顯示具有 cocos2D 標籤的文章。 顯示所有文章
顯示具有 cocos2D 標籤的文章。 顯示所有文章

2014年5月3日 星期六

CCAction資料


轉帖自http://www.apkbus.com/android-797-1.html


CCAction是游戏的一个和重要组成部分,游戏之所以区别于应用就是因为形象鲜明,趣味性交互性强,如果游戏元素没有动作,那就很无聊了;
        之前我们已经介绍过,CCNode节点中有一个(void)runAction:(CCAction *)action 方法,所以,所有继承自CCNode的类,比如精灵,层,甚至菜单都可以执行动作;
        CCAction有很庞大的层次关系,如图所示

        其中主要的为CCAction-->CCFiniteTimeAction
        其中CCFiniteTimeAction下的两个子类CCActionInstant和CCActionInterval分别为瞬时动作和延时动作;
瞬时动作更接近于节点属性的设置,有的时候是为了更方便地组成动作序列,延时动作则是我们经常看到的一些动画画面;
        动作的返回值类型为id,所以,你会经常看到这种写法
        CCMoveTo *move = [CCMoveTo actionWithDuration:3 position:CGPointMake(100,200)];
        [sprite runAction :move];
        瞬时动作我们会在介绍动作序列时再作详细说明,下面归纳一下延时动作,常用的延时动作有
CCMoveTo 
        移动到参数position位置
        示例:CCMoveTo *move = [CCMoveTo actionWithDuration:3 position:CGPointMake(100,200)];//该动作移动到position参数位置;

CCMoveBy
        精灵移动参数个位置
        示例:[sprite runAction:[CCMoveBy actionWithDuration:3 position:pos]];//该动作使节点移动pos个位置;

CCFadeTo
        节点色调透明度变化
        示例: [sprite runAction:[CCFadeTo actionWithDuration:3 opacity:opa]]; //节点透明度渐变为opa(0~255);

CCFadeIn
        节点亮度从0渐变为最高
        示例: [sprite runAction:[CCFadeIn actionWithDuration:3 ]; //节点在3秒内从黑暗变为最亮;

CCFadeOut
        同上相反;

CCBlink
        节点闪烁,需设置闪烁次数;
        示例:[sprite runAction:[CCBlink actionWithDuration:3 blinks:t]]; //节点在3秒内闪烁t次;如果持续时间变长,闪烁频率会自动调低;

CCRotateTo
        节点旋转,需设置旋转角度
        示例:[sprite runAction:[CCRotateTo actionWithDuration:3 angle:180]]; //节点在3秒内旋转180度;

CCRotateBy
        节点旋转,经试验没发现与CCRotateTo有何区别;
        示例:[sprite runAction:[CCRotateBy actionWithDuration:3 angle:180]];      //效果同上一样;

CCScaleTo
        节点放大,有两个方法
        示例:[sprite runAction:[CCScaleTo actionWithDuration:3 scale :2]];//节点在3秒内放大到原来的2倍;
 [sprite runAction:[CCScaleTo actionWithDuration:3 scaleX:2 scaleY:3]];//节点在3秒内横方向放大到原来的2倍,纵方向放大到原来的3倍;

CCScaleBy 
        节点放大,经试验没发现与上述效果有何区别(大家发现后告诉我);

CCTintTo
        节点调色
        示例:[sprite runAction:[CCTintTo actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内着色为RGB颜色如参数所示

CCTintBy
        节点渐变
        示例:[sprite runAction:[CCTintBy actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内以RGB参数逐渐加深;

CCSkewTo
        节点斜率变化
        示例:[sprite runAction:[CCSkewTo actionWithDuration:3 skewX:30 skewY:5]];//将一个节点按横坐标30,纵坐标5的大小倾斜;该参数效果见图


CCSkewBy
        效果同上一样;

CCBezierTo
        使节点按贝塞尔曲线移动,需先生成一个贝塞尔参数,见示例
        示例:
ccBezierConfig bezier;//创建贝塞尔曲线
        bezier.controlPoint_1 =ccp(sprite.position.x, sprite.position.y);//起始点
        bezier.controlPoint_2 =ccp(sprite.position.x+5,sprite.position.y+20);//控制点
        bezier.endPosition =ccp(sprite.position.x+50, sprite.position.y+100);//结束位置
        [sprite runAction:[CCBezierToactionWithDuration:3bezier:bezier]];
关于贝塞尔曲线,主要作用是通过点确定准确的曲线图形,建议大家百度一下点击打开链接

CCBezierBy
        每次移动贝塞尔曲线个距离;用法同上;

        通过上面这些主流的动作行为,我们可以实现一些很有视觉冲击力的动画效果,常用到的常常有放大(远近景拉伸),旋转,跳越等;
        cocos2d中的动作远比上面这些要灵活的多,下回就介绍一下动作的一些修饰,动作序列,和动作序列中怎样加入一些回调方法;

cocos2d 顏色設定



[mysprite setColor:ccc3(R,G,B)] // R,G,B -> 分別為0~255

[mysprite setOpacity:value]; // value 范围0-255,    0完全透明,255完全不透明。

其它可參考基本設定 http://kirenenko-tw.blogspot.tw/2013/11/ccsprite.html

至於CCSprite的饱和度、色相、亮度等属性可參考
http://blog.csdn.net/ldz15838245189/article/details/9365499


另外也可以利用CCAction來做顏色的調控

CCFadeTo
        节点色调透明度变化
        示例: [sprite runAction:[CCFadeTo actionWithDuration:3 opacity:opa]]; //节点透明度渐变为opa(0~255);

CCFadeIn
        节点亮度从0渐变为最高
        示例: [sprite runAction:[CCFadeIn actionWithDuration:3 ]; //节点在3秒内从黑暗变为最亮;

CCFadeOut
        同上相反;

CCBlink
        节点闪烁,需设置闪烁次数;
        示例:[sprite runAction:[CCBlink actionWithDuration:3 blinks:t]]; //节点在3秒内闪烁t次;如果持续时间变长,闪烁频率会自动调低;

CCTintTo
        节点调色
        示例:[sprite runAction:[CCTintTo actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内着色为RGB颜色如参数所示

CCTintBy
        节点渐变
        示例:[sprite runAction:[CCTintBy actionWithDuration:3 red:110 green:110 blue:110]]; //节点在三秒内以RGB参数逐渐加深;






2014年3月28日 星期五

CCSpriteBatchNode使用之注意事項

1. 改變zorder時必須要用
     
[myBatchNode reorderChild:mySprite z:indexOfAnArray];
 
不可使用  [mySprite setZOrder:indexOfAnArray];
 
其中 indexOfAnArray 就用z-order的數值來設定

2014年3月24日 星期一

cocos2d 中添加显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)(轉貼)

cocos2d 中添加显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)

官方說明

   
最近在逛论坛的时候看到有的帖子说显示文本时用 CCLabelTTF 不是很好,且推荐游戏中最好别用。于是网上查了查相关资料,整理了下 ,顺便也分享下
     在 cocos2d 中有三个类可以在层或精灵中添加文字:
  • CCLabelTTF
  • CCLabelBMFont
  • CCLabelAtlas

     CCLabelTTF
           CCLabelTTF 每次调用 setString (即改变文字)的时候,一个新的OPENGL 纹理将会被创建.。这意味着setString 和创建一个新的标签一样慢。
           所以,当你需要频繁的更新它们的时候,尽可能的不用去使用标签对象。  而应该使用CCLabelAtlas或者是CCLabelBMFont。
           OK, 看下它的使用方法
           CCLabelTTF *label = [CCLabelTTF labelWithString:@"the string"  fontName:@"Marker Felt"  fontSize:21];
           [layer addChild:label];
           label.position = ccp(100,100);
           [label setString:@“change string”]; //修改文字的方法

           这个类使用的是系统中的字体,不需要额外往项目文件中添加字体文件。但如果你有自定义的字体也可以加到项目中,如果无法使用,可以查看一下ccConfig.h中的CC_FONT_LABEL_SUPPORT是否enable了。


     CCLabelBMFont
        CCLabelBMFont  相当于每次改变只改变了图片坐标,而CCLabelTTF要重新渲染.这个类使用之前,需要添加好字体文件,包括一个图片文件 (**.png) 和一个 字体坐标文件 (**.fnt)。
         在 cocos2d的示例项目中有现成的,可以先拿过来练习一下,找的时候注意两个文件的 名称是相同的,只是扩展名不同。
         CCLabelBMFont *label =[CCLabelBMFont labelWithString:@"the string"   fntFile:@"konqa32-hd.fnt"];
           [layer addChild:label];
           label.position = ccp(100,100);
           [label setString:@“change string”];
        fntFile是文件名,写扩展名是 .fnt的那个。下面是 .fnt文件的截图
       
        可以看到 .fnt 文件定义了 图像文件的名称,以及每个字符对应的位置信息。
        这个没办法指定字体的字号,但可以用  scale  属性进行缩放来调整大小。就当它是sprite。



   CCLabelAtlas        
        如果你用cocos2d项目模板创建过项目,那么你已经看过它的效果了,就是左下角显示帧率的数字。
        因为帧率一直在变,使用CCLabelTTF的话效率太低,因为只是数字所以也犯不上使用 CCLabelBMFont 加载那么大的文字图像,所以使用这个比较合适。
        CCLabelAtlas *label = [CCLabelAtlas labelWithString:@"12" charMapFile:@"fps_images.png" itemWidth:12 itemHeight:18 startCharMap:'.'];
          [layer addChild:label];
          label.position = ccp(100,100);
          [label setString:@“34”];

       在项目文件中,在resourse group里你可以找一下一个叫 fps_images.png的这个图像文件,文件如下:
       
       所以,这个只能显示上面这个12个字符,abcd什么的就不行了。
       解释一下参数,
       labelWithString就是字符,
       charMapFile 就是字符的图像文件(这个只要图像文件就可以了),
       itemWidth是每个字符的宽度,
       itemHeight是每个字符的高度,这个不能设错,否则显示的时候可能就不对了。
       最后一个是起始字符,它是使用这个其实字符来对应字符和图像关系的。
 

2014年2月14日 星期五

cocos2d 2.0 single touch的基本用法(轉貼)

http://zackworkshopios.blogspot.tw/2012/06/cocos2d-20-single-touch-detection-for.html

需要時方便參考用

In order to detect single touch for CCSprite in Cocos2d 2.0, you must implement CCTargetedTouchDelegate.

Implement CCTargetedTouchDelegate

@interface mySprite : CCSprite <CCTargetedTouchDelegate>

Add Target Delegation

[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

此處 prriority:0 對應此CCLayer的優先權,在所有的layer中此layer的優先權,越高的越優先,也可以是負值,例如CCMenu就是-128,因此不會與其他layer搶先,所以不易出錯。自己所定的layer就可以高一點,如設定1就會比0高,而搶到觸控權。

swallowsTouches是說是否要獨佔此觸控權,一般來說,只有第一層設成YES,其他層最好設成NO,因為其他層CCLayer在釋放記憶體時,不會將觸控權放出,會引致程式掛掉,因此設定時要小心。要安全是釋放可參考下方

Remove Delegation

[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];

-(void)onExit {  // 離開前要呼叫此function,來做正確的釋放touch控制權
    [[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
    [super onExit];
}

Detect Touched or Not

CGPoint touchPoint = [touch locationInView:[touch view]];
touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
CGRect rect = [self boundingBox];
if (CGRectContainsPoint(rect, touchPoint)) {
    return YES;

return NO;

sample code for mySprite.h

#import "cocos2d.h"


@interface mySprite : CCSprite <CCTargetedTouchDelegate>
@end

sample code for mySprite.c


#import "mySprite.h"

@implementation mySprite
-(void)onEnter {
    [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    [super onEnter];
}

-(void)onExit {
    [[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
    [super onExit];
}

-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    BOOL isTouched = [self touched:touch];
    if (isTouched) {
        [self stopAllActions];
        id enlarge = [CCScaleTo actionWithDuration:0.5f scale:1.1f];
        id resize = [CCScaleTo actionWithDuration:0.5f scale:1];
        [self runAction:[CCSequence actions:enlarge, resize, nil]];
    }
    return isTouched;
}

-(BOOL)touched:(UITouch *)touch {
    CGPoint touchPoint = [touch locationInView:[touch view]];
    touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
    CGRect rect = [self boundingBox];
    if (CGRectContainsPoint(rect, touchPoint)) {
        return YES;
    } 
    return NO;
}
@end

2014年2月3日 星期一

CCSpriteBatchNode 的基本method

來自http://blog.csdn.net/honghaier/article/details/7931914
只截取部分內容,方便使用時的參考資訊

class CC_DLL CCSpriteBatchNode : public CCNode, public CCTextureProtocol
 {
 public:
  //析构
  ~CCSpriteBatchNode();
 
  // 取得纹理图块顶点缓冲管理器。
  inline CCTextureAtlas* getTextureAtlas(void) { return m_pobTextureAtlas; }
  //设置纹理图块顶点缓冲管理器
  inline void setTextureAtlas(CCTextureAtlas* textureAtlas) 
  { 
   //如果当前使用的纹理图块顶点缓冲管理器与要设置的纹理图块顶点缓冲管理器不同,先释放原顶点缓冲管理器,再将当前使用的顶点缓冲管理器指针指向要设置顶点缓冲管理器。
   if (textureAtlas != m_pobTextureAtlas)
   {
    CC_SAFE_RETAIN(textureAtlas);
    CC_SAFE_RELEASE(m_pobTextureAtlas);
    m_pobTextureAtlas = textureAtlas;
   }
  }
  //取得存放所有使用此图块集的CCSprite指针数组
  inline CCArray* getDescendants(void) { return m_pobDescendants; }

  //静态函数:通过纹理指针按照默认的图块数量29创建一个CCSpriteBatch实例对象。注意:如果游戏运行中图块数量超过这个数值,则数量递增33%以满足需要

  static CCSpriteBatchNode* batchNodeWithTexture(CCTexture2D *tex);

  //静态函数:通过纹理指针按照设定的图块数量创建一个CCSpriteBatch实例对象。 
  static CCSpriteBatchNode* batchNodeWithTexture(CCTexture2D* tex, unsigned int capacity);

  //静态函数:通过图片名称按照默认的图块数量29创建一个CCSpriteBatch实例对象。
  static CCSpriteBatchNode* batchNodeWithFile(const char* fileImage);

  //静态函数:通过图片名称按照设定的图块数量创建一个CCSpriteBatch实例对象。 
  static CCSpriteBatchNode* batchNodeWithFile(const char* fileImage, unsigned int capacity);

  //通过纹理指针和图块数量进行初始化。
  bool initWithTexture(CCTexture2D *tex, unsigned int capacity);
  //通过图片名称和图块数量进行初始化。
  bool initWithFile(const char* fileImage, unsigned int capacity);
  
  //扩容,递增1/3的图块数量
  void increaseAtlasCapacity();

  //通过索引移除一个子结点,参数doCleanUp决定移除的同时是否对其进行释放。
  void removeChildAtIndex(unsigned int index, bool doCleanup);
  //将一个指定的CCSprite指针插入到子节点指针数组的指定位置
  void insertChild(CCSprite *child, unsigned int index);
  //移除一个指定的CCSprite指针
  void removeSpriteFromAtlas(CCSprite *sprite);
  //重新构建指定的CCSprite指针下的所有子结点的索引
  unsigned int rebuildIndexInOrder(CCSprite *parent, unsigned int index);
  //取得指定CCSprite的所有节点的最大图块索引
  unsigned int highestAtlasIndexInChild(CCSprite *sprite);
  //取得指定CCSprite的所有节点的最小图块索引
  unsigned int lowestAtlasIndexInChild(CCSprite *sprite);
  //取得指定CCSprite的Z顺序之上或之下的最近的图块索引
  unsigned int atlasIndexForChild(CCSprite *sprite, int z);
  
  // 实现CCTextureProtocol的接口函数
  // 取得纹理
     virtual CCTexture2D* getTexture(void);
  // 设置纹理
     virtual void setTexture(CCTexture2D *texture);
  //为纹理设置使用的混合状态
     virtual void setBlendFunc(ccBlendFunc blendFunc);
  //取得混合状态
     virtual ccBlendFunc getBlendFunc(void);

  //重载CCNode的相关函数
  //每一帧要被调用的函数
     virtual void visit(void);
  //将一个CCNode指针做为自已的子结点
     virtual void addChild(CCNode * child);
  //将一个CCNode指针以指定的Z顺序做为自已的子结点
     virtual void addChild(CCNode * child, int zOrder);
  //将一个CCNode指针以指定的Z顺序并附带一个参数值做为自已的子结点
     virtual void addChild(CCNode * child, int zOrder, int tag);
  //将一个子结点重新设置Z顺序
     virtual void reorderChild(CCNode * child, int zOrder);
     //将一个子结点删除,并根所参数决定是否释放元素
     virtual void removeChild(CCNode* child, bool cleanup);
  //将所有的子结点移除,并根所参数决定是否释放元素
     virtual void removeAllChildrenWithCleanup(bool cleanup);
  //绘制函数
     virtual void draw(void);

    protected:
        
        //从精灵数据中在图块管理器中插入一个新的图块,注意:并不将精灵放入子结点。  void addQuadFromSprite(CCSprite *sprite, unsigned int index);
  //在子结点数组指定位置插入一个新的精灵。注意:并不新建图块。
        CCSpriteBatchNode * addSpriteWithoutQuad(CCSprite*child, unsigned int z, int aTag);

 private:
  //更新混合状态
  void updateBlendFunc();

 protected:
  //使用的纹理图块顶点缓冲管理器
  CCTextureAtlas *m_pobTextureAtlas;
  //混合状态
  ccBlendFunc m_blendFunc;
  //指向存放所有使用此纹理中的图块的CCSprite指针数组的指针
  CCArray* m_pobDescendants;
 };

2014年1月13日 星期一

Cocos2d-音乐播放(轉貼)

原址 http://www.cnblogs.com/moon-7/archive/2012/04/23/2467145.html

//预加载背景音乐 和 预加载音效  在播放背景音乐与音效之前都要提前加载,
为了防止加载消耗时间发生与游戏不同步;
[[SimpleAudioEngine sharedEngine] preloadBackgroundMusic:@"office_background.mp3"]; 
[[SimpleAudioEngine sharedEngine] preloadEffect:@"office_background.mp3"];
        
//播放背景音乐 和 循环播放背景音乐;
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"office_background.mp3"];
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"school_kissing.mp3" loop:YES];
        
//暂停播放背景音乐;
[[SimpleAudioEngine sharedEngine] pauseBackgroundMusic];
//继续播放背景音乐(不是从头开始播)
[[SimpleAudioEngine sharedEngine] resumeBackgroundMusic];
//停止播放背景音乐
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
//设置背景音乐音量大小;
[CDAudioManager sharedManager].backgroundMusic.volume=1.0;  //(volume值范围为0.0-1.0);
//背景音乐播放几次:
[CDAudioManager sharedManager].backgroundMusic.numberOfLoops= int值;
//背景音乐播放完后:
[[CDAudioManager sharedManager] 
setBackgroundMusicCompletionListener:self selector:@selector(触发的方法)];
 
//播放音效;
[[SimpleAudioEngine sharedEngine] playEffect:@"school_kissing.mp3"];
        
//pitch(值范围:>0){值最大,音调越高,播放时间越短} 
pan:(值范围:-1到1)貌似是左右声道 
gain:(值范围:>0)音量大小;
[[SimpleAudioEngine sharedEngine] playEffect:@"office_background.mp3" 
pitch:3.0 pan:-1 gain:0.1];
 

有时我们需要循环播放一个音效;
可以做如下操作:
在 #import "SimpleAudioEngine.h" 源码中:
-(ALuint) playEffect:(NSString*) filePath loop:(BOOL)loop;

-(ALuint) playEffect:(NSString*) filePath pitch:(Float32) 
pitch pan:(Float32) pan gain:(Float32) gain loop:(BOOL)loop;

 #import "SimpleAudioEngine.m"源码中 实现方法:
-(ALuint) playEffect:(NSString*) filePath loop:(BOOL)loop
{
    return [self playEffect:filePath pitch:1.0f pan:0.0f gain:1.0f loop:loop];
}

-(ALuint) playEffect:(NSString*) filePath pitch:(Float32) 
pitch pan:(Float32) pan gain:(Float32) gain loop:(BOOL)loop
{
    int soundId = [bufferManager bufferForFile:filePath create:YES];
    if (soundId != kCDNoBuffer) {
        return [soundEngine playSound:soundId sourceGroupId:0 
pitch:pitch pan:pan gain:gain loop:loop];
    } else {
        return CD_MUTE;
    }    
}
这样我们就可以用如下方法实现音效循环播放:
//loop循环播放音效;
[[SimpleAudioEngine sharedEngine] playEffect:@"school_kissing.mp3" loop:YES];
[[SimpleAudioEngine sharedEngine] playEffect:@"school_kissing.mp3" 
pitch:1.0 pan:0.0 gain:1.0 loop:YES];

停止播放音效:设一个全局的静态变量:
static int i=1;(随便赋个值)
在播放音效时候  i=[[SimpleAudioEngine sharedEngine] 
playEffect:@"school_kissing.mp3" loop:YES]; 
 
停止播放音效:   [[SimpleAudioEngine sharedEngine] stopEffect:i];

需要注意的是:如有多个音效播放,索引值不能是同一个, 因为每次播放都会返回一个int值如:
i=[[SimpleAudioEngine sharedEngine] playEffect:@"abc.mp3" loop:YES];
i=[[SimpleAudioEngine sharedEngine] playEffect:@"def.mp3" loop:YES]; 
[[SimpleAudioEnginesharedEnginestopEffect:i]; 
//播放abc可能返回值为100,播放def返回为101,
这样通过同一个索引“i”就不能停止abc的播放了;
你会发现,还在循环播放;必须使用不同的“索引”才行;
 
 

2013年11月28日 星期四

在cocos2d里面如何拖拽精灵

參考網頁 http://www.raywenderlich.com/zh-hans/21318/%E5%9C%A8cocos2d%E9%87%8C%E9%9D%A2%E5%A6%82%E4%BD%95%E6%8B%96%E6%8B%BD%E7%B2%BE%E7%81%B5

以網頁上的說明來測試,由於網頁上的參考例子不是在ios7/xcode5.0上做的,因此無法直接執行,因此就手動修改來測試一下,並將過程記錄一下。

1. 先啟動一個專案,要使用cocos2d_IOS的Template




2. 將Target設定為7.0,這是因為cocos2d V2.1內定為4.0,並且可以把HelloWorld及Intro這兩組檔案刪除,因為我們會重寫兩個新檔案來取代。



3. 開啟一個新的.h檔,設為GameConfig.h,以下是檔案內容


//
// Supported Autorotations:
//        None,
//        UIViewController,
//        CCDirector
//
#define kGameAutorotationNone 0
#define kGameAutorotationCCDirector 1
#define kGameAutorotationUIViewController 2

//
// Define here the type of autorotation that you want for your game
//
#define GAME_AUTOROTATION kGameAutorotationUIViewController

// 設定用來切換是否使用Gesture元件,原始內容沒有
#define USE_Gesture  1



 4.加一組新的HelloWorldScene的檔案,並將下面內容加入。







HelloWorldScene.h

#import "cocos2d.h"

// HelloWorld Layer
@interface HelloWorld : CCLayer
{
    CCSprite * background;
    CCSprite * selSprite;
    NSMutableArray * movableSprites;
}

// returns a Scene that contains the HelloWorld as the only child
+(id) scene;

@end


HelloWorldScene.m

#import "HelloWorldScene.h"

// HelloWorld implementation
@implementation HelloWorld

+(id) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];
   
    // 'layer' is an autorelease object.
    HelloWorld *layer = [HelloWorld node];
   
    // add layer as a child to scene
    [scene addChild: layer];
   
    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
-(id) init {
    if((self = [super init])) {       
        CGSize winSize = [CCDirector sharedDirector].winSize;
       
        [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565];
        background = [CCSprite spriteWithFile:@"blue-shooting-stars.png"];
        background.anchorPoint = ccp(0,0);
        background.scale = 2.0; // 原圖太小了,放大
        [self addChild:background];
        [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_Default];
       
        movableSprites = [[NSMutableArray alloc] init];
        NSArray *images = [NSArray arrayWithObjects:@"bird.png", @"cat.png", @"dog.png", @"turtle.png", nil];      
        for(int i = 0; i < images.count; ++i) {
            NSString *image = [images objectAtIndex:i];
            CCSprite *sprite = [CCSprite spriteWithFile:image];
            float offsetFraction = ((float)(i+1))/(images.count+1);
            sprite.position = ccp(winSize.width*offsetFraction, winSize.height/2);
            sprite.scale = 2.0;
            [self addChild:sprite];
            [movableSprites addObject:sprite];
        }

#ifndef  USE_Gesture
        [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
#endif
    }
    return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    [movableSprites release];
    movableSprites = nil;
    [super dealloc];
}

- (void)selectSpriteForTouch:(CGPoint)touchLocation {
    CCSprite * newSprite = nil;
    for (CCSprite *sprite in movableSprites) {
        if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {           
            newSprite = sprite;
            break;
        }
    }   
    if (newSprite != selSprite) {
        [selSprite stopAllActions];
        [selSprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]];
        CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-4.0];
        CCRotateTo * rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0];
        CCRotateTo * rotRight = [CCRotateBy actionWithDuration:0.1 angle:4.0];
        CCSequence * rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil];
        [newSprite runAction:[CCRepeatForever actionWithAction:rotSeq]]; // 擺動
        selSprite = newSprite;
    }
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {   
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
    [self selectSpriteForTouch:touchLocation];     
    return TRUE;   
}

- (CGPoint)boundLayerPos:(CGPoint)newPos {
    CGSize winSize = [CCDirector sharedDirector].winSize;
    CGPoint retval = newPos;
    retval.x = MIN(retval.x, 0);
    retval.x = MAX(retval.x, -background.contentSize.width+winSize.width);
    retval.y = self.position.y;
    return retval;
}

- (void)panForTranslation:(CGPoint)translation {   
    if (selSprite) {
        CGPoint newPos = ccpAdd(selSprite.position, translation);
        selSprite.position = newPos;
    } else {
        CGPoint newPos = ccpAdd(self.position, translation);
        self.position = [self boundLayerPos:newPos];     
    } 
}

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {      
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
   
    CGPoint oldTouchLocation = [touch previousLocationInView:touch.view];
    oldTouchLocation = [[CCDirector sharedDirector] convertToGL:oldTouchLocation];
    oldTouchLocation = [self convertToNodeSpace:oldTouchLocation];
   
    CGPoint translation = ccpSub(touchLocation, oldTouchLocation);   
    [self panForTranslation:translation];   
}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
   
    if (recognizer.state == UIGestureRecognizerStateBegan) {   
       
        CGPoint touchLocation = [recognizer locationInView:recognizer.view];
        touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
        touchLocation = [self convertToNodeSpace:touchLocation];               
        [self selectSpriteForTouch:touchLocation];
       
    } else if (recognizer.state == UIGestureRecognizerStateChanged) {   
       
        CGPoint translation = [recognizer translationInView:recognizer.view];
        translation = ccp(translation.x, -translation.y);
        [self panForTranslation:translation];
        [recognizer setTranslation:CGPointZero inView:recognizer.view];   
       
    } else if (recognizer.state == UIGestureRecognizerStateEnded) {
       
        if (!selSprite) {        
            float scrollDuration = 0.2;
            CGPoint velocity = [recognizer velocityInView:recognizer.view];
            CGPoint newPos = ccpAdd(self.position, ccpMult(velocity, scrollDuration));
            newPos = [self boundLayerPos:newPos];
            [self stopAllActions];
            CCMoveTo *moveTo = [CCMoveTo actionWithDuration:scrollDuration position:newPos];           
            [self runAction:[CCEaseOut actionWithAction:moveTo rate:1]];           
        }       
       
    }       
}

@end


5. 修改AppDelegate.h


#import <UIKit/UIKit.h>
#import "cocos2d.h"

// Added only for iOS 6 support
@interface MyNavigationController : UINavigationController <CCDirectorDelegate>
@end

@interface AppController : NSObject <UIApplicationDelegate>
{
    UIWindow *window_;
    MyNavigationController *navController_;

    CCDirectorIOS    *director_;                            // weak ref
  
    CCScene *winScene;
}

@property (nonatomic, retain) UIWindow *window;
@property (readonly) MyNavigationController *navController;
@property (readonly) CCDirectorIOS *director;
@property (nonatomic, assign)  CCScene  *winScene;

@end


6. 修改AppDelegate.m

#import "cocos2d.h"

#import "AppDelegate.h"
//#import "IntroLayer.h"

#import "HelloWorldScene.h"
#import "GameConfig.h"


@implementation MyNavigationController

// The available orientations should be defined in the Info.plist file.
// And in iOS 6+ only, you can override it in the Root View controller in the "supportedInterfaceOrientations" method.
// Only valid for iOS 6+. NOT VALID for iOS 4 / 5.
-(NSUInteger)supportedInterfaceOrientations {
   
    // iPhone only
    if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )
        return UIInterfaceOrientationMaskLandscape;
   
    // iPad only
    return UIInterfaceOrientationMaskLandscape;
}

// Supported orientations. Customize it for your own needs
// Only valid on iOS 4 / 5. NOT VALID for iOS 6.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // iPhone only
    if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )
        return UIInterfaceOrientationIsLandscape(interfaceOrientation);
   
    // iPad only
    // iPhone only
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

// This is needed for iOS4 and iOS5 in order to ensure
// that the 1st scene has the correct dimensions
// This is not needed on iOS6 and could be added to the application:didFinish...
-(void) directorDidReshapeProjection:(CCDirector*)director
{
    if(director.runningScene == nil) {
        // Add the first scene to the stack. The director will draw it immediately into the framebuffer. (Animation is started automatically when the view is displayed.)
        // and add the scene to the stack. The director will run it when it automatically when the view is displayed.
        //[director runWithScene: [IntroLayer scene]];
       
        // Run the intro Scene
        CCScene *scene = [HelloWorldScene scene];
       
#ifdef USE_Gesture
       
        HelloWorldScene *layer = (HelloWorldScene *) [scene.children objectAtIndex:0];
       
        UIPanGestureRecognizer *gestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:layer action:@selector(handlePanFrom:)] autorelease];
        //[viewController.view addGestureRecognizer:gestureRecognizer];
        [self.view addGestureRecognizer:gestureRecognizer];
       
#endif
       
        [[CCDirector sharedDirector] runWithScene:scene];

    }
}
@end


@implementation AppController

@synthesize window=window_, navController=navController_, director=director_;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Create the main window
    window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
   
   
    // CCGLView creation
    // viewWithFrame: size of the OpenGL view. For full screen use [_window bounds]
    //  - Possible values: any CGRect
    // pixelFormat: Format of the render buffer. Use RGBA8 for better color precision (eg: gradients). But it takes more memory and it is slower
    //    - Possible values: kEAGLColorFormatRGBA8, kEAGLColorFormatRGB565
    // depthFormat: Use stencil if you plan to use CCClippingNode. Use Depth if you plan to use 3D effects, like CCCamera or CCNode#vertexZ
    //  - Possible values: 0, GL_DEPTH_COMPONENT24_OES, GL_DEPTH24_STENCIL8_OES
    // sharegroup: OpenGL sharegroup. Useful if you want to share the same OpenGL context between different threads
    //  - Possible values: nil, or any valid EAGLSharegroup group
    // multiSampling: Whether or not to enable multisampling
    //  - Possible values: YES, NO
    // numberOfSamples: Only valid if multisampling is enabled
    //  - Possible values: 0 to glGetIntegerv(GL_MAX_SAMPLES_APPLE)
    CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds]
                                   pixelFormat:kEAGLColorFormatRGB565
                                   depthFormat:0
                            preserveBackbuffer:NO
                                    sharegroup:nil
                                 multiSampling:NO
                               numberOfSamples:0];
   
    director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
   
    director_.wantsFullScreenLayout = YES;
   
    // Display FSP and SPF
    [director_ setDisplayStats:YES];
   
    // set FPS at 60
    [director_ setAnimationInterval:1.0/60];
   
    // attach the openglView to the director
    [director_ setView:glView];
   
    // 2D projection
    [director_ setProjection:kCCDirectorProjection2D];
    //    [director setProjection:kCCDirectorProjection3D];
   
    // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
    if( ! [director_ enableRetinaDisplay:YES] )
        CCLOG(@"Retina Display Not supported");
   
    // Default texture format for PNG/BMP/TIFF/JPEG/GIF images
    // It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
    // You can change this setting at any time.
    [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
   
    // If the 1st suffix is not found and if fallback is enabled then fallback suffixes are going to searched. If none is found, it will try with the name without suffix.
    // On iPad HD  : "-ipadhd", "-ipad",  "-hd"
    // On iPad     : "-ipad", "-hd"
    // On iPhone HD: "-hd"
    CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
    [sharedFileUtils setEnableFallbackSuffixes:NO];                // Default: NO. No fallback suffixes are going to be used
    [sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];        // Default on iPhone RetinaDisplay is "-hd"
    [sharedFileUtils setiPadSuffix:@"-ipad"];                    // Default on iPad is "ipad"
    [sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];    // Default on iPad RetinaDisplay is "-ipadhd"
   
    // Assume that PVR images have premultiplied alpha
    [CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
   
    // Create a Navigation Controller with the Director
    navController_ = [[MyNavigationController alloc] initWithRootViewController:director_];
    navController_.navigationBarHidden = YES;

    // for rotation and other messages
    [director_ setDelegate:navController_];
   
    // set the Navigation Controller as the root view controller
    [window_ setRootViewController:navController_];
   
    // make main window visible
    [window_ makeKeyAndVisible];
   
    return YES;
}

// getting a call, pause the game
-(void) applicationWillResignActive:(UIApplication *)application
{
    if( [navController_ visibleViewController] == director_ )
        [director_ pause];
}

// call got rejected
-(void) applicationDidBecomeActive:(UIApplication *)application
{
    [[CCDirector sharedDirector] setNextDeltaTimeZero:YES];   
    if( [navController_ visibleViewController] == director_ )
        [director_ resume];
}

-(void) applicationDidEnterBackground:(UIApplication*)application
{
    if( [navController_ visibleViewController] == director_ )
        [director_ stopAnimation];
}

-(void) applicationWillEnterForeground:(UIApplication*)application
{
    if( [navController_ visibleViewController] == director_ )
        [director_ startAnimation];
}

// application will be killed
- (void)applicationWillTerminate:(UIApplication *)application
{
    CC_DIRECTOR_END();
}

// purge memory
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    [[CCDirector sharedDirector] purgeCachedData];
}

// next delta time will be zero
-(void) applicationSignificantTimeChange:(UIApplication *)application
{
    [[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
}

- (void) dealloc
{
    [window_ release];
    [navController_ release];
   
    [super dealloc];
}
@end


7. 將圖黨下載後,加入專案中,以下是檔案列表



 8. 完成以上程序後就可以執行了,在config中可以切換兩種不同的拖拽模式,一種是使用UIView的原件,一種是使用cocos2d的內部辨識模式。因為原圖形是在iphone3中執行,所以圖片都太小了。原始文件中,背景圖的拖拽,原本就有問題,因不需要使用,就不修改了。

因此將圖稍稍放大兩倍來用,執行結果如下。




2013年11月24日 星期日

cocos2d 2.1版改變了Touch Delegate

cocos2d 2.1版改變了
Touch Delegate:
因此在應用時,需要注意。而原本舊版的程式,需要修改 
 
CCTargetedTouchDelegate -> CCTouchOneByOneDelegate
CCStandardTouchDelegate -> CCTouchAllAtOnceDelegate


 原始官方資訊

2013年11月23日 星期六

CCSprite 基本應用整理


官方資料中文翻譯

以下是常用使用範例

1.
CCSprite* sprite =[CCSprite spriteWithFile:@"Icon.png"];//初始化
[self addChild:sprite]; //添加入层中
sprite.scale=2;//放大2倍
sprite.rotation=90;//旋转90度
sprite.opacity=255;//设置透明度为完全不透明(范围0~255)
sprite.position=ccp(100,100);//设置精灵中心点坐标是x=100,y=100
[sprite setFlipX:YES];//X轴镜像反转
[sprite setFlipY:YES];//Y轴镜像反转
[sprite setColor:ccc3(255, 0, 0)];//设置颜色为红色

2.
起始設定 z order
//--z值1的精灵
CCSprite* sprite =[CCSprite spriteWithFile:@"Icon.png"];
 [self addChild:sprite z:1]; //添加入层中
sprite.position=ccp(300,200);//设置精灵中心点坐标是x=100,y=100


3.
在 Layer中重設z order
[self reorderChild:sprite z:10];


4. 更換貼圖,使用新圖直接更換
CCSprite*sprite2 =[CCSprite spriteWithFile:@"Icon.png"];
sprite2.position=ccp(350,150);
[self addChild:sprite2]; //更换贴图
CCTexture2D * texture =[[CCTextureCache sharedTextureCache] addImage: @"Default.png"];//新建贴图
[sprite2 setTexture:texture]; 更換




5. 在緩衝模式下的圖片更換
//加载帧缓存,这个testpngs.plist保存了Icon和111两张图,-hd表示高清版本iphone4 [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"testpngs-hd.plist"];
CCSprite*sprite2 =[CCSprite spriteWithSpriteFrameName:@"Icon.png"]; sprite2.position=ccp(350,150);
[self addChild:sprite2];
//更换帧贴图 //从帧缓存中取出111.png
CCSpriteFrame* frame2 = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"111.png"];
[sprite2 setDisplayFrame:frame2];  更換





6. 取得 CCSprite 寬跟高
CCSprite *sp = [CCSprite spriteWithFile:@"Icon.png"];
NSLog(@"sp width:%f,heigt,:%f",sp.contentSize.width , sp.contentSize.height);

7. 移除Sprite:
CCSprite *sprite = (CCSprite *)sender; 
[self removeChild:sprite cleanup:YES];





二,常用操作
精灵加载完了就改各种使用了。
1,锚点
锚点就是所有旋转,移动,缩放的参考点。cocos2-x中默认的锚点是中心点。锚点用比例来表示范围为0-1,(0,0)点代表左下点,(1,1)代表右上点。设置的函数为setAnchorPoint(ccp(0.5, 0.5));
2,旋转
setRotation(angle) 其中angle为角度不是弧度。正数为顺时针旋转,负数为逆时针旋转。
3,位置
setPosition(ccp(xPos, yPos)) xPos和yPos为相对于父节点锚点的位置。
4,缩放
setScale(s);   // 整体缩放
setScaleX(s); // 原图片坐标X轴缩放
setScaleY(s); // 原图片坐标Y轴缩放
s为比例,s = 1表示原尺寸。
5,倾斜
setSkewX(s); // 原图片坐标X轴倾斜
setSkewY(s); // 原图片坐标Y轴倾斜
X轴向右为正,Y轴向上为正。
6,透明度
setOpacity(s);
s范围0-255,0完全透明,255完全不透明。
7,可见
setIsVisible(bVisible)
bVisible为bool值true代表可见false代表不可见
8,翻转
setFlipX(bFlip);  // 水平翻转
setFlipY(bFlip);  // 竖直翻转
bFlip 为true,则图片翻转,false不翻转。注意,翻转是针对原图片的操作,水平翻转相当于在图片编辑软件里水平翻转一样。不根据锚点进行翻转。翻转以 后,设置的以前设置的锚点不会随着图片的翻转而改变。比如设置右下角为锚点,则翻转以后,锚点为翻转后的图片的右下角(是不是有点绕?)


最后,初始化完成后,不要忘了使用addChild加入到父节点,否则是不会显示的。

2013年11月12日 星期二

ios7 只能用cocos2D v2.x版了

查詢了官網最新的v1.1RC0版 說明相關資料

* Base SDK 4.1 or newer should be used.
  • Don't report bugs if you are using a previous version.
  • Don't you have Base SDK 4.1 ? Install Xcode 3.2.6 or newer.
  • How to set Base SDK to 4.1: Xcode → Project → Edit project Settings → Build → Base SDK
Only Xcode 4 can be used with cocos2d, Xcode 3 isn't supported anymore.
With Xcode versions below 4.2.1 the compiler will generate warnings about '#pragma clang' statements. These can be safely commented out.
CocosLive is not supported anymore and has been taken out of the templates.
This version still supports armv6 (iPhone 3G, iPod touch 2G and lower), to compile for armv6 use Xcode 4.4.1 or lower.
RC0 has been tested intensively and will also become the stable release of 1.1., if no show stopping bugs will be found.

iPhone5 + iOS6 support


因此可以說沒救了,只能使用v2.1版了,希望程式碼不需要改動太多才好。


官方參考網址
http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:migrate_to_v2.0


改版過程失敗

1. CCNode.h的position_ 變數,改版後變成 _position , tag_及 contentSize_也是一樣

2. Box2D 中的b2DebugDraw 變成 b2Draw

3....


最重要的是如果外部代碼直接使用OPENGLES1,那就真的難救了。
只能就部分了解的想辦法解決了。

大改寫可能會比較快一些,並且可就了解的部分再最佳化了。 


Box2D在Xcode上的使用設定

基本環境,已經加入cocos2D,然後需要加入Box2D時,其設定如下。

1.將Box2D的source Code加入到Project下,原始碼放在cocos2D/external下,先放在libs次目錄下。


2. 設定Build搜尋目錄

3. 所有使用到Box2D的.m檔,其副檔名改成.mm,這樣才能吃進c++所寫的Box2D







2013年11月2日 星期六

cocos2D-iphone開發輔助工具列表

主要參考自 http://yehnan.blogspot.tw/2012/10/cocos2d-iphone.html

有收費的功能較強,如果真的沒錢,就自己尋找破解版吧。Mac/Windows都有。


點陣字型(bitmap font):
* BMFont(AngelCode Bitmap Font Generator),有Windows版。免費確認可用。使用說明
* Glyph Designer,有Mac版。 收費
* bmGlyph(bitmap glyph),有Mac版。 收費
* fonteditor,有Mac、Java版。不會用,找不到使用說明。
* LabelAtlasCreator,有Mac版。 只能產生plist檔,無Fnt檔,不能用
* Hiero Bitmap Font Tool,太舊已無更新,只能在舊版機器上用,Java


Texture Atlas(Sprite Sheet):
* TexturePacker,有Windows、Mac、Ubuntu版。lite版產生的PNG檔會有雜質。
* Zwoptex,有Mac、Flash版。免費版可用
* Atlas Lite ,Mac App Store上的免費工具
* darkFunction Editor,有Java版。只能產生xml格式
* SpriteHelper,與LevelHelper為姊妹產品,兩者搭配使用效果更佳,有Mac版。
* Sprite Sheet Packer,不能直接輸出cocos2d相容的格式,有Windows版。

xcode內建功能



關卡、場景編輯(Scene and Level):
* CocosBuilder,有Mac版。
* Cocoshop,有Mac版。
* LevelHelper,有Mac版。
* JSONWorldBuilder,有Mac版。

Tilemap磁磚拼貼式地圖:
* Tiled Map Editor,開放原始碼,儲存格式在此,有Windows跟Mac版,Java版不再更新。
* iTileMaps,有iPad、iPhone版。

Particle System粒子系統:
* Particle Designer,有Mac版。
* ParticleCreator,有Mac版。

Physics Engine物理引擎:
* PhysicsEditor,有Windows跟Mac版。
* VertexHelper,有Mac版。
* Mekanimo,有Windows版。
* PhysicsBench,有Mac版。

音訊、音檔編輯與格式轉換:
* Audacity,音訊編輯,開放原始碼,有Windows、Mac跟Linux版。
* WinFF,音訊格式轉換,開放原始碼,有Windows跟Linux版。
* Sound Converter,音訊格式轉換,有Mac版。小檔500K以下不用錢?
* Audio Converter,音訊格式轉換,有Windows版。
* afconvert,音訊格式轉換,Mac OS X命令列模式下的工具。
* GarageBand,有Mac版,錄音,音訊編輯。。

影像編輯:
* GIMP,強大的影像編輯軟體。有Windows、Mac、Linux版。
* Seashore,基本型影像編輯軟體,以GIMP底層技術為基礎,使用與GIMP相同的原生影像檔格式。有Mac版。
* Pixen,適合用來繪製像素畫,具有動畫編輯功能。有Mac版。
* ArtIcons,適合用來繪製游標、小圖示、像素畫。有Windows版。
* Microangelo,適合用來繪製游標、小圖示、像素畫。有Windows版。
* Inkscape,向量圖編輯軟體,開放原始碼,格式為Scalable Vector Graphics (SVG),有Windows、Mac、Ubuntu版。

其他:
* Spriter,製作遊戲中人物動畫(玩家角色、怪物)的工具,有Windows、Mac、Linux版。目前尚未被cocos2d-iphone支援。

很多工具都有提供試用版或功能較少的免費版,可先試用,若不滿意,那就請投資預算囉。

參考資料:
* Steffen Itterheim的The Complete (?) List Of Cocos2D Tools
* abitofcode 的Cocos2d – useful tools
* Ludum Dare » Tools,列出一些有名且免費的工具