首页 > 代码库 > cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第九步---英雄发动攻击

cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第九步---英雄发动攻击

/* 说明:

**1.本次游戏实例是《cocos2d-x游戏开发之旅》上的最后一个游戏,这里用3.0重写并做下笔记

**2.我也问过木头本人啦,他说:随便写,第一别完全照搬代码;第二可以说明是学习笔记---好人大笑

**3.这里用cocos2d-x 3.0版本重写,很多地方不同,但是从重写过程中也很好的学习了cocos2d-x

*/

***每一步对应的所有代码以及用到的资源都会打包在最后给出

***为避免代码过多,每一步的代码都做了标记--一看就晓得是第几步实现的避免出错改不回去(难不成还用Git?)

***为了方便移植到手机上,对于每一步都进行编译android测试;因为很多时候代码在win32下可以,编译就会出错,给出的代码会是测试过后的。

本次笔记内容:

1、直接思路&代码

2、下次内容预览

3、本次源码&资源下载

一:思路&代码

让英雄攻击怪物的话,就要用到update函数,自动判断,进入锁定目标攻击,出去就找下一个目标
那么这里首先要解决的就是,英雄必须和当前游戏中的怪物有联系;解决联系问题:
在怪物管理器中添加:

在怪物管理器中添加:

//**9**get MonsterList
	Vector<Monster*>* getMonsterList(){return &_monsterList;};
我这里偷懒,直接放在.h 的class里面作为public成员;这里需要注意的是传地址
在MapLayer中

//**9**
	Vector<Monster*>* getMonsterList(){
		if(_monsterMgr == NULL) return NULL;
	return _monsterMgr->getMonsterList();
	};
那么,之后,我们就可以在英雄的update函数-->checkAtkMonster中,获得怪物信息

看看英雄是怎么样来攻击怪物的:
首先,英雄有一个当前的攻击目标_atkMonster,最开始构造函数赋值为NULL,然后,获取了怪物信息之后,进行判断
其次,英雄需要一个攻击冷却,_isAtkCoolDown 初始
1、如果没攻击目标,那么,从怪物列表中chooseAim
2、如果有,判断目标是否死了,已经死了就从怪物列表中删除,目标清空NULL,本次攻击结束return;
3、有目标,其攻击冷却结束,那么atk函数进行攻击
4、有目标,判断是否离开攻击范围
先看看 update函数

void Hero::checkAtkMonster(float dt){
	//**9**获取怪物列表
	auto scene = Director::getInstance()->getRunningScene();
	MapLayer* layer = (MapLayer*)scene->getChildByTag(TAG_MAP_LAYER);
	Vector<Monster*>* monsterList = layer->getMonsterList();

	if(layer->getMonsterList() == NULL) return;
	
	if(_atkMonster != NULL){
		if(_atkMonster->isDead()){
			monsterList->eraseObject(_atkMonster);
			CC_SAFE_RELEASE_NULL(_atkMonster);
			return;
		}

		if(_isAtkCoolDown == false){
			atk();
		}
		//**9**看看目标是否走出攻击范围
		if(isInAtkRange(_atkMonster->getPosition()) == false){
			CCLOG("out out out out out ");
			CC_SAFE_RELEASE_NULL(_atkMonster); //清空目标
		}
	}
	else{
		//**9**从怪物列表取得攻击目标
		chooseAim((*monsterList));
	}
}
其他函数

void Hero::chooseAim(Vector<Monster*>monsterList){
	for(auto monster : monsterList){
		if(monster != NULL){
			if(isInAtkRange(monster->getPosition())){
				//**9**选择目标在范围内,就锁定目标
				CCLOG("In Atk Range !!");
				CC_SAFE_RELEASE(_atkMonster);
				CC_SAFE_RETAIN(monster);
				_atkMonster = monster;
				break;
			}
		}
	}
}

bool Hero::isInAtkRange(Point pos){
	int atkRange = getAtkRange();
	Point heroPos = getPosition();

	float dis = ccpDistanceSQ(pos,heroPos);
	if(dis <= atkRange*atkRange){
		return true;
	}
	return false;
}

void Hero::atk(){
	CCLOG("Atk!!");

	_isAtkCoolDown = true;

	//攻击间隔时间后,冷却时间到
	this->scheduleOnce(schedule_selector(Hero::atkCollDownEnd),getAtkSpeed()/1000.0f);
}
void Hero::atkCollDownEnd(float dt){
	_isAtkCoolDown = false;
}
最后,在init函数中

	//**9**
	this->schedule(schedule_selector(Hero::checkAtkMonster),0.3f);
之后F5调试,添加一个hero,当有怪物走近的时候,就能看到打印的攻击信息

这里由于攻击需要子弹,而子弹也稍微有点点多,留在下次说

关于效果的话,只能在输出看到

二:下次内容预览

让英雄发射子弹& 怪物受伤看得见---血量条装饰

到下次,也差不多结束啦

三:

----------------------------------------

代码&资源

-------------------------------------------

个人愚昧观点,欢迎指正与讨论



cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第九步---英雄发动攻击