2013年12月3日 星期二

怎樣使用Exception Breakpoints

有時候會遇到無法理解的Exception錯誤,Xcode提供了一個Exception Breakpoints的設定方式,以下為xcode5的範例。

 1. 首先到Breakpoints navigator,按下紅色匡所指的箭頭,就會出現,其快速鍵在Xcode5下為cmd+7



2.  在Breakpoints navigator的左下角有一個“+”號,指向它之後,會出現四種特殊的breakpoints選項,第一個就是exception breakpoints

3. 加入一個新的exception breakpoints後,就可以再一次執行會發生錯誤的app code了。如果使用右鍵,也可以修改這個breakpoints的執行條件




4. 再一次執行錯誤的app code後,就會直接停止在真正錯誤的程式行,而不會是跳離開的main.m這個地方了。




原始資料可參考
http://www.alauda.ro/2013/02/03/xcode-4-exception-breakpoints/



重點備註:
在使用cocos2d-iphone 的playBackgroundMusic來播放音檔時,必須要取消exception break,
不然在preload music file會出現錯誤。

refence--> http://stackoverflow.com/questions/18579761/cocos2d-thread-error-when-trying-to-add-background-music

2013年12月1日 星期日

Mac 當接者USB時,無法正確醒來

Mac在睡眠之後,有時無法正確從睡眠中醒來。

經過檢查過Mac內建的系統監視程式上面的訊息,
發現主要原因是由於醒來的過程中,
把一個手機外接到USB上,
而導致醒來的過程中,一直有一些disable的訊息出現。

同樣的,重新開機過程中,如果有接一個外接的USB或手機,
也會導致開機不順,其原因是由於Mac支援外接USB開機,
因此在啟動時要非常注意,

開機或啟動Mac時將所有的USB外接全部拔除。

2013年11月29日 星期五

遊戲種類及縮寫(網路轉貼)

由于游戏的类型很多,每一种游戏都有与其它游戏一样的共性,更有自己的个性文档。要想清楚的知道自己要做什么,就先要明白游戏都包括哪些类型。现在列举如下:

ACT......(ACTION GAME )动作游戏
STG......(SHOTING GAME )射击游戏
RPG......(ROLE PLAYING GAME )角色扮演游戏
A.RPG....(ACTION ROLE PLAYING GAME )动作角色扮演游戏
S.RPG....(SIMULATION ROLE PLAYIG GAME)模拟角色扮演游戏
FTG......(FIGHTING GAME )格斗游戏 
S.FTG....(SIMULATION FIGHTING GAME )模拟格斗游戏
SLG......(SIMULATION GAME )模拟仿真游戏
SPG......(SPORT GAME )运动游戏
TAB......(TABLE GAME )桌上游戏
PUZ......(PUZZLE GAME )益智游戏
AVG......(ADVENTURE GAME )冒险游戏
RAC......(RACE GAME )赛车游戏
RTG......(REAL TIME GAME)实时战略游戏
PET......(PET)养成类游戏及电子宠物
MAG......(MANAGEMENT GAME)经营类游戏
L.MUD....(LETTER MULTI-USER DUNGEONS)文字网络游戏
F.MUD....(FIGURE MULTI-USER DUNGEONS)图形网络游戏
ETC......(ETCTERA GAME )其他类游戏

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月25日 星期一

很有趣的免費License定義 WTFPL

真是他馬的贊的免費License定義(不是要罵人)


WTFPL – Do What the Fuck You Want to Public License



官網請看 http://www.wtfpl.net/

The Do What The Fuck You Want To Public License (WTFPL) is a free software license.
There is a long ongoing battle between GPL zealots and BSD fanatics, about which license type is the most free of the two. In fact, both license types have unacceptable obnoxious clauses (such as reproducing a huge disclaimer that is written in all caps) that severely restrain our freedoms. The WTFPL can solve this problem.
When analysing whether a license is free or not, you usually check that it allows free usage, modification and redistribution. Then you check that the additional restrictions do not impair fundamental freedoms. The WTFPL renders this task trivial: it allows everything and has no additional restrictions. How could life be easier? You just DO WHAT THE FUCK YOU WANT TO.
相對于GPL及BSD這兩個license的定義,都是他馬的複雜與囉唆,免費就是真的免費,所以就有人提出了WTFPL  這個定義,以後如果是真心要給大家免費分享的東西就使用這個License吧,別再用什麼GPL之類的License了。



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,那就真的難救了。
只能就部分了解的想辦法解決了。

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


Xcode的array語法使用誤例

Xcode 的C++語法比較嚴謹

b2Vec2 vertices[vertexCount]; ==> 不可以這樣用,要改成下面的方法
錯誤告示  variable length array of non-POD element type 'b2Vec2'

   
b2Vec2 *vertices = new b2Vec2[vertexCount]; // 修改後可用,xcode比較嚴謹


使用後要手動使用delete來釋放記憶體。
delete [] vertices; 
 
 
另外一種用法,改成vector
a)
std::vector<b2Vec2> vertices(count);
vertices[0].set(2, 3);
vertices[1].set(3, 4);
...

b)
std::vector<b2Vec2> vertices;
vertices.push_back(b2Vec2(2, 3));
vertices.push_back(b2Vec2(3, 4)); 

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,列出一些有名且免費的工具 

MAC輸入常用的標點符號

內建注音的話,輸入常用的標點符號非常方便!
像是:
[]=「」
\=、
shift + 1=!
shift + , =,
shift + . = 。
shift + ?=?
shift + []=『』
shift + ; = :
option + ; =;



業務與工程師

看了電子工程專輯論壇>上的 "業務與工程師哪個存活率高"所討論的問題,心有感慨,就用鹿鼎記上的人物來說說吧

最有名主角就是瑋小寶了,這是人物就是標準的超級業務,見人說人話,見鬼說鬼話,但他雖然是一個不學無術之人,但所有的事情發展卻也少不了他來牽線,因此在所有的事業單位如神龍教、清王朝 都極力的拉攏他,幾乎可以說是事業單位中的二號人物,這與一般公司內部的情形也差不多了,超級業務的地位都是極高的,而這些人一般都也都會有一些地下管道賺錢,這是一般人做不的。這些人基本上是富得流油了,不是一般人可以比的。

再來是眾多高手(工程師),最厲害的就屬神籠教中的高手們,為了讓這些高手乖乖聽話,只好使用毒藥來控制,美其名可以增進功力,其實大家都知道是控制用的毒藥,眾高手是很難跳巢的,因為藥物發作後,基本上是生不如死。這與許多非常厲害的工程師很像,厲害到老闆也怕你跳巢,所以用種種條約或是限制行股票來制約你,一旦你跳巢,就告到你生不如死。

當然也有些事業單位沒有這麼惡劣,像是少林寺高手就很不錯,有七十二絕技讓你可以不斷進修,在外面地位也不差,因為大家知道你是少林寺出身的,不過少林寺的武功是不能外帶,也就是你練的武功,只能為少林寺所用,七十二絕技是不可能外流的,外流的人也一定會被追殺的。所以只有自廢武功,你才能跳巢,不然就是到少林寺也沒辦法的地方去才可以。在少林寺內幾乎是不可能爬多高的,因為少林寺外流或戰死的人少,所以基本上職位也幾乎都不會改變的,在國內,只有一家半導體代工廠符合少林寺的地位。

那其他的事業單位如吳三桂集團、大明朱家等,對自家高手可就殘忍多了,一旦得罪集團內權貴,就可能死得莫名其妙,不過由於勢力範圍有限,半夜偷偷逃走還是可以的。在這種集團內,武功實力是無法提升多少的,但是有機會收黑錢的就可能賺一些的。如果將機密帶走到別的集團投靠,也會賺一票,只是也有一些風險存在的。基本上大部分公司會與此類似,這些公司已經基本夠大了,所以內部雖然亂,但也不至於立刻倒閉的。

說了這麼多高手(工程師),下場其實都不是太好,只是為了生活不得不投靠某些事業單位,但是也有些高手是自行遊走江湖的,一般來說只要小心,不要招惹到一些大集團,基本上生活還過得去,甚至有一些集團會來拉攏。如果單獨遊走江湖不太好混,基本上就有人會再次投靠其他事業單位,或是在小山頭上做個綠林好漢。也有一些高手在事業單位中混不到可以撈到油水的位置,就出走自立山門的。

現在來看看業務吧,基本上大清王朝的親王們就是標準的業務主管,平常與皇帝見面聊聊事情,派一些人員(小業務或小工程師)去各地辦事,只有大事情,例如與俄羅斯談判之類才會自己出面的。基本上,不管什麼事情,業務主管只要討皇上高興了,就可以收到些賞賜。而這些人也不太會跳巢的,除非皇帝老兒要你死,他們才會逃走的。一般業務主管也不會亂跳巢的,除非被高價收買。但是一旦業務主管跳巢,就會帶走一大票人。因為皇帝老兒一般對沒有跟著走的也不會太信任的。

大宦官也是業務的一種,只是大宦官一般較少出遠門,明朝的宦官除外。所以瑋小寶真的是一個寶啊。

在武林上一般的小業務陣亡率是最高的,除了要刺探軍情外,所有雜事都是小業務幹的,除非熬得夠久了,變成了業務主管的二手,才會比較好過的。

寫了這麼多,來看看高手(工程師)要做到什麼是最好的,神龍教教主、天地會陳近南算得上是最厲害的人物了,但其實到最後都沒有好下場,死不瞑目。反而我覺得西藏法王是最好的,地位崇高,而且還得以善終,但是要有這樣的運氣可不是那麼容易的。

那業務當然是做到瑋小寶等級是最好的了,一般來說做到超級業務後,基本上就無敵了,只要別去想要創業,大概這輩子都不愁吃穿了。如果做不到超級業務等級,只要混到了業務主管,基本上到退休也不成問題的,只要讓皇帝老兒高興了,小富到老絕對是可能的。

那其他人,就好好過日子吧,別想這麼多。實力不夠,連當個武林中的散人都難啊。只能說人在江湖身不由己。




PS: 想想看,身邊或報紙上的高手都像是武俠小說中的那個人物,樂趣就在其中啊!





2013年10月24日 星期四

ipad及iphone預設的啓動背景圖

參考網頁 http://www.idev101.com/code/User_Interface/launchImages.html

原始官方文件 https://developer.apple.com/library/ios/DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/App-RelatedResources/App-RelatedResources.html#//apple_ref/doc/uid/TP40007072-CH6-SW12


其中藍色字的是預設的檔名。 有了這些檔案後,IOS執行程式後,會自動先顯示這些圖檔,才會開始進入程式去執行,因此可以當作Logo來用。



Screen sizes (in pixels) of the iPhone 4S and iPhone 5















2013年10月23日 星期三

cocos2D基本動作例子

以原本template產生的HelloWorldLayer.m來作修改,原本Hello的Label移除,加入兩個移動的飛機圖,然後令他自行移動。


// on "init" you need to initialize your instance
-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {
      
        // ask director the the window size
        CGSize size = [[CCDirector sharedDirector] winSize];
      
        /*
        // create and initialize a Label
        CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];
      
        // position the label on the center of the screen
        label.position =  ccp( size.width /2 , size.height/2 );
        */
      
        CCSprite *spaceCargoShip = [CCSprite spriteWithFile:@"el-plane.png"];
        [spaceCargoShip setPosition:ccp(size.width/2, size.height/4)];
      
        [spaceCargoShip setScale:0.5];
      
        [spaceCargoShip setRotation:270];
      
        [self addChild:spaceCargoShip];
      
        // 原始點往目標點移動,每次移動5點
        id moveAction = [CCMoveTo actionWithDuration:5.0f position:ccp(size.width, size.height)];
                                            //position:ccp(0, size.height/2)];
        [spaceCargoShip runAction:moveAction];
      
      
        CCSprite *spaceCargoShip2 = [CCSprite spriteWithFile:@"url.png"];
        [spaceCargoShip2 setPosition:ccp(size.width/3, size.height/3)];
      
        [spaceCargoShip2 setScale:0.2];
      
        [spaceCargoShip2 setRotation:270];
      
        [self addChild:spaceCargoShip2];
      
        // 原始點往目標點移動,每次移動5點
        id moveAction2 = [CCMoveTo actionWithDuration:5.0f position:ccp(0, size.height)];
      
        [spaceCargoShip2 runAction:moveAction2];
        

      
      
        // add the label as a child to this Layer
        //[self addChild: label];
    }
    return self;
}


結果截圖


2013年10月22日 星期二

cocos2D基本範例資訊

由template產生的範例,有一些內部設定可以瞭解一下,當作未來修改的參考

原始檔案列表


1. GameConfig.h

//
// Supported Autorotations:
//        None,
//        UIViewController,
//        CCDirector
//
#define kGameAutorotationNone 0                               //不使用自動旋轉
#define kGameAutorotationCCDirector 1                      //速度考量使用,不匹配UIKit元件
#define kGameAutorotationUIViewController 2             // 相容性考量(基本設定)

//
// Define here the type of autorotation that you want for your game
//

// 3rd generation and newer devices: Rotate using UIViewController. Rotation should be supported on iPad apps.
// TIP:
// To improve the performance, you should set this value to "kGameAutorotationNone" or "kGameAutorotationCCDirector"
#if defined(__ARM_NEON__) || TARGET_IPHONE_SIMULATOR
#define GAME_AUTOROTATION kGameAutorotationUIViewController

// ARMv6 (1st and 2nd generation devices): Don't rotate. It is very expensive
#elif __arm__
#define GAME_AUTOROTATION kGameAutorotationNone


// Ignore this value on Mac
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)

#else
#error(unknown architecture)
#endif


2.  AppDelegate.m,所有cocos2d的基本設定都在此處完成

#import "cocos2d.h"

#import "AppDelegate.h"
#import "GameConfig.h"
#import "HelloWorldLayer.h"
#import "RootViewController.h"

@implementation AppDelegate

@synthesize window;

- (void) removeStartupFlicker
{
    //
    // THIS CODE REMOVES THE STARTUP FLICKER
    //
    // Uncomment the following code if you Application only supports landscape mode
    //
#if GAME_AUTOROTATION == kGameAutorotationUIViewController

    // 此處的作用還是不清楚,書面資料是要取代原來cocos2D的圖片顯示,但並沒有成功顯示出成果???
    // 還是因為啓動顯示還是直立的關係,此處是要避免橫向啓動時的閃動。

    CC_ENABLE_DEFAULT_GL_STATES();
    CCDirector *director = [CCDirector sharedDirector];
    CGSize size = [director winSize];
    CCSprite *sprite = [CCSprite spriteWithFile:@"travel.png"];
    sprite.position = ccp(size.width/2, size.height/2);
    sprite.rotation = -90;
    [sprite visit];
    [[director openGLView] swapBuffers];
    CC_ENABLE_DEFAULT_GL_STATES();
  
  
#endif // GAME_AUTOROTATION == kGameAutorotationUIViewController  
}
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
    // Init the window
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  
    // Try to use CADisplayLink director
    // if it fails (SDK < 3.1) use the default director
    if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
        [CCDirector setDirectorType:kCCDirectorTypeDefault]; //確保設定cocos2D成功
  
  
    CCDirector *director = [CCDirector sharedDirector]; // 呼叫sharedDirector來 初始化director
  
    // Init the View Controller  初始 viewController
    viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    viewController.wantsFullScreenLayout = YES;
  
    //
    // Create the EAGLView manually  建立EAGLView給遊戲畫面(OPENGLES設定基本運作格式)
    //  1. Create a RGB565 format. Alternative: RGBA8
    //    2. depth format of 0 bit. Use 16 or 24 bit for 3d effects, like CCPageTurnTransition
    //
    //
    EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
                                   pixelFormat:kEAGLColorFormatRGB565    // kEAGLColorFormatRGBA8
                                   depthFormat:0                        // GL_DEPTH_COMPONENT16_OES
                        ];
  
    // attach the openglView to the director
    [director setOpenGLView:glView]; // 將OPENGLES畫面設定給予director
  
//    // 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");
  
    //
    // VERY IMPORTANT:
    // If the rotation is going to be controlled by a UIViewController
    // then the device orientation should be "Portrait".
    //
    // IMPORTANT:
    // By default, this template only supports Landscape orientations.
    // Edit the RootViewController.m file to edit the supported orientations.
    //
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
    [director setDeviceOrientation:kCCDeviceOrientationPortrait];  // 設定原始Device的方向,原始為縱向,可改為橫向
    //[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft]; // 橫向設定後,字才會是橫向的,此處是自己為了橫向顯示而加的,所以mark起來
#else

    [director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#endif
  
    [director setAnimationInterval:1.0/60];  // frame rate 為60
    [director setDisplayFPS:YES];    // 顯示現在frame rate的數值,非Debug必要時可關閉   
  
    // make the OpenGLView a child of the view controller
    [viewController setView:glView]; // 設定glView為viewController的子元件,為了畫面的計算
  
    // make the View Controller a child of the main window
    [window addSubview: viewController.view];  // 將圖顯是在畫面上
    [window makeKeyAndVisible];
  
    // Default texture format for PNG/BMP/TIFF/JPEG/GIF images
    // It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
    // You can change anytime.  預設使用最高位元來顯示貼圖
    [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

    // Removes the startup flicker
    [self removeStartupFlicker]; // 在橫向顯示啓動時會有閃動畫面,因此需要使用此函數
  
    // Run the intro Scene ,執行HelloWorldLayer這個scene
    //[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];
    [director runWithScene: [HelloWorldLayer scene]];
}

//執行順序 applicationWillResignActive -> applicationDidEnterBackground
- (void)applicationWillResignActive:(UIApplication *)application {
    [[CCDirector sharedDirector] pause]; // ipad或iphone螢幕關上時,暫停運作
}

// 執行順序 applicationWillEnterForeground -> applicationDidBecomeActive
- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[CCDirector sharedDirector] resume]; // ipad或iphone螢幕開啓時,重新運作
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    [[CCDirector sharedDirector] purgeCachedData];  // 記憶體不足時,丟棄無用的貼圖及字型資料
}

-(void) applicationDidEnterBackground:(UIApplication*)application {
    [[CCDirector sharedDirector] stopAnimation]; // 程式被移到背景時,暫停運作
}

-(void) applicationWillEnterForeground:(UIApplication*)application {
    [[CCDirector sharedDirector] startAnimation]; // 程式回到前景時,重新運作
}

// director被移除時,停止運作,釋放記憶體
- (void)applicationWillTerminate:(UIApplication *)application {
    CCDirector *director = [CCDirector sharedDirector];
  
    [[director openGLView] removeFromSuperview];
  
    [viewController release];
  
    [window release];
  
    [director end];  
}

- (void)applicationSignificantTimeChange:(UIApplication *)application {
    [[CCDirector sharedDirector] setNextDeltaTimeZero:YES]; // 設定呼叫事件之間的時間差為零,避免不正常行為。
}

- (void)dealloc {
    [[CCDirector sharedDirector] end];
    [window release];
    [super dealloc];
}

@end


3. RootViewController.m 基本狀態下不會進入其中的子程式,因此不看了



4. HelloWorldLayer.m,一個scene的物件,作為顯示一組動作元件之用

// Import the interfaces
#import "HelloWorldLayer.h"

// HelloWorldLayer implementation
@implementation HelloWorldLayer

+(CCScene *) scene  // 設定HelloWorldLayer 的scene並回傳後使用,初始化HelloWorldLayer之用
// 其中至少要包含了一組以上的Layer
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node]; // 設定scene是一個CCNode的物件
    // CCScene <- CCNode
   
    // 'layer' is an autorelease object.
    HelloWorldLayer *layer = [HelloWorldLayer node]; // 設定layer是一個CCNode的物件
    // 因為HelloWorldLayer <- CCLayer <- CCNode   繼承關係

    // 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 // 外部呼叫此子程式來使用HelloWorldLayer的scene,進而顯示動作效果
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {  // 在此Layer下,所有動作設定的位置。如要加入新的顯示元件,也是在此。
       
        // create and initialize a Label
        CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];

        // ask director the the window size
        CGSize size = [[CCDirector sharedDirector] winSize];
   
        // position the label on the center of the screen
        label.position =  ccp( size.width /2 , size.height/2 );
       
        // add the label as a child to this Layer
        [self addChild: label];
    }
    return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    // in case you have something to dealloc, do it in this method
    // in this particular example nothing needs to be released.
    // cocos2d will automatically release all the children (Label)
   
    // don't forget to call "super dealloc"
    [super dealloc];
}
@end


5.  縱向及橫向結果顯示
[director setDeviceOrientation:kCCDeviceOrientationPortrait];  // 設定原始Device的方向,原始為縱向,可改為橫向








   


[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft]; // 橫向設定後,字才會是橫向的