游戏效果解密----水果忍者刀划痕效果
闲来无事,开始研究opengl在cocos2d中图像渲染时候的底层用法,及除了CCScene,CCSprint普通接口以外,底层opengl图形纹理渲染部分的代码。github有不少很棒的demo,拿过来研究一下。在这里感谢开源社区的所有贡献者。
水果忍者刀划痕效果,github地址:https://github.com/hiepnd/CCBlade
该例子主要用一下两个文件:
CCBlade.m//划痕效果的顶点存储,opengl的渲染
TouchTrailLayer.m //继承CCLayer,接收touch的begin、end点,传递给CCBlade,进行动画显示
下面主要介绍CCBlade。由于代码较多,难度不一,因此我将我的理解注释和测试代码写入了文件中,你可以直接阅读代码,里面关键的地方我已经写上了注释。有助于理解,当然,我的理解肯定有错误,还请多多指正,共同进步。
效果图:
CCBlade.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"#define USE_STL_LIST 0inline float fangle(CGPoint vect);
inline float lagrange1(CGPoint p1, CGPoint p2, float x);inline void CGPointSet(CGPoint *v, float x, float y);
inline void f1(CGPoint p1, CGPoint p2, float d, CGPoint *o1, CGPoint *o2);@interface CCBlade : CCNode {//轨迹所有点arrayNSMutableArray *path;unsigned int pointLimit;int count;//opengl中存储vertices & coordinate数组CGPoint *vertices;CGPoint *coordinates;BOOL reset;CCTexture2D *_texture; float width;BOOL _finish;BOOL _willPop;
}
@property (readonly)unsigned int pointLimit;
@property(retain) CCTexture2D *texture;
@property(nonatomic) float width;
@property (nonatomic, assign) BOOL autoDim;+ (id) bladeWithMaximumPoint:(int) limit;
- (id) initWithMaximumPoint:(int) limit;
- (void) push:(CGPoint) v;
- (void) pop:(int) n;
- (void) clear;
- (void) reset;
- (void) dim:(BOOL) dim;
- (void) finish;
@end
CCBlade.m
#import "CCBlade.h"//计算旋转角度
inline float fangle(CGPoint vect){//相同,不旋转if (vect.x == 0.0 && vect.y == 0.0) {return 0;}//y不同,旋转90度if (vect.x == 0.0) {return vect.y > 0 ? M_PI/2 : -M_PI/2;}//x逆向if (vect.y == 0.0 && vect.x < 0) {return -M_PI;}//出去上面的特殊情况,剩下的atan计算角度float angle = atan(vect.y / vect.x);return vect.x < 0 ? angle + M_PI : angle;
}//p1,p2 原点
//o1,o2 目标点
//d 宽度
inline void f1(CGPoint p1, CGPoint p2, float d, CGPoint *o1, CGPoint *o2){float l = ccpDistance(p1, p2);//计算转角角度float angle = fangle(ccpSub(p2, p1));//将p1点的width两端进行旋转//这里只取p1,是因为下一次p2会迭代为p1进行计算*o1 = ccpRotateByAngle(ccp(p1.x + l,p1.y + d), p1, angle);*o2 = ccpRotateByAngle(ccp(p1.x + l,p1.y - d), p1, angle);
}inline float lagrange1(CGPoint p1, CGPoint p2, float x){return (x-p1.x)/(p2.x - p1.x)*p2.y + (x-p2.x)/(p1.x - p2.x)*p1.y ;
}inline void CGPointSet(CGPoint *v, float x, float y){v->x = x;v->y = y;
}@implementation CCBlade
@synthesize texture = _texture;
@synthesize pointLimit;
@synthesize width;
@synthesize autoDim;+ (id) bladeWithMaximumPoint:(int) limit{return [[[self alloc] initWithMaximumPoint:limit] autorelease];
}- (id) initWithMaximumPoint:(int) limit{self = [super init];pointLimit = limit;self.width = 5;vertices = (CGPoint *)calloc(2*limit+5, sizeof(vertices[0]));coordinates = (CGPoint *)calloc(2*limit+5, sizeof(coordinates[0]));CGPointSet(coordinates+0, 0.00, 0.5);reset = NO;path = [[NSMutableArray alloc] init];return self;
}- (void) dealloc{[_texture release];free(vertices);free(coordinates);[path release]; [super dealloc];
}//move (populater) vertices
- (void) populateVertices{vertices[0] = [[path objectAtIndex:0] CGPointValue];//get the header point ,then iterate itCGPoint pre = vertices[0];unsigned int i = 0;/**glTexCoordPointer(2, GL_FLOAT, 0, coordinates);glVertexPointer(2, GL_FLOAT, 0, vertices);*///get second point ,then iterate itCGPoint it = [[path objectAtIndex:1] CGPointValue];float dd = width / [path count];//as "pre"&"it" cost 2 item ,so "while" is "n-2"
// printf("%s:%d sizeof CGPoing:%ld\n",__FUNCTION__,__LINE__,sizeof(CGPoint));while (i < [path count] - 2){//change the width (height) of the blade//"width - i * dd",dd不变 i 越大,越宽f1(pre, it, width - i * dd , vertices+2*i+1, vertices+2*i+2);
// f1(pre, it, 7, vertices+2*i+1, vertices+2*i+2);//all coordinates are same value , never change valueCGPointSet(coordinates+2*i+1, .5, 1.0);CGPointSet(coordinates+2*i+2, .5, 0.0);i++;pre = it;it = [[path objectAtIndex:i+1] CGPointValue];}CGPointSet(coordinates+1, 0.25, 1.0); CGPointSet(coordinates+2, 0.25, 0.0);vertices[2*[path count]-3] = it;CGPointSet(coordinates+2*[path count]-3, 0.75, 0.5);
}
//移动点坐标,未用
- (void) shift{int index = 2 * pointLimit - 1;for (int i = index; i > 3; i -= 2) {vertices[i] = vertices[i-2];vertices[i-1] = vertices[i-3];}
}- (void) setWidth:(float)width_{width = width_ * CC_CONTENT_SCALE_FACTOR();
}#define DISTANCE_TO_INTERPOLATE 10 //允许的线条最大长度//insert a point at the header of the path
- (void) push:(CGPoint) v{_willPop = NO;if (reset) {return;}//retina screenif (CC_CONTENT_SCALE_FACTOR() != 1.0f) {v = ccpMult(v, CC_CONTENT_SCALE_FACTOR());}if ([path count] == 0) {[path insertObject:[NSValue valueWithCGPoint:v] atIndex:0];return;}CGPoint first = [[path objectAtIndex:0] CGPointValue];if (ccpDistance(v, first) < DISTANCE_TO_INTERPOLATE) {//如果小于最大长度,则insert at the header[path insertObject:[NSValue valueWithCGPoint:v] atIndex:0];if ([path count] > pointLimit) {[path removeLastObject];}}else{//移除最后的verticesint num = ccpDistance(v, first) / DISTANCE_TO_INTERPOLATE;CGPoint iv = ccpMult(ccpSub(v, first), (float)1./(num + 1));for (int i = 1; i <= num + 1; i++) {[path insertObject:[NSValue valueWithCGPoint:ccpAdd(first, ccpMult(iv, i))] atIndex:0];}while ([path count] > pointLimit) {[path removeLastObject];}}[self populateVertices];
}
//移除最后点
- (void) pop:(int) n{while ([path count] > 0 && n > 0) {[path removeLastObject];n--;}if ([path count] > 2) {[self populateVertices];}
}- (void) clear{[path removeAllObjects];reset = NO;if (_finish)[self removeFromParentAndCleanup:YES];
} - (void) reset{reset = TRUE;
}- (void) dim:(BOOL) dim{reset = dim;
}- (void) draw{if ((reset && [path count] > 0) || (self.autoDim && _willPop)) {[self pop:1];if ([path count] < 3) {[self clear];}}if ([path count] < 3) {return;}_willPop = YES;glDisableClientState(GL_COLOR_ARRAY);NSAssert(_texture, @"NO TEXTURE SET");/**f1(pre, it, width - i * dd , vertices+2*i+1, vertices+2*i+2);// f1(pre, it, 7, vertices+2*i+1, vertices+2*i+2);//all coordinates are same value , never change valueCGPointSet(coordinates+2*i+1, .5, 1.0);CGPointSet(coordinates+2*i+2, .5, 0.0);*/glBindTexture(GL_TEXTURE_2D, _texture.name);
// glVertexPointer(2, GL_FLOAT, 0, vertices);glTexCoordPointer(2, GL_FLOAT, 0, coordinates);glVertexPointer(2, GL_FLOAT, 0, vertices);
// glTexCoordPointer(2, GL_FLOAT, 0, vertices);
// glVertexPointer(2, GL_FLOAT, 0, coordinates);glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*[path count]-2);//不是blade,是fans
// glDrawArrays(GL_TRIANGLE_FAN, 0, 2*[path count]-2);glEnableClientState(GL_COLOR_ARRAY);
}- (void) finish
{_finish = YES;
}
游戏效果解密----水果忍者刀划痕效果相关推荐
- android水果忍者源码,android 水果忍者的 刀锋 效果实现源码
[实例简介] android 水果忍者的 刀锋 效果实现源码 [实例截图] [核心代码] 54532水果忍者Ninjia └── Ninjia ├── AndroidManifest.xml ├── ...
- 《游戏学习》| 水果忍者HTML5网页版在线游戏 | 源码分析
游戏介绍 这是一款由百度JS小组提供的HTML5版切水果游戏,这款基于HTML5实现的网页版切水果游戏虽然和原版的切水果游戏相比仍有美中不足之处,但也算有声有色,画面效果也十分炫目华丽. 游戏截图 主 ...
- 基于前端实现的JS游戏-二开水果忍者
下来看看效果吧! 这个是游戏结束! 游戏均可二开,自己可以下载后,吧图片,音乐改成自己的.这个是文件 图片在image里面修改,游戏难度在js代码修改,目前已经在重要难度修改的地方已经添加注释. 音乐 ...
- 苹果的水果忍者未能连接到服务器是怎么回事,水果忍者总是显示无法连接网络...
水果忍者这款游戏相信大家都不陌生吧,最近小编经常收到水果忍者总是显示无法连接网络问题的反馈,接下来小编就为大家提供几种常见的处理方案. 水果忍者游戏简介 <水果忍者® - 爽快切水果>是一 ...
- 水果忍者未能连接到服务器,打开水果忍者提示网络异常或者连接不上
打开水果忍者提示网络异常或者连接不上,相信大家在玩水果忍者的过程中,经常会遇到这样的问题,下面ourplay小编就简单为大家介绍几种常见的解决方案. 水果忍者游戏简介 <水果忍者® - 爽快切水 ...
- 玩水果忍者未能找到服务器,水果忍者无法连接服务器是什么原因
水果忍者这款游戏相信大家都不陌生吧,最近小编经常收到水果忍者无法连接服务器是什么原因问题的反馈,接下来小编就为大家提供几种常见的处理方案. 水果忍者游戏简介 <水果忍者® - 爽快切水果> ...
- C/C++实现水果忍者(一) 启动
文章目录 思路和想法 起步:显示背景 思路和想法 水果忍者是经典的小游戏. <水果忍者>(Fruit Ninja),是由澳大利亚公司Halfbrick Studios开发的一款休闲益智类游 ...
- 用haXe+NME实现水果忍者的刀光效果,支持多点触摸,Flash10, Android通用
前两天玩了玩水果忍者,感觉这种输入方式是非常适合多点触摸屏的,输入直观而且爽快感十足,于是就想到了如何使用haxe+NME实现刀光的效果,今天按照我的想法把效果实现了,感觉还是很逼真的.估计即使不是水 ...
- HTML5 水果忍者游戏
HTML5 实现水果忍者小游戏 相信大家对于水果忍者这款游戏肯定不陌生,在几年前的移动端手机上随处可见到处切水果的身影 那我们现在就来了解一下PC端的水果忍者是怎么编写的 一.代码结构 图片归图片.音 ...
最新文章
- 如何使用Leangoo自动生成燃尽图
- 第一次现场看球,第一次场看国家队打球,第一次场看国家队打架,第一次上电视,第... ......
- wireshark的使用
- win10下最新MySQL8.0安装与环境配置,Navicat图形化管理工具连接,完整详细可收藏
- 6-3 递增的整数序列链表的插入 (10 分)
- 如何预防销售人员带走客户?
- java连接数据库的基本操作
- 几个常用的dos命令
- 道路施工安全智能预警
- 真正拖垮打工人的,是沉没成本
- html万花筒图片轮播代码,jQuery实现可拖拽3D万花筒旋转特效
- 利用pygame实现大鱼吃小鱼游戏
- SONET、SDH、POS简介
- 《武魂》物理引擎特效全解析
- psd 将分组合并导出png图片
- Transmitting Network Data Using Volley(使用Volley框架传输网络数据)
- HTML5+CSS3小实例:自定义滤镜实现液体加载动画
- 1、使用类与接口的知识完成如下要求:(1)定义一个接口CanFly,描述会飞的方法public void fly();(2)分别定义类飞机和鸟,实现CanFly接口。(3)定义一个测试类,测试飞
- 【图文并茂】Win7在线一键重装系统教程
- HP Sprinter:敏捷加速器
热门文章
- html设置花样的分界线,CSS秘密花园: 花式的符号
- 小程序解码/富文本解析
- 基于android写字机器人,抄作业神器?模仿手写的写字小机器人Line-us!
- python回溯算法_回溯算法经典问题及python代码实现
- Antlr 4语法与空格
- MAC下 ant 环境搭建
- 算法设计手冊(第2版)读书笔记, Springer - The Algorithm Design Manual, 2ed Steven S.Skiena 2008...
- 仿人型手腕 6R机械臂 D-H参数和运动学逆解
- origin如何调整图例为2行
- 【单片机笔记】中颖单片机开发笔记