Cocos2d-x 3.2 大富翁游戏项目开发-第二十六部分 人物技能

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.2 大富翁游戏项目开发-第二十六部分 人物技能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
本节主要是添加人物技能,技能包括

暴风骤雨:此技能可以把地块变成空白地块,
随心步: 选择想走的步数,想走几步走几步
巧取豪夺:把对手的土地变成自己的


技能包含的信息:等级 和 耗费体力
等级共5级,每提高一个等级,需要耗费的体力值减10


暴风骤雨:初始耗费体力值70
随心步: 初始耗费体力值50

巧取豪夺:初始耗费体力值100





1、添加技能SkillCard 类,包含了技能基本信息以及如何显示技能
其实现和前面讲解的股票 彩票 card类相似,不再累述

2、修改RicherPlayer类,添加技能相关属性方法

RicherPlayer.h

	//添加技能播放的动画
	void addSkillAnimation(); 
	CC_SYNTHESIZE(Vector<SpriteFrame*>,skill_rain_vector,Skill_rain_vector);
	CC_SYNTHESIZE(Vector<SpriteFrame*>,skill_transfer_vector,Skill_transfer_vector);

	CC_SYNTHESIZE(Animate*,rain_skill,RainSkill);
	CC_SYNTHESIZE(Animate*,transfer_skill,Transfer_skill);

	//存放技能等级信息
	std::vector<int> skill_vector;
	//存放角色停止走动后的位置
	float stop_x;
	float stop_y;

RicherPlayer.cpp

RicherPlayer::RicherPlayer()
{
	......
	//初始停留位置
	stop_x = -100;
	stop_y =0;
}

bool RicherPlayer::init(char* name,int tag,bool enemy,int money,int strength)
{
	...................
	//初始技能默认等级为1
	skill_vector.push_back(1);
	skill_vector.push_back(1);
	skill_vector.push_back(1);
	//添加技能动画相关
	addSkillAnimation();
}

void RicherPlayer::addSkillAnimation()
{
	..............
	//包括暴风骤雨 、巧取豪夺 2个技能的动画
	 rain_skill =Animate::create(AnimationCache::getInstance()->getAnimation("rain_animation"));
	 transfer_skill = Animate::create(AnimationCache::getInstance()->getAnimation("transfer_animation"));
	 
	 rain_skill->retain();
	 transfer_skill->retain();

}

3、添加技能菜单
//在添加go按钮的时候同时添加技能按钮
void  GameBaseScene::addGoButton()
{
................
	//技能按钮,在go按钮下发
    skillMenuItemButton = MenuItemImage::create("images/skill_button_normal.png","images/skill_button_pressed.png",this,menu_selector(GameBaseScene::goButtonCallback));
    skillMenuItemButton->setPosition(ccp(tableStartPosition_x+2*tableWidth+20,tableStartPosition_y-tableHeight*6-80));
	skillMenuItemButton->setTag(skillButtonTag);
	menu->addChild(skillMenuItemButton);
	//添加步数按钮,用于随心步技能
    step1Button = MenuItemImage::create("images/step1_normal.png","images/step1_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	..........
    step2Button = MenuItemImage::create("images/step2_normal.png","images/step2_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	............
    step3Button = MenuItemImage::create("images/step3_normal.png","images/step3_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	..........
    step4Button = MenuItemImage::create("images/step4_normal.png","images/step4_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	.........
    step5Button = MenuItemImage::create("images/step5_normal.png","images/step5_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	.......
    step6Button = MenuItemImage::create("images/step6_normal.png","images/step6_pressed.png",menu_selector(GameBaseScene::goButtonCallback));
	//暴风骤雨技能显示界面
	skillStorm = SkillCard::createCardSprite(LanguageString::getInstance()->getLanguageString(RAIN),LanguageString::getInstance()->getLanguageString(GRADE),LanguageString::getInstance()->getLanguageString(LOST_STRENGTH),LanguageString::getInstance()->getLanguageString(DOWN_GRADE),skillSpriteCardWidth,skillSpriteCardHeight,100,-130,skillStormTag,"images/thunderstorm.png");

	addChild(skillStorm,50);
	//随心步技能显示界面
	skillStep = SkillCard::createCardSprite(LanguageString::getInstance()->getLanguageString(GOBY_HEART),LanguageString::getInstance()->getLanguageString(GOBY_HEART_INFO),280,skillStepTag,"images/skill_step.png");
	addChild(skillStep,50);

	//巧取豪夺显示界面
	skillTransfer = SkillCard::createCardSprite(LanguageString::getInstance()->getLanguageString(YOURS_IS_MINE),LanguageString::getInstance()->getLanguageString(YOURS_IS_MINE_INFO),460,skillTransferTag,"images/skill_transfer.png");
	addChild(skillTransfer,50);

	//添加各个界面点击回调方法
	skillStorm->setSkillButtonCallback(this,callfuncN_selector(GameBaseScene::skillClick));
	skillStep->setSkillButtonCallback(this,callfuncN_selector(GameBaseScene::skillClick));
	skillTransfer->setSkillButtonCallback(this,callfuncN_selector(GameBaseScene::skillClick));
	//技能界面是否在显示
	isSkillLayerShow = false;
	//随心步步数按钮界面是否显示
	isStepLayerShow = false;
}

4、显示或隐藏随心步步数按钮界面,显示或隐藏时播放旋转动画
void  GameBaseScene::showStepButton(bool show)
{
	if(show)
	{
		//显示时变为可见
		step1Button->setVisible(true);
		step2Button->setVisible(true);
		step3Button->setVisible(true);
		step4Button->setVisible(true);
		step5Button->setVisible(true);
		step6Button->setVisible(true);
		//顺时针依次播放动画
		step2Button->runAction(RotateBy::create(stepSkillAnimaTime,60));
		step3Button->runAction(RotateBy::create(2*stepSkillAnimaTime,120));
		step4Button->runAction(RotateBy::create(3*stepSkillAnimaTime,180));
		step5Button->runAction(RotateBy::create(4*stepSkillAnimaTime,240));
		step6Button->runAction(RotateBy::create(5*stepSkillAnimaTime,300));

	}else
	{
		//隐藏时相反
		step2Button->runAction(RotateBy::create(stepSkillAnimaTime,-60));
		step3Button->runAction(RotateBy::create(2*stepSkillAnimaTime,-120));
		step4Button->runAction(RotateBy::create(3*stepSkillAnimaTime,-180));
		step5Button->runAction(RotateBy::create(4*stepSkillAnimaTime,-240));
		step6Button->runAction(RotateBy::create(5*stepSkillAnimaTime,-300));

		step6Button->runAction(Sequence::create(RotateBy::create(5*stepSkillAnimaTime,-300),CallFunc::create([this](){
			step1Button->setVisible(false);
			step2Button->setVisible(false);
			step3Button->setVisible(false);
			step4Button->setVisible(false);
			step5Button->setVisible(false);
			step6Button->setVisible(false);
		}
		),NULL));
	}
}

//技能界面点击相应函数
void GameBaseScene::skillClick(Node *pNode)
{
	int tag = pNode->getTag();
	if(tag == skillStormTag)
	{
		if(player1->stop_x  < 0)
		{
			return;
		}
		//当点击暴风骤雨时,判断角色体力值是否满足技能耗费的体力值,如果满足 就播放暴风骤雨动画,动画结束后角色所在地块变为空地块
		int needLostStrength = 80-player1->skill_vector.at(0)*10;
		if(player1->getStrength() >= needLostStrength)
		{
			showSkillSprites();
			player1->setStrength(player1->getStrength()-needLostStrength);
			refreshStrengthLabel(player1,0);
			Point pointOfGL = Util::map2GL(ccp(player1->stop_x,player1->stop_y),_map);
			rainSprite = Sprite::createWithSpriteFrame(player1->getRainSkill()->getAnimation()->getFrames().at(0)->getSpriteFrame());
			addChild(rainSprite);
			
			rainSprite->setAnchorPoint(ccp(0,0));
			rainSprite->setPosition(pointOfGL+ccp(-tiledWidth/2,tiledHeight/2));

			rainSprite->runAction(Sequence::create(player1->getRainSkill(),CallFunc::create([this]()
			{
				landLayer->setTileGID(blank_land_tiledID,ccp(player1->stop_x,player1->stop_y));	
				rainSprite->removeFromParent();
			}),NULL));
		}else //如果体力不足,Toast显示提示信息
		{
			CocosToast::createToast(this,LanguageString::getInstance()->getLanguageString(YOUR_STRENGTH_IS_LOW)->getCString(),TOAST_SHOW_TIME,winSize/2);
		}



	}

	if(tag == skillStepTag)
	{//如果点击了随心步 则显示随心步步数按钮界面
		showStepButton(!isStepLayerShow);
		isStepLayerShow = !isStepLayerShow;
	}

	if(tag == skillTransferTag)
	{//如果点击巧取豪夺
		if(player1->stop_x  < 0)
		{
			return;
		}
		//判断角色体力值和技能所需的体力值是否满足技能需求
		int needLostStrength = 110-player1->skill_vector.at(0)*10;
		if(player1->getStrength() >= needLostStrength)
		{
			//记录夺取地块的等级
			int transferLand = 0;
			if(transferLandTag== MSG_PAY_TOLLS_1_TAG)
			{
				transferLand = player1_building_1_tiledID;
			}
			if(transferLandTag== MSG_PAY_TOLLS_2_TAG)
			{
				transferLand = player1_building_2_tiledID;
			}
			if(transferLandTag== MSG_PAY_TOLLS_3_TAG)
			{
				transferLand = player1_building_3_tiledID;
			}
			transferLandTag = 0;
			if(transferLand != 0)
			{
				showSkillSprites();
				player1->setStrength(player1->getStrength()-needLostStrength);
				refreshStrengthLabel(player1,0);
				Point pointOfGL = Util::map2GL(ccp(player1->stop_x,_map);
				transferSprite = Sprite::createWithSpriteFrame(player1->getTransfer_skill()->getAnimation()->getFrames().at(0)->getSpriteFrame());
				addChild(transferSprite);
			
				transferSprite->setAnchorPoint(ccp(0,0));
				transferSprite->setPosition(pointOfGL);
				//播放巧取豪夺技能动画,并把地块变为自己相应等级的地块
				transferSprite->runAction(Sequence::create(player1->getTransfer_skill(),CallFunc::create([this,transferLand]()
				{
					landLayer->setTileGID(transferLand,player1->stop_y));	
					transferSprite->removeFromParent();
				}),NULL));

			}
			
		}else
		{
			CocosToast::createToast(this,winSize/2);
		}
	}
}

//修改goButtonCallback方法添加技能按钮和随心步步数按钮相应
void GameBaseScene::goButtonCallback(cocos2d::CCObject *pSender)
{
	
	int tag = ((Node*)pSender)->getTag();
	....................
	//当点击技能按钮时,显示或隐藏技能界面
	if(tag == skillButtonTag)
	{
		skillStorm->setSkillGrade(player1->skill_vector.at(0));
		skillStep->setSkillGrade(player1->skill_vector.at(1));
		skillTransfer->setSkillGrade(player1->skill_vector.at(2));

		skillStorm->setStength(80-player1->skill_vector.at(0)*10);
		skillStep->setStength(60-player1->skill_vector.at(1)*10);
		skillTransfer->setStength(110-player1->skill_vector.at(2)*10);

		showSkillSprites();
	}
	//当点击步数按钮时
	if(tag == step1_tag || tag == step2_tag || tag == step3_tag || tag == step4_tag || tag == step5_tag || tag == step6_tag)
	{

		int needLostStrength = 60-player1->skill_vector.at(1)*10;
		//当体力值足够时,角色减少相应体力值,同时隐藏技能界面,人物进行相应步数的行走
		if(player1->getStrength() >= needLostStrength)
		{
			player1->setStrength(player1->getStrength()-needLostStrength);
			refreshStrengthLabel(player1,0);
			showSkillSprites();

			int steps = tag - stepBaseTag;
			RouteNavigation::getInstance()->getPath(player1,steps,canPassGrid,tiledRowsCount,tiledColsCount);
			std::vector<int> colVector = RouteNavigation::getInstance()->getPathCols_vector();
			std::vector<int> rowVector = RouteNavigation::getInstance()->getPathRow_vector();
			NotificationCenter::getInstance()->postNotification(MSG_GO,String::createWithFormat("%d",MSG_GO_HIDE_TAG));		
			player1->startGo(rowVector,colVector);
		}else //当体力值不足时,显示提示信息
		{
			CocosToast::createToast(this,winSize/2);
		}

	}


}

//该方法进行技能界面显示,当显示时,向上移动,隐藏时,向下移动
void GameBaseScene::showSkillSprites()
{
		if(!isSkillLayerShow)
		{
			skillStorm->runAction(MoveBy::create(0.3,ccp(0,130)));
			skillStep->runAction(MoveBy::create(0.3,130)));
			skillTransfer->runAction(MoveBy::create(0.3,130)));
			isSkillLayerShow = true;
		}else
		{
			skillStorm->runAction(MoveBy::create(0.3,-130)));
			skillStep->runAction(MoveBy::create(0.3,-130)));
			skillTransfer->runAction(MoveBy::create(0.3,-130)));
			isSkillLayerShow = false;

			if(isStepLayerShow)
			{
				showStepButton(!isStepLayerShow);
				isStepLayerShow = !isStepLayerShow;
			}


		}
}

5、添加对手机器人技能
void RicherGameController::pickOnePlayerToGo()
{
	...............
		if(richerPlayer->getTag() == PLAYER_1_TAG )
			{
				NotificationCenter::getInstance()->postNotification(MSG_GO,MSG_GO_SHOW_TAG));
				return;
			}
		//当不是第一角色时
		if(richerPlayer->stop_x > 0)
		{
			//获取角色所在地块id值
			int gid = GameBaseScene::landLayer->getTileGIDAt(ccp(richerPlayer->stop_x,richerPlayer->stop_y));
			//如果地块不是自己的,则随机使用技能
			if(gid != GameBaseScene::blank_land_tiledID && gid != GameBaseScene::player2_building_1_tiledID && gid != GameBaseScene::player2_building_2_tiledID && gid != GameBaseScene::player2_building_3_tiledID)
			{	//获取角色体力
				int playerStrength = richerPlayer->getStrength();
				//随机取得要使用的技能
				int randomSkill_index = rand()%3;
				int needLostStrength = 0;
				int landLevel = 0;
				//记录地块的等级
				if(gid == GameBaseScene::player1_building_1_tiledID)
				{
					landLevel =  GameBaseScene::player2_building_1_tiledID;
				}
				if(gid == GameBaseScene::player1_building_2_tiledID)
				{
					landLevel =  GameBaseScene::player2_building_2_tiledID;
				}
				if(gid == GameBaseScene::player1_building_3_tiledID)
				{
					landLevel =  GameBaseScene::player2_building_3_tiledID;
				}
				//获取使用技能需要耗费的体力
				switch(randomSkill_index)
				{
				case 0:
					{
						needLostStrength = 80-richerPlayer->skill_vector.at(0)*10;
						break;
					}
				case 1:
					{
					
					}
				case 2:
					{
						needLostStrength = 110-richerPlayer->skill_vector.at(2)*10;
						break;
					}
				}
				//如果角色体力值满足要求,发送使用技能的消息,然后方法返回
				if(playerStrength >= needLostStrength)
				{
					String * str = String::createWithFormat("%d-%f-%f-%d-%d-%d-%d",MSG_USE_SKILL_TAG,richerPlayer->stop_x,richerPlayer->stop_y,richerPlayer->getTag(),randomSkill_index,needLostStrength,landLevel);
					NotificationCenter::getInstance()->postNotification(MSG_USE_SKILL,str);
					return;
				}

			}

		}
		如果地块是自己的时候,角色则行走
		int randNumber = rand()%6 + 1; 
		RouteNavigation::getInstance()->getPath(richerPlayer,randNumber,GameBaseScene::canPassGrid,GameBaseScene::tiledRowsCount,GameBaseScene::tiledColsCount);
		richerPlayer->startGo(RouteNavigation::getInstance()->getPathRow_vector(),RouteNavigation::getInstance()->getPathCols_vector());
		return;
	}

}

//当角色收到消息时
void GameBaseScene::receivedNotificationOMsg(Object* data)
{
	...............
	case MSG_USE_SKILL_TAG:
		{
			//获取角色的tag 
			int playerTag = messageVector.at(3)->intValue();
			//角色要使用的技能
			int kill_index =  messageVector.at(4)->intValue();
			//使用技能需要耗费的体力
			int needLostStrength = messageVector.at(5)->intValue();
			//当前地块的等级
			int landLevel = messageVector.at(6)->intValue();
			
			if(playerTag == PLAYER_2_TAG)
			{
				//让角色减少相应的体力
				player2->setStrength(player2->getStrength()-needLostStrength);
				refreshStrengthLabel(player2,0);
				Point pointOfGL = Util::map2GL(ccp(player2->stop_x,player2->stop_y),_map);
				//播放技能相应动画
				switch(kill_index)
				{
					case 0://暴风骤雨
					{
						rainSprite = Sprite::createWithSpriteFrame(player2->getRainSkill()->getAnimation()->getFrames().at(0)->getSpriteFrame());
						addChild(rainSprite);
						rainSprite->setAnchorPoint(ccp(0,0));
						rainSprite->setPosition(pointOfGL+ccp(-tiledWidth/2,tiledHeight/2));
						//动画播放完毕后,设置地块为空地块。并发送角色继续行走的消息
						rainSprite->runAction(Sequence::create(player2->getRainSkill(),CallFunc::create([this]()
						{
							landLayer->setTileGID(blank_land_tiledID,ccp(player2->stop_x,player2->stop_y));	
							rainSprite->removeFromParent();
							NotificationCenter::getInstance()->postNotification(MSG_PICKONE_TOGO,MSG_PICKONE_TOGO_TAG));
						}),NULL));
						break;
					}
					case 1://随心步,这个方法暂时不写,后期大家可以自己添加
						{
							
						}
					case 2://巧取豪夺
						{
							transferSprite = Sprite::createWithSpriteFrame(player2->getTransfer_skill()->getAnimation()->getFrames().at(0)->getSpriteFrame());
							addChild(transferSprite);
			
							transferSprite->setAnchorPoint(ccp(0,0));
							transferSprite->setPosition(pointOfGL);
							//动画播放完毕后,设置地块为自己相应等级地块。并发送角色继续行走的消息
							transferSprite->runAction(Sequence::create(player2->getTransfer_skill(),landLevel]()
							{
								landLayer->setTileGID(landLevel,player2->stop_y));	
								transferSprite->removeFromParent();
								NotificationCenter::getInstance()->postNotification(MSG_PICKONE_TOGO,MSG_PICKONE_TOGO_TAG));
							}),NULL));

						
							break;
						}
				}

			}

			break;
		}	
	
	...............

}

至此人物技能基本流程结束


代码中其他修改部分:


骰子动画效果感觉有些多余,代码中注释掉了
添加了机器人角色购买股票的代码


点击下载代码


未完待续...............

猜你在找的Cocos2d-x相关文章