这部分我们要添加怪物查看了,首先我们看一下下面这张图:
这就是我们所要实现的效果图,我们很容易就能看到其相似的地方每个怪物显示的内容都差不多。
我们这里需要添加两个类MonsterInformation(查看怪物信息主界面)和MonsterInformationCell(单个怪物显示信息块)
首先我们来看一下MonsterInformation.h文件代码:
#import<Foundation/Foundation.h>
#import"cocos2d.h"
@class Enemy;
@class Hero;
@interface MonsterInformation : CCLayer
{
//背景
CCTMXTiledMap *mapBackground;
Hero *hero;
}
//当前图层怪物数组
@property (nonatomic,retain) NSMutableArray *mosterArray;
//怪物列表数量
@property (nonatomic,assign)int mosterListCount;
//是否移除界面
@property (nonatomic,assign)bool removeView;
//加载怪物列表
-(void)ViewInit:(Enemy*) monster;
//更新损失血量
-(void)updateLossHP;
@end
这个类有三个属性,第一个就是存储当前图层怪物信息的数组,第二个怪物列表的引用计数,第三个就是用于判断界面是否可以移除。
然后我们开始添加MonsterInformation.m文件代码:
#import"MonsterInformation.h"
#import"MonsterInformationCell.h"
#import"Monster.h"
#import"Hero.h"
@implementation MonsterInformation
@synthesize mosterArray;
@synthesize mosterListCount;
@synthesize removeView;
-(id)init
{
if ((self = [super init]))
{
//背景
mapBackground = [CCTMXTiledMap tiledMapWithTMXFile:@"shopbg.tmx"];
mapBackground.position = ccp(10,50);
mapBackground.scale =2.2;
[self addChild:mapBackground];
self.mosterArray = [[[NSMutableArray alloc] init] autorelease];
}
returnself;
}
-(void)ViewInit:(Enemy*) monster
{
//获取屏幕大小
CGSize size = [[CCDirectorsharedDirector]winSize];
//判断当前怪物信息数组是否空
if (self.mosterArray.count ==0)
{
//如果是则初始化怪物信息标签并添加到数组中
mosterListCount =1;
MonsterInformationCell *cell = [[[MonsterInformationCellalloc]init]autorelease];
[cell viewInit:monster];
cell.position =ccp(30, size.height -80*mosterListCount -14);
[self.mosterArrayaddObject:cell];
[selfaddChild:cell];
}
else
{
//如果不是则先判断一下当前怪物信息标签是否已经存在数组中
bool sa = NO;
for (MonsterInformationCell *cellinself.mosterArray)
{
if (cell.enemy.enemyID == monster.enemyID)
{
//如果在则怪物标签计数加1
cell.count ++;
sa =YES;
}
}
if (!sa)
{
//如果不在则初始化怪物信息标签并添加到数组中
mosterListCount +=1;
MonsterInformationCell *cell = [[[MonsterInformationCellalloc]init]autorelease];
[cell viewInit:monster];
cell.position =ccp(30, size.height -80*mosterListCount -14);
[self.mosterArrayaddObject:cell];
[selfaddChild:cell];
}
}
}
-(void)updateLossHP
{
for (MonsterInformationCell *cellinself.mosterArray)
{
hero = [Hero getHero];
int enemyHp,_heroHp;
enemyHp = cell.enemy.HP;
_heroHp = 0;
if (hero.Attack > cell.enemy.Defense)
{
do
{
enemyHp -= (hero.Attack - cell.enemy.Defense);
if (enemyHp >0)
{
if ((cell.enemy.Attack -hero.Defense) >0)
{
_heroHp += (cell.enemy.Attack -hero.Defense);
}
}
} while (enemyHp >0);
[cell updateLossHP:_heroHp];
}
}
}
@end
我们的查看怪物信息主界面有了,下面我们来讲一下MonsterInformationCell这个类,先看一下头文件:
#import<Foundation/Foundation.h>
#import"cocos2d.h"
#import"Monster.h"
@interface MonsterInformationCell :CCLayer
{
//勇士损失血量
CCLabelTTF *label61;
}
@property (nonatomic,retain)Enemy *enemy;
@property (nonatomic,assign)int count;
//初始化怪物信息标签
-(void)viewInit:(Enemy*) monster;
//更新损失生命
-(void)updateLossHP:(int) lossHp;
@end
我们这个类只有一个需要更新的标签就是勇士损失血量标签,还有两个属性,一个是怪物,一个是怪物个数。还有两个方法,一个是初始化标签,一个是用于更新勇士要损失的血量。下面我们来看一下实现文件中的代码:
#import"MonsterInformationCell.h"
@implementation MonsterInformationCell
@synthesize enemy;
@synthesize count;
-(id) init
{
if ((self = [superinit]))
{
self.count = 1;
}
returnself;
}
-(void)viewInit:(Enemy*) monster
{
self.enemy = monster;
monster.scale =2.0;
monster.anchorPoint =ccp(0,0);
monster.position =ccp(0, -10);
[selfaddChild:monster];
//
CCLabelTTF *label1 = [[CCLabelTTFalloc]initWithString:@"名称"fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label2 = [[CCLabelTTFalloc]initWithString:@"攻击"fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label3 = [[CCLabelTTFalloc]initWithString:@"金*经"fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label4 = [[CCLabelTTFalloc]initWithString:@"生命"fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label5 = [[CCLabelTTFalloc]initWithString:@"防御"fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label6 = [[CCLabelTTFalloc]initWithString:@"损失"fontName:@"Verdana-Bold"fontSize:20];
//
CCLabelTTF *label11 = [[CCLabelTTF alloc] initWithString:[NSStringstringWithFormat:@"%@",monster.name]fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label21 = [[CCLabelTTF alloc] initWithString:[NSStringstringWithFormat:@"%d",monster.Attack]fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label31 = [[CCLabelTTF alloc] initWithString:[NSStringstringWithFormat:@"%d*%d",monster.Coin,monster.Experience]fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label41 = [[CCLabelTTF alloc] initWithString:[NSStringstringWithFormat:@"%d",monster.HP]fontName:@"Verdana-Bold"fontSize:20];
CCLabelTTF *label51 = [[CCLabelTTF alloc] initWithString:[NSStringstringWithFormat:@"%d",monster.Defense]fontName:@"Verdana-Bold"fontSize:20];
label61 = [[CCLabelTTFalloc]initWithString:[NSStringstringWithFormat:@"???"]fontName:@"Verdana-Bold"fontSize:20];
//label位置
label1.position =ccp(90,35);
label11.position =ccp(200,35);
label2.position =ccp(290,35);
label21.position =ccp(400,35);
label3.position =ccp(490,35);
label31.position =ccp(600,35);
label4.position =ccp(90,0);
label41.position =ccp(200,0);
label5.position =ccp(290,0);
label51.position =ccp(400,0);
label6.position =ccp(490,0);
label61.position =ccp(600,0);
//加载label
[selfaddChild:label1];
[selfaddChild:label11];
[selfaddChild:label2];
[selfaddChild:label21];
[selfaddChild:label3];
[selfaddChild:label31];
[selfaddChild:label4];
[selfaddChild:label41];
[selfaddChild:label5];
[selfaddChild:label51];
[selfaddChild:label6];
[selfaddChild:label61];
}
//更新损失生命
-(void)updateLossHP:(int) lossHp
{
[label61setString:[NSStringstringWithFormat:@"%d",lossHp]];
}
@end
这里面全都是标签就不多说了。我们再来看以下MonsterInformation中的更新血量的方法,通过遍历数组得到怪物的信息,进行损失血量的判断并更新。好了这两个类建好了,下面就是该在那里用、怎么用的问题了。有两种方式一种是在游戏中需要查看的时候初始化它;另一种就是直接在加载地图的时候创建它,把它当成地图的一部分,然后使用是时候直接调用它。两种方式的优略我就不讲了,有兴趣的可以两种都试试。这里我使用的是第二种方式,所以我们下面就要在TitledMap中添加代码了。
首先我们要添加一个属性:
@property (nonatomic,retain)MonsterInformation *monsterInfor;
并在初始化方法中实例化monsterInfor:
self.monsterInfor = [[[MonsterInformationalloc]init]autorelease];
然后我们再添加一个用于创建我们的怪物信息界面的方法:
-(void)createMonsterInformation
{
for (int x = 0; x <= 10; x++)
{
for (int y = 0; y <= 10; y++)
{
CGPoint towerLoc = CGPointMake(x, y);
int enemy_tileGid = [self.enemytileGIDAt:towerLoc];
if (enemy_tileGid)
{
NSDictionary *props = [self propertiesForGID:enemy_tileGid];
NSString *value = [props valueForKey:@"enemy"];
int type = [value intValue];
Enemy *enemy = [Monster initWith:type];
[self.monsterInforViewInit:enemy];
}
}
}
return;
}
在这里我们遍历怪物图层获取怪物信息并添加到怪物信息界面中。
然后我们在初始化方法中调用它。
[selfcreateMonsterInformation];
下面就让我们在Game01中调用它吧!
昨天我们已经把图标添加上了,现在我们就来添加它的响应事件:
if (openpredict)
{
if (CGRectIntersectsRect(Rect, RectPredict))
{
if (!self.curtitleMap.monsterInfor.removeView)
{
if (!flyFloor.removeView)
{
[selfonPredict];
self.curtitleMap.monsterInfor.removeView =YES;
_hero.isFighting = YES;
}
}
}
}
这部分代码添加到楼层飞行器触摸检测下面,并在楼层飞行器移除方法下面
截图如下:
这部分代码中有一个开关变量openpredict,控制是否开启洞悉权杖,应为我们的游戏中有一个道具只有吃到它的时候才可以使用它,所以我们要在道具检测的if(value4)中添加:
openpredict =YES;
另外还调用到一个新的方法onPredict:
//更新并加载查看怪物信息界面
-(void)onPredict
{
if (self.curtitleMap.monsterInfor.mosterListCount > 0)
{
[self.curtitleMap.monsterInforupdateLossHP];
[selfaddChild:self.curtitleMap.monsterInfor];
self.curtitleMap.monsterInfor.position =ccp(0,0);
}
}
这样我们的洞悉权杖就可以使用了,不过为了测试我们可以把openpredict这个开关变量在初始化方法中赋值为YES。运行一下看看是否跟我们开头部分的效果图一样呢。如果一样的话我们就来添加这部分最后一部分代码吧!
这部分代码要实现的功能是:把已死亡怪物的信息从我们的怪物信息查看界面中移除掉。显然这部分代码要添加到移除怪物的方法(removeEnemy)中去,代码如下:
MonsterInformationCell *removecell =nil;
for (MonsterInformationCell *cellinself.curtitleMap.monsterInfor.mosterArray)
{
if (cell.enemy.enemyID ==self.selenemy.enemyID)
{
//如果找到与之相对应的怪物信息标签则计数减1
cell.count -=1;
//当怪物信息标签计数等于零时我们把它移除掉并且列表计数减1
if (cell.count == 0)
{
removecell = cell;
[cell.parentremoveChild:cellcleanup:YES];
self.curtitleMap.monsterInfor.mosterListCount -=1;
}
}
}
//如果有怪物信息标签被移除则从数组中删除,并重新布局界面
if (removecell)
{
[self.curtitleMap.monsterInfor.mosterArrayremoveObject:removecell];
int i = 1;
for (MonsterInformationCell *cellinself.curtitleMap.monsterInfor.mosterArray)
{
cell.position =ccp(30,size.height -80*i - 14);
i += 1;
}
}
好了我们这部分内容就添加完毕了。运行一下试试吧!截图:
到这里我们的游戏教程就快要结束了!!!