这一章我们就要开始在Game01.m文件中canMoveTo: 方法中的if循环中添
加相应的事件了,我在制作地图时图块都设置了其属性如图:
这里我就要获取其属性值
NSDictionary *props = [self.curtitleMap propertiesForGID:enemy_tileGid];
NSString *value = [props valueForKey:@"enemy"];
int type = [value intValue];
通过获取到的属性值来判断是那一类怪物,这里还得再添加两个类Enemy 和 Monster
为了有重点的讲解这里我就先不介绍这两个类了。代码如下:
Enemy.h代码
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface Enemy : CCSprite<NSCopying>
{
}
//怪物编号
@property (nonatomic,assign) int enemyID;
//怪物名
@property (nonatomic,retain) NSString *name;
//血量
@property (nonatomic,assign) int HP;
//攻击
@property (nonatomic,assign) int Attack;
//防御
@property (nonatomic,assign) int Defense;
//金币
@property (nonatomic,assign) int Coin;
//经验
@property (nonatomic,assign) int Experience;
//怪物行走动画
@property (nonatomic,retain) CCAnimation *walkAction;
-(Enemy*) initWithEmeny:(Enemy*) copyform;
@end
Enemy.m代码
#import "Enemy.h"
@implementation Enemy
@synthesize enemyID;
@synthesize name;
@synthesize HP;
@synthesize Attack;
@synthesize Defense;
@synthesize Coin;
@synthesize Experience;
@synthesize walkAction;
-(id) copyWithZone:(NSZone *)zone
{
Enemy *copy = [[[self class] allocWithZone:zone] initWithEmeny:self];
return copy;
}
-(Enemy*) initWithEmeny:(Enemy *)copyform
{
if ((self = [super init]))
{
self.enemyID = copyform.enemyID;
self.name = copyform.name;
self.HP = copyform.HP;
self.Attack = copyform.Attack;
self.Defense = copyform.Defense;
self.Coin = copyform.Coin;
self.Experience = copyform.Experience;
self.walkAction = copyform.walkAction;
}
return self;
}
@end
Monster.h代码
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Enemy.h"
@interface Monster : Enemy
+(id)initWith:(int)typeID;
@end
Monster.m代码
#import "Monster.h"
@implementation Monster
+(id)initWith:(int)typeID
{
CGRect Rect;
Rect = CGRectMake(0, typeID*32, 32, 32);
Monster *enemy = nil;
NSString *name;
int HP,Attack,Defense,Coin,Experience;
if ((enemy = [[[super alloc] initWithFile:@"enemy.png" rect:Rect] autorelease]))
{
switch (typeID)
{
case 0:
name = @"骷髅兵1";
HP = 110;
Attack = 25;
Defense = 5;
Coin = 5;
Experience = 4;
break;
case 1:
name = @"骷髅兵2";
HP = 150;
Attack = 40;
Defense = 20;
Coin = 8;
Experience = 6;
break;
case 2:
name = @"骷髅队长";
HP = 400;
Attack = 90;
Defense = 50;
Coin = 15;
Experience = 12;
break;
case 3:
name = @"冥队长";
HP = 3500;
Attack = 1280;
Defense = 1000;
Coin = 112;
Experience = 100;
break;
case 4:
name = @"小蝙蝠";
HP = 100;
Attack = 20;
Defense = 5;
Coin = 3;
Experience = 3;
break;
case 5:
name = @"大蝙蝠";
HP = 150;
Attack = 65;
Defense = 30;
Coin = 10;
Experience = 8;
break;
case 6:
name = @"红蝙蝠";
HP = 550;
Attack = 160;
Defense = 90;
Coin = 25;
Experience = 20;
break;
case 7:
name = @"boss";
HP = 50000;
Attack = 2800;
Defense = 2700;
Coin = 1000;
Experience = 1000;
break;
case 8:
name = @"绿球怪";
HP = 50;
Attack = 20;
Defense = 1;
Coin = 1;
Experience = 1;
break;
case 9:
name = @"红球怪";
HP = 70;
Attack = 15;
Defense = 2;
Coin = 2;
Experience = 2;
break;
case 10:
name = @"黑球怪";
HP = 200;
Attack = 35;
Defense = 10;
Coin = 5;
Experience = 5;
break;
case 11:
name = @"怪王";
HP = 700;
Attack = 250;
Defense = 125;
Coin = 32;
Experience = 30;
break;
case 12:
name = @"初级法师";
HP = 125;
Attack = 50;
Defense = 25;
Coin = 10;
Experience = 7;
break;
case 13:
name = @"高级法师";
HP = 100;
Attack = 200;
Defense = 110;
Coin = 30;
Experience = 25;
break;
case 14:
name = @"麻衣法师";
HP = 250;
Attack = 120;
Defense = 70;
Coin = 20;
Experience = 17;
break;
case 15:
name = @"红衣法师";
HP = 500;
Attack = 400;
Defense = 260;
Coin = 47;
Experience = 45;
break;
case 16:
name = @"兽面人";
HP = 300;
Attack = 75;
Defense = 45;
Coin = 13;
Experience = 10;
break;
case 17:
name = @"兽面武士";
HP = 900;
Attack = 450;
Defense = 330;
Coin = 50;
Experience = 50;
break;
case 18:
name = @"石头怪人";
HP = 500;
Attack = 115;
Defense = 65;
Coin = 15;
Experience = 15;
break;
case 19:
name = @"影子战士";
HP = 3100;
Attack = 1150;
Defense = 1050;
Coin = 92;
Experience = 80;
break;
case 20:
name = @"初级卫兵";
HP = 450;
Attack = 150;
Defense = 90;
Coin = 22;
Experience = 19;
break;
case 21:
name = @"冥卫兵";
HP = 1250;
Attack = 500;
Defense = 400;
Coin = 55;
Experience = 55;
break;
case 22:
name = @"高级卫兵";
HP = 1500;
Attack = 570;
Defense = 480;
Coin = 60;
Experience = 60;
break;
case 23:
name = @"双手剑客";
HP = 1200;
Attack = 620;
Defense = 520;
Coin = 65;
Experience = 75;
break;
case 24:
name = @"冥灵魔王";
HP = 30000;
Attack = 1700;
Defense = 1500;
Coin = 250;
Experience = 220;
break;
case 44:
name = @"黑衣魔王";
HP = 20000;
Attack = 1333;
Defense = 1333;
Coin = 130;
Experience = 130;
break;
case 52:
name = @"红衣魔王";
HP = 15000;
Attack = 1000;
Defense = 1000;
Coin = 100;
Experience = 100;
break;
case 56:
name = @"冥战士";
HP = 2000;
Attack = 680;
Defense = 590;
Coin = 70;
Experience = 65;
break;
case 57:
name = @"金卫士";
HP = 850;
Attack = 350;
Defense = 200;
Coin = 45;
Experience = 40;
break;
case 58:
name = @"金队长";
HP = 900;
Attack = 750;
Defense = 650;
Coin = 77;
Experience = 70;
break;
case 59:
name = @"灵武士";
HP = 1600;
Attack = 1306;
Defense = 1200;
Coin = 117;
Experience = 100;
break;
case 53:
name = @"白衣武士";
HP = 1300;
Attack = 300;
Defense = 150;
Coin = 40;
Experience = 35;
break;
case 54:
name = @"灵法师";
HP = 2000;
Attack = 1110;
Defense = 980;
Coin = 100;
Experience = 90;
break;
default:
break;
}
enemy.enemyID = typeID;
enemy.name = name;
enemy.HP = HP;
enemy.Attack = Attack;
enemy.Defense = Defense;
enemy.Coin = Coin;
enemy.Experience = Experience;
}
return enemy;
}
@end
这里面的有怪物参数我自己修改了一部分。
根据获取到的属性值来实例化响应的怪物代码如下:
selenemy:当前选中怪物 ,应为要在其它方法里调用这个怪物的参数所以这里定义了一个属性。
这样我们已经实例化了怪物,那么接下来就要添加怪物的打斗界面了在打斗之前呢我们要判断
是否能够打过当前怪物所以再接着添加如下代码:
self.selenemy = enemy;
int enemyHp,_heroHp;
enemyHp = enemy.HP;
_heroHp = _hero.HP;
if (_hero.Attack > enemy.Defense)
{
do
{
enemyHp -= (_hero.Attack - enemy.Defense);
if (enemyHp >0)
{
if ((enemy.Attack - _hero.Defense) > 0)
{
_heroHp -= (enemy.Attack - _hero.Defense);
}
}
} while (enemyHp >0 && _heroHp >0);
}
if (enemyHp <=0 )
{
[self creatFightScene];
}
这里我没还要再添加一个创建打斗场景的方法creatFightScene。
-(void)creatFightScene
{
FightLayer* fightLayer = [[[FightLayer alloc] initWith:selenemy.enemyID] autorelease];
[self addChild:fightLayer];
}
写到这里我们还得再添加一个类FightLayer ,用于创建战斗场景,通过敌人的编号来创建相应
的场景。
FightLayer.h代码
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@class Hero;
@class Enemy;
@interface FightLayer : CCLayer
{
//怪物
CCLabelTTF *enemyHpLable;
//英雄
CCLabelTTF *heroHpLable;
//
Hero *hero;
//
Enemy *selenemy;
}
-(id)initWith:(int) type;
@end
FightLayer.m代码
#import "FightLayer.h"
#import "Enemy.h"
#import "Monster.h"
#import "Hero.h"
#import "Herohp.h"
@implementation FightLayer
-(id)initWith:(int)type
{
if ((self = [super init]))
{
//获取屏幕大小
CGSize size = [[CCDirector sharedDirector] winSize];
//背景
CCTMXTiledMap *background = [CCTMXTiledMap tiledMapWithTMXFile:@"fightbg.tmx"];
background.scale = 3.0;
background.position = ccp(35, size.height / 2 - 150);
[self addChild:background];
selenemy = [Monster initWith:type];
selenemy.scale = 4.0;
selenemy.position = ccp(150, 600);
[self addChild:selenemy];
CCTexture2D *heroTexture = [[CCTextureCache sharedTextureCache]addImage:@"hero.png"];
CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:heroTexture rect:CGRectMake(0, 0, 32, 32)];
CCSprite *herosp = [CCSprite spriteWithSpriteFrame:frame];
herosp.scale = 4.0;
herosp.position = ccp(900, 600);
[self addChild:herosp];
hero = [Hero getHero];
//怪物
CCLabelTTF *enemy = [CCLabelTTF labelWithString:@"怪物" fontName:@"Verdana-Bold" fontSize:45];
//勇士
CCLabelTTF *yongshi = [CCLabelTTF labelWithString:@"勇士" fontName:@"Verdana-Bold" fontSize:45];
enemy.position = ccp(150, 400);
yongshi.position = ccp(900, 400);
[self addChild:enemy];
[self addChild:yongshi];
//标签1
enemyHpLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"生命 %i",selenemy.HP] fontName:@"Verdana-Bold" fontSize:35];
enemyHpLable.anchorPoint = ccp(0, 0);
enemyHpLable.position = ccp(260, 530);
[self addChild:enemyHpLable];
//标签2
heroHpLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"生命 %i",hero.HP] fontName:@"Verdana-Bold" fontSize:35];
heroHpLable.anchorPoint = ccp(0, 0);
heroHpLable.position = ccp(600, 530);
[self addChild:heroHpLable];
//标签3
CCLabelTTF* heroAttackLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"攻击 %i",hero.Attack] fontName:@"Verdana-Bold" fontSize:35];
heroAttackLable.anchorPoint = ccp(0, 0);
heroAttackLable.position = ccp(600, 430);
[self addChild:heroAttackLable];
//标签4
CCLabelTTF* heroDefenseLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"防御 %i",hero.Defense] fontName:@"Verdana-Bold" fontSize:35];
heroDefenseLable.anchorPoint = ccp(0, 0);
heroDefenseLable.position = ccp(600, 330);
[self addChild:heroDefenseLable];
//标签5
CCLabelTTF* enemyAttackLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"攻击 %i",selenemy.Attack] fontName:@"Verdana-Bold" fontSize:35];
enemyAttackLable.anchorPoint = ccp(0, 0);
enemyAttackLable.position = ccp(260, 430);
[self addChild:enemyAttackLable];
//标签6
CCLabelTTF* enemyDefenseLable = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"防御 %i",selenemy.Defense] fontName:@"Verdana-Bold" fontSize:35];
enemyDefenseLable.anchorPoint = ccp(0, 0);
enemyDefenseLable.position = ccp(260, 330);
[self addChild:enemyDefenseLable];
[self schedule:@selector(update) interval:0.2];
}
return self;
}
-(void)update
{
selenemy.HP -= (hero.Attack - selenemy.Defense);
if (selenemy.HP <= 0)
{
selenemy.HP = 0;
[self.parent removeEnemy];
[self.parent removeChild:self cleanup:YES];
}
else
{
if ((selenemy.Attack - hero.Defense) > 0)
{
hero.HP -= (selenemy.Attack - hero.Defense);
}
[enemyHpLable setString:[NSString stringWithFormat:@"生命 %i",selenemy.HP]];
[heroHpLable setString:[NSString stringWithFormat:@"生命 %i",hero.HP]];
}
}
@end
这里我只讲一下更新方法里面的代码,
if (selenemy.HP <= 0)
{
selenemy.HP = 0;
[self.parent removeEnemy];
[self.parent removeChild:self cleanup:YES];
}
这个是判断敌人是否死亡如果死亡则调用父节点消除敌人的方法,并把自己从父场景中消除
这个时候我们就要在Game01中添加removeEnemy方法。
-(void)removeEnemy
{
[self.curtitleMap.enemy removeTileAt:towerLoc];
canmove = YES;
}
好了到这里我们的勇士就可以和怪物打斗了
还有一个问题就是canmove这个变量主要就是控制勇士是否可以移动,在很多地方都有用到
前面updataMove方法里要添加一个控制,否则有时候怪物就消除不掉,需要添加的代码:
添加这样一个判断就ok了。
完成之后游戏截图