(NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;)
通用的星星类已经完成了,下面我们来实现具体的变长和缩短道具.
变长的反弹棒
我们想实现如下功能:在掉落变长星之后,如果反弹棒接到它,则使反弹棒的长度变为原先的2倍.
看似很简单,但实际有一个问题.你不能仅仅延长反弹棒精灵纹理的长度,因为你在这个游戏中使用的是物理引擎,反弹棒的物理对象的大小是不可以在游戏运行中随意变化的.
所以我们需要想办法延长反弹棒的物理大小,当然同时也要延长其精灵帧的大小,这样才能相互配合达到逼真的延长效果.
这里本猫使用偷梁换柱的方法,用Ai制作一个延长后的反弹棒,并调整它的物理对象适应新的长度,然后在反弹棒需要变长时,用新长棒代替原来的短棒.
首先用Ai制作一个长的反弹棒.然后在SpriteBuilder中创建一个StickLonger.ccb文件,设置好其物理对象的边界:
实现变长星道具
回到Xcode中,在Stick类的接口文件中添加一个新属性:
+(instancetype)stickLonger;
在Stick.m中实现该类方法:
+(instancetype)stickLonger{
Stick *stick = (Stick*)[CCBReader load:@"Elements/StickLonger"];
stick.name = @"stickLonger";
return stick;
}
可以看到除了stick对象发生了变化,其名称也和普通的stick有所区别.
回到GameScene.m中在小球与砖块的碰撞处理中添加以下一句:
[Star spawnStar:(Brick*)brick];
接着我们要处理星星和反弹棒接触时的事件:
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair star:(CCNode *)star
stick:(CCNode *)stick{
//star形状是五角星,可能会在短时间内多次发生碰撞;但在star已经由第一次碰撞时删除掉从而导致star为nil
//所以这里要确保star不为nil.
//star删除也不能保证其一定为nil,所以增加判断其parent是否为nil.(2015-11-09 2006)
StarType starType;
@synchronized(self){
if (!star || !star.parent) {
return YES;
}
starType = ((Star*)star).starType;
[star removeFromParentAndCleanup:YES];
}
switch (starType) {
case starTypeStickLonger:
@synchronized(self){
[self scheduleBlock:^(CCTimer *timer){
[Star doStickLongerWork:self.stickInGameScene];
} delay:0];
}
break;
case starTypeUnknown:
case starTypeMax:
NSAssert(NO, @"error star type!");
break;
default:
break;
}
return YES;
}
为什么其中使用了同步伪指令呢?因为其中的代码会改变GameScene中反弹棒的状态,而该状态在GameScene中也可能同时被改变,所以我们需要将其做同步处理.
扩展Star类
最后我们在Star类中添加doStickLongerWork方法:
+(void)doStickLongerWork:(Stick *)stick{
GameScene *gameScene = [GameScene sharedGameScene];
CCPhysicsNode *physicsWorld = (CCPhysicsNode*)stick.parent;
@synchronized(gameScene){
if ([stick.name isEqualToString:@"stickLonger"]) {
return;
}
if ([stick.name isEqualToString:@"stickShorter"]) {
Stick *stickNormal = [Stick stickNormal];
stickNormal.position = stick.position;
[stick removeFromParent];
//[physicsWorld removeChild:stick cleanup:YES];
[physicsWorld addChild:stickNormal];
gameScene.stickInGameScene = stickNormal;
return;
}
}
CGPoint position = stick.position;
__block Stick *stickLonger;
@synchronized(gameScene){
stickLonger = [Stick stickLonger];
//[physicsWorld removeChild:stick cleanup:YES];
[stick removeFromParent];
stickLonger.position = position;
[physicsWorld addChild:stickLonger];
stickLonger.visible = NO;
gameScene.stickInGameScene = stickLonger;
CCSprite *stickNode = (CCSprite*)[CCBReader load:@"Elements/StickNode"];
stickNode.position = stickLonger.position;
[gameScene addChild:stickNode z:50];
CCActionScaleTo *longerAction = [CCActionScaleTo actionWithDuration:0.4f scaleX:2.0f scaleY:1.0f];
CCActionCallBlock *blk = [CCActionCallBlock actionWithBlock:^{
[stickNode removeFromParent];
stickLonger.visible = YES;
}];
CCActionSequence *seq = [CCActionSequence actions:longerAction,blk,nil];
[stickNode runAction:seq];
}
[stickLonger scheduleBlock:^(CCTimer *timer){
@synchronized(gameScene){
Stick *stickNormal = [Stick stickNormal];
stickNormal.position = stickLonger.position;
[stickLonger removeFromParent];
[physicsWorld addChild:stickNormal];
gameScene.stickInGameScene = stickNormal;
}
} delay:10];
}
你看到以上方法的第一感觉估计是:好长啊!其实内容很好理解,基本上它做了如下几件事:
- 如果反弹棒已经变长了,则啥也不做返回
- 如果反弹棒处在变短状态,则恢复其原本大小.这里考虑到了其他可能改变反弹棒的叠加效果.在反弹棒变短的代码逻辑中,我们同样会考虑到这一点.
- 创建一个变长的反弹棒对象,但暂时将其隐藏,因为我们还想实现一个反弹棒由短变长的动画效果.因为这个动画很短,所以不会影响用户的操控.如果你希望更完美的实现用户操控的连续性,你可以将反弹棒的触摸处理临时”嫁接”到这个临时对象上,当然是有点麻烦,篇幅原因,这里只是点到为止.
- 在10秒之后将反弹棒恢复为原来大小
变长道具制作完毕,我们现在编译运行app,看一下效果:
下一篇将来完成缩小的道具星,see you ;)
(NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!的更多相关文章
- (NO.00004)iOS实现打砖块游戏(十五):导弹发射道具的实现(上)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇中我们实现了3球道具,但是好像还是不过瘾,如果能让反弹棒更 ...
- (NO.00004)iOS实现打砖块游戏(十六):导弹发射道具的实现(下)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们完成了导弹道具相关的道具制作,本篇中我们来完成其实现 ...
- (NO.00004)iOS实现打砖块游戏(十四):3球道具的实现
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 反弹棒变化道具实现前面已经介绍过了,我们下面可以在小球上做些文章 ...
- (NO.00004)iOS实现打砖块游戏(十三):伸缩自如,我是如意金箍棒(下)!
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 准备缩短反弹棒素材 和上一篇类似,我们如法炮制一张缩短后反弹棒的 ...
- (NO.00004)iOS实现打砖块游戏(十):砖块!更多的砖块!
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 到目前为止游戏基本可玩,但是砖块数量是不变的,等玩家打光所有的砖 ...
- 《剑指offer》第三十二题(分行从上到下打印二叉树)
// 面试题32(二):分行从上到下打印二叉树 // 题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层 // 打印到一行. #include <cstdio> #in ...
- (NO.00004)iOS实现打砖块游戏(二):实现游戏主界面动画
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个内容不错的游戏也要一个好的包装.玩家进入游戏时第一眼看到的是 ...
- IOS基础之 (十二) Block
一 定义 Block封装了一段代码,可以在任何时候执行. Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值. 二 使用 1. 定义函数指针,然后在实现. #import & ...
- 从零开始学ios开发(十二):Table Views(上)
这次学习的控件非常重要且非常强大,是ios应用中使用率非常高的一个控件,可以说几乎每个app都会使用到它,它就是功能异常强大的Table Views.可以打开你的iphone中的phone.Messa ...
随机推荐
- PTA 邻接表存储图的广度优先遍历(20 分)
6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...
- 读书笔记-《Maven实战》-2018/4/17
第五章 坐标和依赖 1.如同笛卡尔坐标系一样,Maven也通过坐标三元素定位一个资源. <groupId>com.dengchengchao.test</groupId> &l ...
- 【问底】徐汉彬:亿级Web系统搭建——单机到分布式集群
http://www.csdn.net/article/2014-11-06/2822529/3 大规模流量的网站架构,从来都是慢慢"成长"而来.而这个过程中,会遇到很多问题,在不 ...
- Mysql数据库连接报错!1130:host XXX is not allowed to connect to this mysql server
我猜想是可能是连接的用户权限问题.结果这样子操作mysql库,可以解决此问题.在本机登入mysql后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost” ...
- 在OpenCV3.1.0中使用SIFT,SURF算法
写在前边: 1.我使用的是python2.7 + OpenCV3.1.0 2.OpenCV3.0.0+的文档有很大问题,很多文档写的还是OpenCV2.0+, OpenCV3.0+根本用不了,其中有一 ...
- 剑指架构师系列-Logstash分布式系统的日志监控
Logstash主要做由三部署组成: Collect:数据输入 Enrich:数据加工,如过滤,改写等 Transport:数据输出 下面来安装一下: wget https://download.el ...
- block的那些事(从懵懂到使用)
从大学开始自学iOS,在iOS岗位已经两年了,遇到传值等操作,代理和block二选一的话,以前我会毫不犹豫选择代理.久而久之,入职到大公司之后,发现处处是block的天地,才慢慢的了解block并爱上 ...
- EntityFramework Core 自动绑定模型映射
笔者最近在和同事共同开发项目时,需要从他们提供的包含数据库实体类型的类库中读取实体信息绑定到自己的项目中(但是都在同一个解决方案里),所以很直接的一种方式就是把项目中所有的实体都以 public Db ...
- 在Windows cmd中计算行数
本文主体来自这篇外文文章的翻译.原文中有一个副标题:"如何简单地用Windows自带的FIND在CMD.exe中计算行数" 当我们在命令行环境中工作时,能计算其它工具输出内容的行数 ...
- ubuntu日志文件管理
众所周知,ubuntu的日志文件会越来越大,需要定期管理 logrotate是个十分有用的工具,它可以自动对日志进行截断(或轮循).压缩以及删除旧的日志文件.例如,你可以设置logrotate,让/v ...