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 ...
随机推荐
- 项目中BigDecimal与Double使用场景
金额要用BigDecimal 金额计算不能用doube!!!! 金额计算必须用BigDecimal,下面对比一下用double 跟BigDecimal的区别.先看一个小例子: 请看题: 示例1 问, ...
- js改变dom对象样式
object.style.display = value; objcet对象必须是确定单个对象. 若以class名和标签名查找,需要指定对象集合中的第几个.
- vue+node.js+webpack开发微信公众号功能填坑——v -for循环
页面整体框架实现,实现小功能,循环出数据,整体代码是上一篇 vue+node.js+webpack开发微信公众号功能填坑--组件按需引入 修改部门代码 app.vue <yd-flexbox&g ...
- python学习之路网络编程篇(第三篇)
python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...
- python笔记八(切片)
一.切片 首先我们要记得在Python中可以用于切片的对象有 列表.元组.字符串. 切片操作就是直接从列表.元组或字符串中,选择出我们想要的内容,这些操作非常简洁实用. >>> L ...
- 使用FFMPEG在windows平台下推rtmp流
使用FFMPEG在windows平台下推rtmp流 工作中习惯在Linux下面使用FFmpeg模拟推rtmp流,无奈家中的电脑都是windows系统,需要利用家中的带宽来测试流媒体服务器的性能.所以研 ...
- ionic tab页面跳转
要使用到Tabs,现将Tabs导入 import { NavController, ModalController, Tabs } from 'ionic-angular'; 把要选择的Tabs页面的 ...
- 硬盘存储计量单位KB、MB、GB大小换算
一. 预备知识 1. bit与byte 1. bit(简记为 b) 1 bit = 0 or 1 = one binary 2. byte(简记为 B) 1 byte = 8 bits 1字节,8个二 ...
- 记一次MySQL删库的数据恢复
昨天因为不可描述的原因,数据库直接被 drop database删除.在第一时间停止数据库服务和Web服务,备份MySQL数据目录下的所有文件之后,开始走上数据恢复之路. 第一次干这种事,各种不得法. ...
- 解决使用BottomSheetDialog时状态栏变黑的问题
问题描述 当使用support里的design 库里的BottomSheetDialog时,在6.0的机器上当对话框弹出时系统状态栏会变黑,如下图所示: 一开始以为是我用的姿势不对,试过对style配 ...