Cocos2D旋转炮塔到指定角度(三)
到目前为止都很美好!
但是却有一点奇怪,因为炮塔一下子跳转到指定位置去射击,并不是平滑的跟随触摸去转动到指定位置.你可以修复这个问题,但是这需要略微一点的重构(refactoring).
首先打开HelloWorldLayer.h,在你的类中添加下面一个实例变量:
CCSprite *_nextProjectile;
然后回到HelloWorldLayer.m中按如下代码修改ccTouchesEnded方法:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (_nextProjectile != nil) return;
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace:touch];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
_nextProjectile = [[CCSprite spriteWithFile:@"projectile2.png"] retain];
_nextProjectile.position = ccp(20, winSize.height/2);
// Determine offset of location to projectile
CGPoint offset = ccpSub(location, _nextProjectile.position);
// Bail out if you are shooting down or backwards
if (offset.x <= 0) return;
// Determine where you wish to shoot the projectile to
int realX = winSize.width + (_nextProjectile.contentSize.width/2);
float ratio = (float) offset.y / (float) offset.x;
int realY = (realX * ratio) + _nextProjectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far you're shooting
int offRealX = realX - _nextProjectile.position.x;
int offRealY = realY - _nextProjectile.position.y;
float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Determine angle to face
float angleRadians = atanf((float)offRealY / (float)offRealX);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = -1 * angleDegrees;
float rotateDegreesPerSecond = 180 / 0.5; // Would take 0.5 seconds to rotate 180 degrees, or half a circle
float degreesDiff = _player.rotation - cocosAngle;
float rotateDuration = fabs(degreesDiff / rotateDegreesPerSecond);
[_player runAction:
[CCSequence actions:
[CCRotateTo actionWithDuration:rotateDuration angle:cocosAngle],
[CCCallBlock actionWithBlock:^{
// OK to add now - rotation is finished!
[self addChild:_nextProjectile];
[_projectiles addObject:_nextProjectile];
// Release
[_nextProjectile release];
_nextProjectile = nil;
}],
nil]];
// Move projectile to actual endpoint
[_nextProjectile runAction:
[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallBlockN actionWithBlock:^(CCNode *node) {
[_projectiles removeObject:node];
[node removeFromParentAndCleanup:YES];
}],
nil]];
_nextProjectile.tag = 2;
[[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"];
}
看起来代码不少,但是实际你并没有修改太多,大多数都仅仅是很小的重构,以下是代码做出的改变:
- 在方法开始处如果_nextProjectile不为nil则直接退出,意思是你正在处理射击操作
- 之前你使用的是一个名为projectile的局部变量,然后立即把它添加到场景中.在新的版本中你创建了一个实例变量_nextProjectile,但是没有立即添加到场景中.
- 你定义了炮塔旋转的速度为180 / 0.5,意味着半秒钟旋转180度.
- 去计算旋转特定的角度需要多长时间
- 然后开始一个顺序action去旋转炮塔到正确的角度,然后调用一个block去将导弹添加到场景中.
偶鸟,试一试吧!编译运行项目,然后现在炮塔应该旋转的平滑多了 ;)
原文地址:Rotating Turrets: How To Make A Simple iPhone Game with Cocos2D 2.X Part 2
Cocos2D旋转炮塔到指定角度(三)的更多相关文章
- Cocos2D旋转炮塔到指定角度(一)
原文地址:Rotating Turrets: How To Make A Simple iPhone Game with Cocos2D 2.X Part 2 翻译有节选和删除. 在你旋转炮塔之前,首 ...
- Cocos2D旋转炮塔到指定角度(二)
增加如下代码到ccTouchesEnded方法中,就在你在导弹精灵上调用runAction之前: // Determine angle to face float angleRadians = ata ...
- 【Cocos2d入门教程七】三分钟看懂Cocos2d坐标系
无论是搞2d还是3d开发,最需要搞清楚的就是坐标系,这部分混乱的话就没啥搞头了.所以玩cocos2d,一上来就需要先把各种与坐标有关的东西搞清楚. 1.OpenGL坐标系 Cocos2d-x使用的是O ...
- 使用cmd查看电脑连接过的wifi密码并将密码发送至指定邮箱(三)
之前,我写了使用cmd查看电脑连接过的wifi密码(二)和使用cmd查看电脑连接过的wifi密码(一)但其中的功能不完善,在本次的更新中新增了更多的功能,其实2018/10/24 就更新完成了,一直拖 ...
- osg指定向量旋转指定角度
向量AB,沿着n旋转10度 osg::Vec3 left = AB*osg::Matrix::rotate(osg::inDegrees(10), n); osg::Vec3 right = AB*o ...
- python入门学习笔记(三)
10.函数 求绝对值的函数 abs(x) 也可以在交互式命令行通过 help(abs) 查看abs函数的帮助信息.调用 abs 函数:>>> abs(100)100>>& ...
- 用MATLAB绘制折线图,x轴为字符串,并旋转一定的角度!!!
先上代码,然后再一行一行解释: x=1:37; %这一行其实一开始,写的时候是没有的,后来需要给X轴上规定几个刻度才加上的 plot(x,Y,'linewidth',2); %以x为自变量,y为因变量 ...
- mysql中影响myisam引擎写入性能的三项设置
一.LOW_PRIORITY1.对于myisam默认是写操作优先,读操作滞后.通过该项更改,可以使读操作优先,写操作在有空闲的时候再写入.但该项可能在理论上造成,写被永远阻塞. SQL语句中使用示例: ...
- C#GDI+基础(三)画刷详解
SolidBrush:一般的画刷,通常只用一种颜色去填充GDI+图形 创建一般画刷: SolidBrush sbBrush1 = new SolidBrush(Color.Green); HatchB ...
随机推荐
- 开发网页时,127.0.0.1或者localhost能访问,而本机地址不能访问的解决
第一 ping试试 127.0.0.1 和 本机地址 若127.0.0.1可以 说明可以自己ping自己 若本机地址可以 说明host正常 第二 检查服务器部署 再部署一个新的 若新的正常 说明你项目 ...
- 深入理解final关键字
在了解了final关键字的基本用法之后,这一节我们来看一下final关键字容易混淆的地方. 1.类的final变量和普通变量有什么区别? 当用final作用于类的成员变量时,成员变量(注意是类的成员变 ...
- 在移动端画出真正的1px边框
一.问题 写H5的样式时候,设置元素的边框为1px,不幸的事情在IOS设备上发生了,设计师会说,咦,边框怎么那么大,这是2px了吧?改成1px.我明明设置成1px了啊. 二.为什么边框变粗了? ...
- SQL执行SQL语句提示 "内存不足"(insufficient memory....)的解决方法
由于本地执行的sql script的文件太大但是本地sql的运行内存有限,当我在MSSql的工具上运行这份178M左右的脚本的时候 它会提示 如下错误(Insufficient memory to c ...
- SUSE10的虚拟机安装以及ORACLE 11g的安装
SUSE10虚拟机安装与ORACLE安装 作者:张欣橙 本文所需要的所有参数均位于文末附录中 一.SUSE10虚拟机的安装与创建 新建虚拟机安装 选择下一步 选择下一步 选择下一步 选择下一步 选择下 ...
- Linux完全卸载Oracle的操作步骤
卸载步骤如下:1.运行$ORACLE_HOME/bin/localconfig delete2.rm -rf $ORACLE_BASE/*3.rm -f /etc/oraInst.loc etc/or ...
- 03_OGNL
1.值栈: 解答Struts能够直接获取属性值: 原因:Struts并不是直接通过request隐式对象中获取,而是将整个对象封装到了ValueStack值栈中,直接匹配是否存在这个属性,找到了就取出 ...
- 小白到大神,Python 密集知识点汇总
Python 基础 1. 变量 你可以把变量想象成一个用来存储值的单词.我们看个例子. Python 中定义一个变量并为它赋值是很容易的.假如你想存储数字 1 到变量 "one" ...
- Android开发学习之路--性能优化之布局优化
Android性能优化方面也有很多文章了,这里就做一个总结,从原理到方法,工具等做一个简单的了解,从而可以慢慢地改变编码风格,从而提高性能. 一.Android系统是如何处理UI组件的更新操作的 ...
- Windows下Java调用BAT批处理不弹出cmd窗口
常规Windows下Java调用BAT方式肯定会弹出cmd窗口 Runtime.getRuntime().exec("cmd.exe /C start D:\\test.bat") ...