博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(译)如何使用cocos2d制作一个塔防游戏:第四部分(完)
阅读量:5200 次
发布时间:2019-06-13

本文共 4152 字,大约阅读时间需要 13 分钟。

原文链接地址:

教程截图:

  这部分教程,我们将实现我们刚开始所讨论的完整的塔防游戏。这是本系列教程的第四部分,也是最后一部分,在继续阅读之前,建议你先查看前3个教程,可以从开始。

  今天,我们将学习到新的东西--“让炮塔开火!”。这是塔防游戏中最重要的组成部分,也是本程序中最有意思的部分。我当然不可能在这个教程中覆盖塔防游戏中所有好玩的东西,但是,我保证我们会在不将的将来创建各式各样的tower。我想,在学习完这个系列教程之后,你自己也可以制作出非常好玩的塔防游戏。我会尽量让代码的robust性更好的!

  这里有本教程的。

   首先,我们需要做的就是创建实际的子弹(projectile)--projectile类目前有一点点简单,它里面什么也没有,但是,不代表它将来也没有内容。

Projectile.h

#import
"
cocos2d.h
"
@interface Projectile : CCSprite {
}
+
(id)projectile;
@end

Projectile.m

#import
"
Projectile.h
"
@implementation Projectile
+
(id)projectile {
Projectile
*
projectile
=
nil;
if
((projectile
=
[[[super alloc] initWithFile:
@"
Projectile.png
"
] autorelease])) {
}
return
projectile;
}
-
(
void
) dealloc
{
[super dealloc];
}
@end

  我们现在添加新的方法到update函数中,此函数在TowerScene中。那里面处理当前的子弹和creep的碰撞检测。这个基本的逻辑很简单:

  1.遍历所有的projectiles

  2.对于每一个projectiles,遍历所有的targets

  3.看projectile的边界是否和target的边界有交叉

  4.如果交叉了,减少creep的生命值,同时把projectile加到一个即将被删除的数组 projectilesToDelete里面去

  5.如果creep的生命值==0,那么就把它加到targetToDelete数组里面。

  具体代码如下:(其实这段代码和Ray的教程《如何使用cocos2d制作一个简单的iphone游戏》里面的忍者发射飞盘一样的)

-
(
void
)update:(ccTime)dt {
DataModel
*
m
=
[DataModel getModel];
NSMutableArray
*
projectilesToDelete
=
[[NSMutableArray alloc] init];
for
(Projectile
*
projectile
in
m._projectiles) {
CGRect projectileRect
=
CGRectMake(projectile.position.x
-
(projectile.contentSize.width
/
2
),
projectile.position.y
-
(projectile.contentSize.height
/
2
),
projectile.contentSize.width,
projectile.contentSize.height);
NSMutableArray
*
targetsToDelete
=
[[NSMutableArray alloc] init];
for
(CCSprite
*
target
in
m._targets) {
CGRect targetRect
=
CGRectMake(target.position.x
-
(target.contentSize.width
/
2
),
target.position.y
-
(target.contentSize.height
/
2
),
target.contentSize.width,
target.contentSize.height);
if
(CGRectIntersectsRect(projectileRect, targetRect)) {
[projectilesToDelete addObject:projectile];
Creep
*
creep
=
(Creep
*
)target;
creep.hp
--
;
if
(creep.hp
<=
0
) {
[targetsToDelete addObject:target];
}
break
;
}
}
for
(CCSprite
*
target
in
targetsToDelete) {
[m._targets removeObject:target];
[self removeChild:target cleanup:YES];
}
[targetsToDelete release];
}
for
(CCSprite
*
projectile
in
projectilesToDelete) {
[m._projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];
}

  最后,我们回到tower代码,看看我们是怎么处理开火机制的。在towerLogic代码里面,我们在RotateTo action之后再添加了一个action,叫做CCCallFunc。它会触发一个finishFiring方法。

[self runAction:[CCSequence actions:
[CCRotateTo actionWithDuration:rotateDuration angle:cocosAngle],
[CCCallFunc actionWithTarget:self selector:@selector(finishFiring)],
nil]];

   finishFiring只是在我们知道tower朝着正确的方向的时候才开火。它主要是创建一个新的子弹,然后把它加到DataModel的projectile数组中,同时给它一个位置和目的点。

-
(
void
)finishFiring {
DataModel
*
m
=
[DataModel getModel];
self.nextProjectile
=
[Projectile projectile];
self.nextProjectile.position
=
self.position;
[self.parent addChild:self.nextProjectile z:
1
];
[m._projectiles addObject:self.nextProjectile];
ccTime delta
=
1.0
;
CGPoint shootVector
=
ccpSub(self.target.position, self.position);
CGPoint normalizedShootVector
=
ccpNormalize(shootVector);
CGPoint overshotVector
=
ccpMult(normalizedShootVector,
320
);
CGPoint offscreenPoint
=
ccpAdd(self.position, overshotVector);
[self.nextProjectile runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:delta position:offscreenPoint],
[CCCallFuncN actionWithTarget:self selector:@selector(creepMoveFinished:)],
nil]];
self.nextProjectile.tag
=
2
;
self.nextProjectile
=
nil;
}

  你可以看到上面的代码,我们在projectile上面运行另一个CCMoveTo action,使之朝一个特定的方向移动。这样就会使得看起来是tower在发射子弹,但是,现在默认的距离是320.一旦子弹到达目的地后, "creepMoveFinished"方法就会被调用,它会从DataModel projectile数组中把这个projectile移除掉,并且把它从舞台中剔除。

-
(
void
)creepMoveFinished:(id)sender {
DataModel
*
m
=
[DataModel getModel];
CCSprite
*
sprite
=
(CCSprite
*
)sender;
[self.parent removeChild:sprite cleanup:YES];
[m._projectiles removeObject:sprite];
}

  恩,就这些了,编译并运行,你现在可以旋转炮塔了,而且它们可以攻击被杀死creep了。很酷吧?其实,我们的工作还没有完成,我们其实还需要添加一些塔的威力,还需要一个买卖系统,同时还要一个波数控制系统(可以控制当前波的速度快慢,总共多少波数等问题)。很多事情要做,不过我们已经上路了。。。

  继续完善吧!

 

著作权声明:本文由翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

转载于:https://www.cnblogs.com/zilongshanren/archive/2011/07/10/2102416.html

你可能感兴趣的文章
matlab求解三次条样插值
查看>>
powerdesigner的逆向工程
查看>>
JMeter学习(四)参数化
查看>>
Spring实战(十二) Spring中注入AspectJ切面
查看>>
数据结构(五) 查找和哈希表
查看>>
Java Base64 加密/解密
查看>>
queue队列
查看>>
HDU 2602 Bone Collector
查看>>
linux 安装mysql5.7.25
查看>>
Deep Learning 学习笔记(4):Logistic Regression 逻辑回归
查看>>
云计算为ERP的应用带来新机遇
查看>>
LintCode-372.在O(1)时间复杂度删除链表节点
查看>>
【BZOJ1088】[SCOI2005] 扫雷Mine(分类讨论)
查看>>
1222: FJ的字符串 [水题]
查看>>
制作IPL
查看>>
django中同通过getlist() 接收页面form的post数组
查看>>
一劳永逸解决PPT中声音视频的路径问题(转)
查看>>
.net 调用java的WSDL
查看>>
C++中一个Vector和动态数组的经典例子
查看>>
bzoj1406: [AHOI2007]密码箱
查看>>