塔之战:炮塔的攻击

炮塔就位了?检查.敌人前进中?再次检查 - 它们看起来就是如此!看起来到了击溃这些家伙的时候了!这里我们将智能置入炮塔的代码中去.

每一个炮塔检查是否有敌人在其攻击范围.(炮塔一次只能攻击一个敌人.猫猪注)如果有,炮塔将开始向敌人开火直到两件事之一发生:敌人移出攻击范围或者敌人被摧毁.炮塔接着开始寻找其他欠扁的家伙 :]

将它们放到一起,新建新炮塔!你已经有一个防御基础了!

因为敌人和炮塔类相互依赖彼此,你不得不首先更新它们类的头文件,去避免你在修改实现代码时Xcode发生显示错误.

首先,打开Tower.h文件,然后完成以下修改:

// Add some instance variables
BOOL attacking;
Enemy *chosenEnemy;

// Add method definition
-(void)targetKilled;

打开Enemy.h文件修改如下:

// Add instance variable
NSMutableArray *attackedBy;

// Add method definitions
-(void)getAttacked:(Tower *)attacker;
-(void)gotLostSight:(Tower *)attacker;
-(void)getDamaged:(int)damage;

下一步,回到Tower.m中做如下修改:

// Import Enemy header at the top of the file:
#import "Enemy.h"

// Add the following methods
-(void)attackEnemy
{
    [self schedule:@selector(shootWeapon) interval:fireRate];
}

-(void)chosenEnemyForAttack:(Enemy *)enemy
{
    chosenEnemy = nil;
    chosenEnemy = enemy;
    [self attackEnemy];
    [enemy getAttacked:self];
}

-(void)shootWeapon
{
    CCSprite * bullet = [CCSprite spriteWithFile:@"bullet.png"];
    [theGame addChild:bullet];
    [bullet setPosition:mySprite.position];
    [bullet runAction:[CCSequence actions:
                       [CCMoveTo actionWithDuration:0.1 position:chosenEnemy.mySprite.position],
                       [CCCallFunc actionWithTarget:self selector:@selector(damageEnemy)],
                       [CCCallFuncN actionWithTarget:self selector:@selector(removeBullet:)], nil]];

}

-(void)removeBullet:(CCSprite *)bullet
{
    [bullet.parent removeChild:bullet cleanup:YES];
}

-(void)damageEnemy
{
    [chosenEnemy getDamaged:damage];
}

-(void)targetKilled
{
    if(chosenEnemy)
        chosenEnemy =nil;

    [self unschedule:@selector(shootWeapon)];
}

-(void)lostSightOfEnemy
{
    [chosenEnemy gotLostSight:self];
    if(chosenEnemy)
        chosenEnemy =nil; 

    [self unschedule:@selector(shootWeapon)];
}

最后,替换之前版本只能怪留下的空白update方法:

-(void)update:(ccTime)dt {
    if (chosenEnemy){

        //We make it turn to target the enemy chosen
        CGPoint normalized = ccpNormalize(ccp(chosenEnemy.mySprite.position.x-mySprite.position.x,
                                              chosenEnemy.mySprite.position.y-mySprite.position.y));
        mySprite.rotation = CC_RADIANS_TO_DEGREES(atan2(normalized.y,-normalized.x))+90;

        if(![theGame circle:mySprite.position withRadius:attackRange
             collisionWithCircle:chosenEnemy.mySprite.position collisionCircleRadius:1])
        {
            [self lostSightOfEnemy];
        }
    } else {
        for(Enemy * enemy in theGame.enemies)
        {
            if([theGame circle:mySprite.position withRadius:attackRange
                collisionWithCircle:enemy.mySprite.position collisionCircleRadius:1])
            {
                [self chosenEnemyForAttack:enemy];
                break;
            }
        }
    }
}

Cocos2D:塔防游戏制作之旅(十四)的更多相关文章

  1. Cocos2D:塔防游戏制作之旅(十八)

    在Enemy.m的getDamaged:方法只给你添加如下1行(在if条件内): [theGame awardGold:200]; 现在运行游戏你将注意到你不能放置超出你资源金币的炮塔了.当然杀死敌人 ...

  2. Cocos2D:塔防游戏制作之旅(十六)

    编译运行你的app,放置一些炮塔在你的地图上吧!你将看到炮塔在敌人移动如攻击范围时如何立即开始攻击,并且敌人的血条将随着攻击不断减少知道它们被人道毁灭!胜利即将来临了! 哦!Okay,这里只有少数细节 ...

  3. Cocos2D:塔防游戏制作之旅(十)

    最终,draw方法显示这些路径点被放置在哪里,并且绘制出路径点之间的连线,它们仅仅被用作调试.一个成品游戏不应该绘制敌人的路径 - 那对于玩家来说太过容易了! 创建路径点的列表.打开HelloWorl ...

  4. Cocos2D:塔防游戏制作之旅(十五)

    Yes,貌似添加了好多的代码啊 ;] ,在你添加更多代码时,你可能注意到一些Xcode中的一些警告.首先你先忽略这些警告,我们先添加少量最终缺失的部分,然后再来解释上面代码做了什么! 在Enemy.m ...

  5. Cocos2D:塔防游戏制作之旅(十二)

    以上代码块相当直观 - 但是它分解的有些细致了. 首先,敌人通过传递HelloWorldLayer对象的引用而初始化.在init方法里,少数重要的变量被设置: maxHP:定义敌人有多经打(Tough ...

  6. Cocos2D:塔防游戏制作之旅(一)

    原文地址:http://www.raywenderlich.com/37701/how-to-make-a-tower-defense-game-tutorial 由Pablo Ruiz写的入门教程, ...

  7. Cocos2D:塔防游戏制作之旅(二)

    一个象牙塔的视图 如果你并不熟悉此类型的游戏,塔防游戏是一个战略游戏,你需要购买和将武装塔放置在战略位置,去阻止一波又一波的敌人到达并摧毁你的基地 每一波敌人都更强,这些更强的对手有着更快的速度和对于 ...

  8. Cocos2D:塔防游戏制作之旅(十七)

    getHpDamage方法当敌人到达基地时被调用.你需要添加该方法到Enemy.m的update:方法中去,以便检查当敌人到达基地是会发生什么.幸运的是,你已经在之前的代码中实现这些了,你可以接着往下 ...

  9. Cocos2D:塔防游戏制作之旅(八)

    如果所有东西通过检查,则创建一个新炮塔,将它放置在基座上,然后添加到towers数组中. 注意:在方法最后的bridge语法需要做一些解释.你下载的初始项目已经为一 些文件打开ARC,但不是Cocos ...

随机推荐

  1. idea+jsp+jstl c标签页面异常

    先在Schema and DTDs配置C.tld文件 最后提示是少包 网上很多方法都说少jstl.jar 折腾了很久 其实还少standard.jar 以前的解决方法(看下面) 把这两个包分别加到项目 ...

  2. 详解linux进程间通信-管道 popen函数 dup2函数

    前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...

  3. OpenCv error :unresolved external symbol(链接库没有加上)

    Error 如下:Linking...: error LNK2001: unresolved external symbol _cvDestroyWindow: error LNK2001: unre ...

  4. 【python标准库模块四】Json模块和Pickle模块学习

    Json模块 原来有个eval函数能能够从字符串中提取出对应的数据类型,比如"{"name":"zhangsan"}",可以提取出一个字典. ...

  5. FJUT第四周寒假作业之第一集,临时特工?(深度优先搜索)

    原网址:http://210.34.193.66:8080/vj/Contest.jsp?cid=163#P2 第一集,临时特工? TimeLimit:1000MS  MemoryLimit:128M ...

  6. Node.js 逐行读取

    逐行读取 稳定性: 2 - 不稳定 使用 require('readline'),可以使用这个模块.逐行读取(Readline)可以逐行读取流(比如process.stdin) 一旦你开启了这个模块, ...

  7. 2016移动端Android新技术综合预览--好文不多,这一篇就足够

    Csdn /Tamic 原文地址: http://blog.csdn.net/sk719887916/article/details/53525067 本文章6月份已完成(http://www.jia ...

  8. Linux测量kernel子模块加载时间的方法

    1. 在文件kernel/init/main.c里面,在接口do_one_initcall( )中,将initcall_debug设置为true,然后编译boot.img 2. 使用adb shell ...

  9. Android存储之SQLite数据库

    Android存储之SQLite数据库数据库 创建数据库 package --; import android.content.Context; import android.database.sql ...

  10. 【Unity3D】 Unity Chan项目分享

    写在前面 之前的一个博文里分享了日本Unity酱的项目,如果大家有去仔细搜Unity酱的话,就会发现日本Unity官方还放出了一个更完整的Unity酱的项目,感觉被萌化了!(事实上,Unity日本经常 ...