如何使用kobold2d来做一个简单的iphone游戏教程(第四部分)
来源:互联网 发布:js鼠标滚轮控制滚动条 编辑:程序博客网 时间:2024/04/29 19:54
免责声明:本系列教程是根据该系列教程实践过程所作的自己使用kobold2D框架经历。仅供学习与交流使用,请勿进行商业传播,转载时不要移除本声明。如果产生任何纠纷均与博客所有者无关。欢迎转载。
作者:Rush.xzj
本篇文章的目标:1.炮台发射子弹
2.炮台可以旋转
3.子弹可以消灭怪物
子弹:
在这里,我们的炮台需要有一些行动了--因此让我们增加一些射击吧!这里有许许多多实现射击的方式,但是在这个游戏里面,我们想让用户触摸一下屏幕,然后子弹就会从player开始,沿着你触摸的位置发射出来。
发射子弹
我们使用CCMoveTo action来实现这个功能。但是,为了使用这个功能,我们必须首先来做一些数学题。这是因为,CCMoveTo需要我们为子弹指定目的地。但是我们又不能使用触摸点,因为触摸点仅仅代表飞盘飞的方向。我们实际上想让子弹超过触摸点,然后飞出屏幕之外去。
下面这张图解释了这个问题:
因此,就像你看到的,在触摸点和player之间有一个小的三角形,由origin点,offx和offy组成。我们只需要画一个更大的三角形,同时使用一样的比率就行了。然后我们就可以根据比例算出飞盘飞出屏幕的位置。
为了能让屏幕能响应触摸事件,在init函数中添加如下代码:
//可以接受触摸消息 self.isTouchEnabled = YES;
因为我们已经设置Layer的isTouchEnabled的属性为YES,所以我们要在H恶劣咯HelloWorldLayer.m中实现ccTouchesEnded方法,为了让用户点击一次的时候可以调用:
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; //添加子弹到屏幕,子弹对应的图片文件名称:Projectile2.png" CCSprite *projectile = [CCSprite spriteWithFile:@"Projectile2.png"]; projectile.position = player.position; [self addChild:projectile]; //屏幕大小 CGSize winSize = [[CCDirector sharedDirector] winSize]; float maxWinSizeLength = winSize.height > winSize.width ? winSize.height : winSize.width; //发射坐标 CGPoint startPoint = player.position; //点击坐标,点触的屏幕坐标到当前屏幕的坐标转换,必须要是同一个坐标系 //对于home键在右侧(也就是当前游戏的横版模式),坐标原点在左下角,向上是Y正值,向左是X正值 //对于home健在下面(正常iphone的位置),坐标原点在左上角,想下是Y正值,想左是X正值,touch的坐标是此坐标系 //也许这里有更好的解决方案直接就可以得到touch在屏幕的坐标 CGPoint touchPoint2 = [touch locationInView:[touch view]]; CGPoint touchPoint; touchPoint.x = touchPoint2.y; touchPoint.y = touchPoint2.x; //计算射击的向量 CGPoint shootVector = ccpSub(touchPoint, startPoint); //向量的单位化 CGPoint normalizedShootVector = ccpNormalize(shootVector); //延长线,足够长 CGPoint overshootVector = ccpMult(normalizedShootVector, maxWinSizeLength); //计算终点的坐标 CGPoint endPoint = ccpAdd(startPoint, overshootVector); //设置子弹多长时间移动完 ccTime delta = 1.0; CCMoveTo *moveTo = [CCMoveTo actionWithDuration:delta position:endPoint]; CCCallFuncN *callFuncN = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)]; CCSequence *sequence = [CCSequence actions:moveTo, callFuncN, nil]; [projectile runAction:sequence];}
因为在子弹是从炮台的位置发射的,所以我们需要获取炮台的相关信息,可以把炮台的Sprite设置成一个属性,修改如下
首先在HelloWorldLayer.h中
添加
CCSprite *player;
然后添加属性:
@property (nonatomic, strong) CCSprite *player;
在HelloWorldLayer.m中添加:
@synthesize player;
修改init方法中:
CSprite *player = [CCSprite spriteWithFile:@"player2.png"];
更改成:
player = [CCSprite spriteWithFile:@"player2.png"];
也就是一句话,把CSprite *player换成属性
炮台旋转
现在子弹已经可以发射了,但是炮台还不可以旋转,这个给人的感觉很不好,现在我们就来添加炮台旋转
炮台旋转和发射子弹的逻辑顺序:
1.先旋转炮台,2.添加子弹3,子弹移动
所以先把子弹
CCSprite *projectile = [CCSprite spriteWithFile:@"Projectile2.png"];
提取成属性projectile,以下是修改后的代码:
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //防止点击过快 if(projectile != nil) return; UITouch *touch = [touches anyObject]; //添加子弹到屏幕,子弹对应的图片文件名称:Projectile2.png" projectile = [CCSprite spriteWithFile:@"Projectile2.png"]; projectile.position = player.position; //[self addChild:projectile]; //屏幕大小 CGSize winSize = [[CCDirector sharedDirector] winSize]; float maxWinSizeLength = winSize.height > winSize.width ? winSize.height : winSize.width; //发射坐标 CGPoint startPoint = player.position; //点击坐标,点触的屏幕坐标到当前屏幕的坐标转换,必须要是同一个坐标系 //对于home键在右侧(也就是当前游戏的横版模式),坐标原点在左下角,向上是Y正值,向左是X正值 //对于home健在下面(正常iphone的位置),坐标原点在左上角,想下是Y正值,想左是X正值,touch的坐标是此坐标系 //也许这里有更好的解决方案直接就可以得到touch在屏幕的坐标 CGPoint touchPoint2 = [touch locationInView:[touch view]]; CGPoint touchPoint; touchPoint.x = touchPoint2.y; touchPoint.y = touchPoint2.x; //计算射击的向量 CGPoint shootVector = ccpSub(touchPoint, startPoint); //向量的单位化 CGPoint normalizedShootVector = ccpNormalize(shootVector); //延长线,足够长 CGPoint overshootVector = ccpMult(normalizedShootVector, maxWinSizeLength); //计算终点的坐标 CGPoint endPoint = ccpAdd(startPoint, overshootVector); //计算旋转角度 CGFloat shootAngle = ccpToAngle(shootVector); //弧度值转换为角度值,cocos2D是用角度值进行计算的 //关于角度的计算和为什么* -1 请参照: //http://www.cnblogs.com/andyque/articles/1997820.html CGFloat cocosAngle = CC_RADIANS_TO_DEGREES(-1 * shootAngle); CGFloat curAngle = player.rotation; CGFloat rotationDiff = cocosAngle - curAngle; if(rotationDiff > 180) rotationDiff -= 360; if(rotationDiff < -180) rotationDiff += 360; CGFloat rotationSpeed = 0.5 / 180; CGFloat rotationduration = fabs(rotationDiff * rotationSpeed); //设置炮台的旋转动作 CCRotateTo *rotateTo = [CCRotateTo actionWithDuration:rotationduration angle:cocosAngle]; CCCallFunc *callFunc = [CCCallFunc actionWithTarget:self selector:@selector(finishShoot)]; CCSequence *playSequence = [CCSequence actions:rotateTo, callFunc, nil]; [player runAction:playSequence]; //设置子弹多长时间移动完 ccTime delta = 1.0; CCMoveTo *moveTo = [CCMoveTo actionWithDuration:delta position:endPoint]; CCCallFuncN *callFuncN = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)]; CCSequence *projectileSequence = [CCSequence actions:moveTo, callFuncN, nil]; [projectile runAction:projectileSequence];}当炮台旋转完成后:需要一个回调函数finishShoot:
-(void)finishShoot { [self addChild:projectile]; projectile = nil;}
运行就可以看见,发射子弹的时候,炮台也开始旋转了
到此为止,本篇教程就结束了。
该篇主要是介绍了旋转炮台和发射子弹。敬请期待下一篇文章!
- 如何使用kobold2d来做一个简单的iphone游戏教程(第四部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第一部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第二部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第三部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第五部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第六部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第七部分)
- 如何使用kobold2d来做一个简单的iphone游戏教程(第八部分)
- 2.如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- 如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- (译)如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- 如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- (译)如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- (译)如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- 如何使用cocos2d-x 3.0来做一个简单的iphone游戏教程(第一部分)
- 【Cocos2D游戏引擎教程】如何使用Cocos2D制作一款简单的iPhone游戏(第二部分)
- 3 .如何使用cocos2d开发一个简单的iphone游戏:旋转炮塔(第二部分)
- (译)如何使用cocos2d开发一个简单的iphone游戏:旋转炮塔。(第二部分)
- Activemqcpp 在接收设置了TTL的消息时候,出现receive timeout接收不到消息的问题
- 数据库怪异事件探源之PreparedStatement
- 批量删除索引、约束、列
- 持续集成的概念(摘自张辰雪《持续集成实践 之 CruiseControl》)
- discuz数据表结构
- 如何使用kobold2d来做一个简单的iphone游戏教程(第四部分)
- JUnit in Action Note Taking (2nd)
- 让调试利器zend debugger与zend Optimizer共存,和谐!
- DB2 建索引SQL
- c++ const函数精解(国外大学的教程就是透彻)
- C++ Tutorial: Enhance Type Safety and Code Clarity with the nullptr Keyword
- Zend Debugger安装
- myeclipse 配置多个tomcat
- 如何查看进程 IO 读写情况?