2011/05/04

實作類似水果忍者刀光

效果如下

以cocos2d  的CCLayer實作
CutterPathScene.h
 #import <Math.h>  
 #import "cocos2d.h"  
 #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))  
 #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)  
 #define BLADE_NODE 20  
 #define CREATE_NODE (BLADE_NODE+BLADE_NODE-2)  
 @interface CutterPathScene : CCLayer {  
 @private  
   NSMutableArray* pointAry;  
   CCTexture2D* texture_;  
   GLfloat lver[CREATE_NODE*2];  
   GLfloat ltexCoord[CREATE_NODE*2];  
   GLfloat rver[CREATE_NODE*2];  
   GLfloat rtexCoord[CREATE_NODE*2];  
   int nodeCount;  
   bool isOnTouch;  
 }  
 @property (nonatomic, assign)bool isOnTouch;  
 +(id)scene;  
 -(void)addPoint:(CGPoint)p;  
 -(void)changeCutterPathData;  
 @end  

CutterPathScene.m
 #import "CutterPathScene.h"  
 @implementation CutterPathScene  
 @synthesize isOnTouch;  
 +(id)scene  
 {  
   CCScene *scene = [CCScene node];  
   CCLayer *layer = [CutterPathScene node];  
   [scene addChild:layer];  
   return scene;  
 }  
 -(void) onEnterTransitionDidFinish  
 {  
   [super onEnterTransitionDidFinish];  
   [self scheduleUpdate];  
 }  
 - (id)init  
 {  
   self = [super init];  
   if (self) {  
     pointAry = [[NSMutableArray alloc]init];  
     //texture_ = [[CCTexture2D alloc]initWithImage:[UIImage imageNamed:@"key.png"]];  
     //ccTexParams *params = malloc(sizeof(ccTexParams));  
     //params->magFilter = GL_NEAREST;  
     //params->minFilter = GL_LINEAR;  
     //params->wrapS = GL_REPEAT;  
     //params->wrapT = GL_REPEAT;  
     //[texture_ setTexParameters:params];  
     //free(params);  
     for(int i=0; i<CREATE_NODE*2; i++)  
     {  
       lver[i] = 0;  
       ltexCoord[i] = 0;  
       rver[i] = 0;  
       rtexCoord[i] = 0;  
     }  
   }  
   self.isOnTouch = false;  
   self.isTouchEnabled = YES;  
   return self;  
 }  
 -(void) update:(ccTime) dt  
 {  
   static ccTime addTime =0;  
   addTime+=dt;  
   if(!isOnTouch)  
   {  
     if(addTime >0.02)  
     {  
       [pointAry removeObjectAtIndex:0];  
       [self changeCutterPathData];  
       addTime-=0.02;  
     }  
   }  
 }  
 - (void)draw  
 {          
     // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY  
     // Needed states: GL_VERTEX_ARRAY, GL_COLOR_ARRAY  
     // Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY  
   [super draw];  
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
   glDisableClientState(GL_COLOR_ARRAY);  
     glDisable(GL_TEXTURE_2D);  
   //glBindTexture(GL_TEXTURE_2D, [texture_ name]);  
   if(nodeCount >0)  
   {  
     glVertexPointer(2, GL_FLOAT, 0, lver);  
     //glTexCoordPointer(2, GL_FLOAT, 0, ltexCoord);  
     glDrawArrays(GL_TRIANGLE_STRIP, 0, nodeCount);  
     glVertexPointer(2, GL_FLOAT, 0, rver);  
     //glTexCoordPointer(2, GL_FLOAT, 0, rtexCoord);  
     glDrawArrays(GL_TRIANGLE_STRIP, 0, nodeCount);  
   }  
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
   glEnableClientState(GL_COLOR_ARRAY);  
     glEnable(GL_TEXTURE_2D);  
 }  
 -(void) registerWithTouchDispatcher  
 {  
   [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];  
 }  
 -(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event  
 {  
   isOnTouch = true;  
   return YES;  
 }  
 -(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event  
 {  
   isOnTouch = false;  
 }  
 -(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event  
 {  
   CGPoint touchPoint = [touch locationInView:[touch view]];  
   CGPoint convertDPoint = [[CCDirector sharedDirector]convertToGL:touchPoint];   
   [self addPoint:convertDPoint];  
 }  
 -(void) addPoint:(CGPoint) p  
 {  
   if([pointAry count]>(BLADE_NODE-1))  
     [pointAry removeObjectAtIndex:0];  
   [pointAry addObject:[NSValue valueWithCGPoint:p]] ;  
   [self changeCutterPathData];  
 }  
 -(void) changeCutterPathData  
 {  
   nodeCount = [pointAry count]+[pointAry count] -2 ;  
   float len = 0;  
   for(int i=0; i<[pointAry count]; i++)  
   {  
     CGPoint p = [[pointAry objectAtIndex:i]CGPointValue];  
     if(i==0)  
     {  
       lver[0] = p.x;  
       lver[1] = p.y;  
       ltexCoord[0] = 0.5;  
       ltexCoord[1] = 0;  
       rver[0] = p.x;  
       rver[1] = p.y;  
       rtexCoord[0] = 0.5;  
       rtexCoord[1] = 0;  
     }  
     else if(i == [pointAry count]-1)  
     {  
       CGPoint subP = ccpSub([[pointAry objectAtIndex:i]CGPointValue], [[pointAry objectAtIndex:i-1]CGPointValue]);  
       subP = ccpMult( ccpNormalize(subP), 10);  
       int idx = (i-1)*4+2;  
       lver[idx] = p.x+subP.x;  
       lver[idx+1] = p.y+subP.y;  
       ltexCoord[idx] = 0.5;  
       ltexCoord[idx+1] = len;  
       rver[idx] = p.x+subP.x;  
       rver[idx+1] = p.y+subP.y;  
       rtexCoord[idx] = 0.5;  
       rtexCoord[idx+1] = len;  
     }else  
     {  
       int idx = (i-1)*4+2;  
       lver[idx] = p.x;  
       lver[idx+1] = p.y;  
       CGPoint subP = ccpSub([[pointAry objectAtIndex:i]CGPointValue], [[pointAry objectAtIndex:i+1]CGPointValue]);  
       subP = ccpNormalize(subP);  
       CGPoint lsubP = ccpRotateByAngle(subP, ccp(0, 0), DEGREES_TO_RADIANS(90));  
       lsubP = ccpMult(lsubP, 10);  
       lver[idx+2] = p.x+lsubP.x*((float)(i)/[pointAry count]);  
       lver[idx+3] = p.y+lsubP.y*((float)(i)/[pointAry count]);  
       rver[idx] = p.x;  
       rver[idx+1] = p.y;  
       CGPoint rsubP = ccpRotateByAngle(subP, ccp(0, 0), DEGREES_TO_RADIANS(-90));  
       rsubP = ccpMult(rsubP, 10);  
       rver[idx+2] = p.x+rsubP.x*((float)(i)/[pointAry count]);  
       rver[idx+3] = p.y+rsubP.y*((float)(i)/[pointAry count]);  
       ltexCoord[idx] = 0.5;  
       ltexCoord[idx+1] = len;  
       ltexCoord[idx+2] = 0;  
       ltexCoord[idx+3] = len;  
       rtexCoord[idx] = 0.5;  
       rtexCoord[idx+1] = len;  
       rtexCoord[idx+2] = 1;  
       rtexCoord[idx+3] = len;  
       len+=ccpDistance([[pointAry objectAtIndex:i]CGPointValue], [[pointAry objectAtIndex:i+1]CGPointValue])/50;   
     }  
   }  
 }  
 - (void)dealloc  
 {  
   [pointAry release];  
   [texture_ release];  
   [super dealloc];  
 }  
 @end  

程式碼當中有貼圖的部份是用來為刀光貼圖
不過在這裡是先關掉

沒有留言 :