首页 > 代码库 > iOS_31_cocos2d_SpriteBatchNode

iOS_31_cocos2d_SpriteBatchNode

最终效果图:

一次完整的渲染包括三步:渲染前的准备(open)、执行渲染、渲染完成后的工作(close)
一个spriteBatchNode对应一个纹理\图片
因此,添加到spriteBatchNode里面的sprite必须使用同一个图片\纹理
从上面,可以看到,不使用spriteBatchNode时,精灵个数不停地增加
当使用了spriteBatchNode,精灵个数恒定
在上面的图片中,实例化spriteBatchNode时,参数指定的image file是一张打包合成的大图片
前面说过,spriteFrameCache精灵帧缓存,里面放的是plist文件中每一帧的数据:rect,rotated,小图片名等;根据小图片在plist中的key(小图片名),可以到一个大的图片中去裁剪出来想要的小图片
因此,可以将所有的裁剪出来的所有精灵帧添加到同一个spriteBatchNode里面去,由它统一管理、统一渲染(因为这些精灵帧用到的纹理都是同一个,即大的图片)
而场景里,只需添加一个spriteBatchNode即可;其他的,通过同一个大图片\纹理 创建出来的精灵或精灵帧只需添加到spriteBatchNode里面
类似的,如果项目中用到两个或多个图片(或大图片),只需要一个spriteBatchNode对应一个图片,一个图片(或大图片)创建出来的sprite全部统一添加到与该图片\纹理对应的spriteBatchNode里面
//
//  SpriteBatchNode.m
//  31_cocos2D入门
//
//  Created by beyond on 14-9-25.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
// 添加SpriteBatchNode到当前场景,以后batch统一负责管理所有的【使用了同一张图片作为纹理的】精灵
/*
 一个CCSpriteBatchNode对象只能处理一个纹理对象(添加到batch中的子节点必须和batch使用同一个纹理对象)
 
 // 创建一个精灵批处理(类似一个池,所有用同一张图片,生成的精灵,全部加到这个池中,统一管理,重要前提:一个精灵批处理只认一张图片,即:一个精灵批处理只允许使用相同纹理的精灵加入它,加入池,加入这个大家庭)
 
 // 因为一个spriteWithFile,会经历三个步骤:首先是open纹理, 然后是 渲染,最后是 close纹理
 // 如果使用spriteWithFile方法,生成1000个sprite,上面三个步骤会执行一千次,屏幕上,此时也会生成1000个node
 
 // 因此,使用spriteBatchNode之后,只会open纹理一次,渲染1000次,关闭纹理一次即可,此时屏幕上,始终只有一个Node,它就是spriteBatchNode,因为sprite全部添加到spriteBatchNode中,让它去统一管理
 
 // 假如,项目中所有图片全部打包到一个大图片,那么项目就只有一个大的纹理,所有的精灵帧,都会根据Plist文件中的key即小图片名,到大的纹理相册中裁剪图片,那么,我们就可以就让一个spriteBatchNode管理该大图片,即大的纹理相册;所有的精灵帧对象,由于使用的是同一张大图片,所以可以全部添加到spriteBatchNode中统一进行管理;因为所有的精灵帧使用到同一个纹理相册,同一个大图片
 
 // spriteFrameCache精灵帧缓存,里面放的是plist文件中每一帧的数据:如rect,rotated,小图片名等;根据这些,到一个大的图片中去裁剪出来想要的小图片
 */

#import "SpriteBatchNodeScene.h"
@interface SpriteBatchNodeScene()
{
    CCSpriteBatchNode *_batch;
}
@end
@implementation SpriteBatchNodeScene

#pragma mark - 覆盖父类方法
-(id)init
{
    if (self=[super init]) {
        // 1、场景Node 允许交互
        self.userInteractionEnabled = YES;
    }
    return self;
}
- (void)addSpriteInCenter{}
- (void)addShowBtns
{
    // 1.使用spriteBatchNode
    [self addBtn:@"【使用batchNode】" position:ccp(0, 0) target:self sel:@selector(use_batchNode)];
}
#pragma mark - 按钮点击
- (void)use_batchNode
{
    // 添加SpriteBatchNode到当前场景,以后batch统一负责管理所有的【使用了同一张图片作为纹理的】精灵
    // 1.加载大的纹理相册
    CCSpriteFrameCache *spriteFrameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
    [spriteFrameCache addSpriteFramesWithFile:@"zhaoyun.plist"];
    // 2.参数是图片名,一个batch只会只能管理 从同一个大图片 创建出来的sprite
    _batch = [CCSpriteBatchNode batchNodeWithFile:@"zhaoyun.png"];
    // 下面二句 等价于 上面的一句
    CCTexture *texture = [CCTexture textureWithFile:@"zhaoyun.png"];
    [CCSpriteBatchNode batchNodeWithTexture:texture];
    // 3.添加batch到当前场景,以后所有创建出来的精灵,只需添加到spriteBatchNode中即可
    // 当前场景 只管理batch,而batch统一负责管理所有的【使用了同一张图片作为纹理的】精灵
    [self addChild:_batch];
}

#pragma mark - 点击屏幕
// 手抬起处就放一个精灵
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    // 得到触摸点
    CGPoint touchLoc = [touch locationInNode:self];
    // 从纹理相册plist文件中,根据key:图片名,从大图片中裁剪出小图片
    // 从大图片中随机取出一个小图片,key为Plist中的图片名,1~9.png
    NSString *imgName = [NSString stringWithFormat:@"%d.png",arc4random()%9+1];
    CCSpriteFrame *frame = [CCSpriteFrame frameWithImageNamed:imgName];
    CCSprite *s = [CCSprite spriteWithSpriteFrame:frame];
    // 关键一句:
    // 设置 子弹出现的位置
    s.position = touchLoc;


    if (_batch == nil) {
        [self addChild:s];
    } else {
        [_batch addChild:s];
    }
}



@end






























iOS_31_cocos2d_SpriteBatchNode