这篇教程是Ray Wenderlich的《如何使用cocos2d制作基于tiled地图的游戏》系列教程的后续。如果你还没有看过前面两部分的教程,可以在我的博客上找到另外两篇我翻译Ray的教程。
在第二部分教程中,Ray教大家如何在地图中制作可碰撞的区域,如何使用tile属性,如何制作可以拾取的物品以及如何动态修改地图、如何使用“Heads up display”来显示分数。
在这个教程中,我们将加入敌人,这样的话,你的忍者就可以向它们扔飞镖啦,同时还增加了胜利和失败的游戏逻辑。但是,首先,你得下载一些相关的资源文件。
这个zip文件里面包含以下内容:
1.一个敌人精灵
2.一个忍者飞镖,从Ray的《如何使用cocos2d制作一个简单的iphone游戏》中拿过来的。
3.两张按钮的图片,在教程的后面有使用。
在继续学习之前,不要忘了把这些资源加入到你的工程中。
增加敌人
到第二部分教程结束的时候,游戏已经很酷了,但是它还不是一个完整的游戏。你的忍者可以轻而易举地四处游荡,想吃就吃。但是,什么时候玩家会胜利或者失败呢。我们不妨想象一下,有2个敌人在追杀你的忍者,那么这个游戏会显得更加有趣。
敌人出现的位置点
好了,回到Tiled软件(此教程使用java版),然后打开你的Tile地图(TileMap.tmx)。
往对象层中加入一个对象,在player附近就行,但是不要太近,否则敌人一出现玩家就Game over了。这个位置将成为敌人出现的位置点,把它命名为“EnemySpawn1”。
对象组(对象层中的所有对象组成一个对象组)中的对象被存储在一个NSMutableDictionary中,同时使用对象名字作为key。这意味着每一个位置点必须有一个唯一的名字。尽管我们可以遍历所有的key来比较哪个是以“EnemySpawn”开头,但是这样做效率很低下。相反,我们采用的做法是,使用一个属性来表示,每个给定的对象代表一个敌人出现的位置点。
给这个对象一个属性“Enemy”,同时赋一个值1.如果你想在这个教程的基础上扩展,并且增加其它的不同类型的敌人,你可以使用这些敌人的属性值来表示不同类型的敌人。
现在,制作6-10个这种敌人出现位置点对象,相应的它们离player的距离也要有一些不同。为每一个对象定义一个“Enemy”属性,并且赋值为1.保存这张地图并且回到Xcode。
开始创建敌人
好了,现在我们将把敌人实际显示到地图上来。首先在HelloWorldScene.m中添加如下代码:
//in the HelloWorld class
-(void)addEnemyAtX:(int)x y:(int)y {
CCSprite*enemy = [CCSprite spriteWithFile:@"enemy1.png"];
enemy.position=ccp(x, y);
[self addChild:enemy];
}//in the init method - after creating the player//iterate through objects, finding all enemy spawn points//create an enemy for each one
NSMutableDictionary *spawnPoint;for (spawnPoint in[objects objects]) {if ([[spawnPoint valueForKey:@"Enemy"] intValue] ==1){
x= [[spawnPoint valueForKey:@"x"] intValue];
y= [[spawnPoint valueForKey:@"y"] intValue];
[self addEnemyAtX:x y:y];
}
}
第一个循环遍历对象列表,判断它是否是一个敌人出现的位置点。如果是,则获得它的x和y坐标值,然后调用addEnemyAtX:Y方法把它们加入到合适的地方去。
这个addEnemyAtX:Y方法非常直白,它仅仅是在传入的X,Y坐标值处创建一个敌人精灵。
如果你编译并运行,你会看到这些敌人出现在你之前在Tiled工具中设定的位置处,很酷吧!
但是,这里有一个问题,这些敌人很傻瓜,它们并不会追杀你的忍者。
使它们移动
因此,现在我们将添加一些代码,使这些敌人会追着我们的player跑。因为,player肯定会移动,我们必须动态地改变敌人的运动方向。为了实现这个目的,我们让敌人每次移动10个像素,然后在下一次移动之前,先调整它们的方向。在HelloWorldScene.m中加入如下代码:
//callback. starts another iteration of enemy movement.
- (void) enemyMoveFinished:(id)sender {
CCSprite*enemy = (CCSprite *)sender;
[self animateEnemy: enemy];
}//a method to move the enemy 10 pixels toward the player
- (void) animateEnemy:(C