接下来添加攻击按钮用于执行攻击动作。
同时修复了上一版移动时的bug。
修复后的Player::walkTo()函数:

void Player::walkTo(Vec2 dest)
{ if (_seq)
this->stopAction(_seq);
auto curPos = this->getPosition();
if (curPos.x > dest.x)
this->setFlippedX(true);
else
this->setFlippedX(false);
auto diff = dest - curPos;
auto time = diff.getLength() / _speed;
auto moveTo = MoveTo::create(time, dest);
auto func = [&]()
{
this->stopAllActions();
this->playAnimationForever("stay");
_seq = nullptr;
};
auto callback = CallFunc::create(func);
this->stopAllActions();
this->playAnimationForever("walk");
_seq = Sequence::create(moveTo, callback, nullptr); this->runAction(_seq);
}

在MainScene::init()函数中添加了攻击按钮:

    auto attackItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(MainScene::attackCallback, this)); attackItem->setPosition(Vec2(origin.x + visibleSize.width - attackItem->getContentSize().width/ ,
origin.y + attackItem->getContentSize().height/)); // create menu, it's an autorelease object
auto menu = Menu::create(attackItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, );

增加了攻击的回调函数:

void MainScene::attackCallback(Ref* pSender)
{
_hero->stopAllActions();
_hero->playAnimation("attack");
}

增加了Player::playAnimation()函数,执行了一次动作之后又回返回重复执行"stay"。

void Player::playAnimation(std::string animationName)
{
auto str = String::createWithFormat("%s-%s", _name.c_str(), animationName.c_str())->getCString();
bool exist = false;
for (int i = ; i < _animationNum; i ++) {
if (animationName == _animationNames[i])
{
exist = true;
break;
}
}
if (exist == false)
return;
auto animation = AnimationCache::getInstance()->getAnimation(str);
auto func = [&]()
{
this->stopAllActions();
this->playAnimationForever("stay");
_seq = nullptr;
};
auto callback = CallFunc::create(func);
auto animate = Sequence::create(Animate::create(animation), callback,NULL);
this->runAction(animate);
}

效果:

#ifndef __Player__
#define __Player__
#include "cocos2d.h" USING_NS_CC; class Player : public Sprite
{
public:
enum PlayerType
{
HERO,
ENEMY
};
bool initWithPlayerType(PlayerType type);
static Player* create(PlayerType type);
void addAnimation();
void playAnimationForever(std::string animationName);
void playAnimation(std::string animationName);
void walkTo(Vec2 dest);
private:
PlayerType _type;
std::string _name;
int _animationNum = ;
float _speed;
std::vector<int> _animationFrameNums;
std::vector<std::string> _animationNames;
Sequence* _seq;
}; #endif

Player.h

#include "Player.h"
#include <iostream> bool Player::initWithPlayerType(PlayerType type)
{
std::string sfName = "";
std::string animationNames[] = {"attack", "dead", "hit", "stay", "walk"};
_animationNames.assign(animationNames,animationNames+);
switch (type)
{
case PlayerType::HERO:
{
_name = "hero";
sfName = "hero-stay0000.png";
int animationFrameNums[] = {, , , , };
_animationFrameNums.assign(animationFrameNums, animationFrameNums+);
_speed = ;
break;
}
case PlayerType::ENEMY:
{
_name = "enemy";
sfName = "enemy-stay0000.png";
int animationFrameNums[] = {, , , , };
_animationFrameNums.assign(animationFrameNums, animationFrameNums+);
break;
}
}
this->initWithSpriteFrameName(sfName);
this->addAnimation();
return true;
}
Player* Player::create(PlayerType type)
{
Player* player = new Player();
if (player && player->initWithPlayerType(type))
{
player->autorelease();
return player;
}
else
{
delete player;
player = NULL;
return NULL;
}
}
void Player::addAnimation()
{
auto animation = AnimationCache::getInstance()->getAnimation(String::createWithFormat("%s-%s", _name.c_str(),
_animationNames[].c_str())->getCString());
if (animation)
return;
for (int i = ; i < _animationNum; i ++)
{
auto animation = Animation::create();
animation->setDelayPerUnit(1.0f / 10.0f);
for (int j = ; j < _animationFrameNums[i]; j ++)
{
auto sfName = String::createWithFormat("%s-%s%04d.png", _name.c_str(), _animationNames[i].c_str(), j)->getCString();
animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(sfName));
if (!animation)
log("hello ha ha");
}
AnimationCache::getInstance()->addAnimation(animation, String::createWithFormat("%s-%s", _name.c_str(),
_animationNames[i].c_str())->getCString());
}
}
void Player::playAnimationForever(std::string animationName)
{
auto str = String::createWithFormat("%s-%s", _name.c_str(), animationName.c_str())->getCString();
bool exist = false;
for (int i = ; i < _animationNum; i ++) {
if (animationName == _animationNames[i])
{
exist = true;
break;
}
}
if (exist == false)
return;
auto animation = AnimationCache::getInstance()->getAnimation(str);
auto animate = RepeatForever::create(Animate::create(animation));
this->runAction(animate);
} void Player::playAnimation(std::string animationName)
{
auto str = String::createWithFormat("%s-%s", _name.c_str(), animationName.c_str())->getCString();
bool exist = false;
for (int i = ; i < _animationNum; i ++) {
if (animationName == _animationNames[i])
{
exist = true;
break;
}
}
if (exist == false)
return;
auto animation = AnimationCache::getInstance()->getAnimation(str);
auto func = [&]()
{
this->stopAllActions();
this->playAnimationForever("stay");
_seq = nullptr;
};
auto callback = CallFunc::create(func);
auto animate = Sequence::create(Animate::create(animation), callback,NULL);
this->runAction(animate);
} void Player::walkTo(Vec2 dest)
{
if (_seq)
this->stopAction(_seq);
auto curPos = this->getPosition();
if (curPos.x > dest.x)
this->setFlippedX(true);
else
this->setFlippedX(false);
auto diff = dest - curPos;
auto time = diff.getLength() / _speed;
auto moveTo = MoveTo::create(time, dest);
auto func = [&]()
{
this->stopAllActions();
this->playAnimationForever("stay");
_seq = nullptr;
};
auto callback = CallFunc::create(func);
this->stopAllActions();
this->playAnimationForever("walk");
_seq = Sequence::create(moveTo, callback, nullptr); this->runAction(_seq);
}

Player.cpp

#ifndef __MainScene__
#define __MainScene__ #include "cocos2d.h"
#include "Player.h" USING_NS_CC; class MainScene : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
void menuCloseCallback(cocos2d::Ref* pSender);
CREATE_FUNC(MainScene);
bool onTouchBegan(Touch* touch, Event* event);
void attackCallback(Ref* pSender);
private:
Player* _hero;
Player* _enemy;
EventListenerTouchOneByOne* _listener_touch;
}; #endif

MainScene.h

#include "MainScene.h"
#include "FSM.h" Scene* MainScene::createScene()
{
auto scene = Scene::create();
auto layer = MainScene::create();
scene->addChild(layer);
return scene;
}
bool MainScene::init()
{
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin(); SpriteFrameCache::getInstance()->addSpriteFramesWithFile("images/role.plist","images/role.png"); Sprite* background = Sprite::create("images/background.png");
background->setPosition(origin + visibleSize/);
this->addChild(background); //add player
_hero = Player::create(Player::PlayerType::HERO);
_hero->setPosition(origin.x + _hero->getContentSize().width/, origin.y + visibleSize.height/);
this->addChild(_hero); //add enemy1
_enemy = Player::create(Player::PlayerType::ENEMY);
_enemy->setPosition(origin.x + visibleSize.width - _enemy->getContentSize().width/, origin.y + visibleSize.height/);
this->addChild(_enemy); _hero->playAnimationForever("stay");
_enemy->playAnimationForever("stay"); _listener_touch = EventListenerTouchOneByOne::create();
_listener_touch->onTouchBegan = CC_CALLBACK_2(MainScene::onTouchBegan,this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(_listener_touch, this); auto attackItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(MainScene::attackCallback, this)); attackItem->setPosition(Vec2(origin.x + visibleSize.width - attackItem->getContentSize().width/ ,
origin.y + attackItem->getContentSize().height/)); // create menu, it's an autorelease object
auto menu = Menu::create(attackItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, ); return true;
}
void MainScene::menuCloseCallback(cocos2d::Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
return;
#endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit();
#endif
} bool MainScene::onTouchBegan(Touch* touch, Event* event)
{
Vec2 pos = this->convertToNodeSpace(touch->getLocation());
_hero->walkTo(pos);
log("MainScene::onTouchBegan");
return true;
} void MainScene::attackCallback(Ref* pSender)
{
_hero->stopAllActions();
_hero->playAnimation("attack");
}

MainScene.cpp

cocos2dx游戏--欢欢英雄传说--添加攻击按钮的更多相关文章

  1. cocos2dx游戏--欢欢英雄传说--添加游戏背景

    经过一段时间的学习cocos2dx,接下来我想要实践开发一个小游戏,我把它命名为“欢欢英雄传说”,项目名将取为HuanHero.环境:cocos2dx环境:cocos2d-x 3.11.1IDE:Co ...

  2. cocos2dx游戏--欢欢英雄传说--添加动作

    添加完人物之后接着给人物添加上动作.我们为hero添加4个动作:attack(由3张图片构成),walk(由2张图片构成),hit(由1张图片构成),dead(由1张图片构成):同样,为enemy添加 ...

  3. cocos2dx游戏--欢欢英雄传说--添加人物

    接下来需要导入精灵帧资源,因为之前下载了TexturePacker,然后通过TexturePacker的"Publish sprite sheet"方法可以生成一个.pvr.ccz ...

  4. cocos2dx游戏--欢欢英雄传说--添加触摸响应

    主要的调整就是将HelloWorldScene改成了MainSecne,然后将Player作为了MainScene的私有成员变量来处理.修改了人物图片,使用了网上找到的三国战纪的人物素材代替我之前画的 ...

  5. cocos2dx游戏--欢欢英雄传说--为敌人添加移动和攻击动作

    这里主要为敌人添加了一个移动动作和攻击动作.移动动作是很简略的我动他也动的方式.攻击动作是很简单的我打他也打的方式.效果:代码: #ifndef __Progress__ #define __Prog ...

  6. cocos2dx游戏--欢欢英雄传说--添加血条

    用一个空血槽图片的Sprite做背景,上面放一个ProgressTimer, 通过设置ProgressTimer的进度来控制血条的长短.建立一个Progress类来实现.Progress.h: #if ...

  7. cocos2d-x游戏引擎核心之六——绘图原理和绘图技巧

    一.OpenGL基础 游戏引擎是对底层绘图接口的包装,Cocos2d-x 也一样,它是对不同平台下 OpenGL 的包装.OpenGL 全称为 Open Graphics Library,是一个开放的 ...

  8. Cocos2dx游戏开发系列笔记13:一个横版拳击游戏Demo完结篇

    懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 ) 写下这些东西的同时 旁边放了两部电影 周星驰的<还魂夜> 甄子丹的<特殊身份& ...

  9. Android Cocos2d-x游戏集成友盟社会化组件分享功能

    最近在帮助开发者集成友盟社会化组件的过程中,发现游戏的集成过程遇到一些困难,而Cocos2d-x具有较好的代表性,因此整理了一篇关于Android Cocos2d-x游戏集成友盟社会化组件指南,由于本 ...

随机推荐

  1. ADO中记录集recordSet的使用

    _RecordsetPtr使用方法 _variant_t vUsername,vID,vname; //变量声明_RecordsetPtr m_pRecordset;     //记录集CString ...

  2. 【Visual Studio】切换版本控制工具插件

    需求:安装了VS的某些版本控制工具的插件(比如Svn的插件AnkhSvn),但是打开VS后依然使用的是默认的版本控制工具,想要切换. Tool –> Options –> Source C ...

  3. Linux下Kill函数用法

    http://www.cnblogs.com/winnxm/archive/2010/01/22/1654502.html 用于向任何进程组或进程发送信号. #include <sys/type ...

  4. kernel printk信息显示级别

    涉及文件:kernel/printk.c include/linux/kernel.h用printk内核会根据日志级别把消息打印到当前控制台上.信息正常输出前提是--日志输出级别(msg_log_le ...

  5. 总结golang之map

    总结golang之map 2017年04月13日 23:35:53 趁年轻造起来 阅读数:18637 标签: golangmapgo 更多 个人分类: golang   版权声明:本文为博主原创文章, ...

  6. 实现字符串转化为整数函数atoi()函数

    函数原型: int atoi(const char *nptr); 函数说明: 参数nptr字符串,如果第一个非空格字符存在,并且,如果不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数 ...

  7. ThinkPHP U函数生成URL伪静态

    ThinkPHP支持伪静态URL设置,可以通过设置URL_HTML_SUFFIX参数随意在URL的最后增加你想要的静态后缀,而不会影响当前操作的正常执行.例如,我们设置 'URL_HTML_SUFFI ...

  8. 关于矢量图片资源向后兼容:CompatVectorFromResourcesEnabled标志的使用

    StackOverflow上摘抄的: some things have changed since I asked this question so I will answer it myself.W ...

  9. Android Studio编译错误:Unexpected lock protocol found in lock file. Expected 3, found 0.

    如果不小心手动修改了.gradle文件夹中的内容,那么再打开之前编译成功的工程时,会出现类似下面的错误: Gradle app neame project refresh failed: Unexpe ...

  10. DirectoryEntry 账户启动与停用 以及创建账户等

    启动账户: DirectoryEntry usr = new DirectoryEntry("LDAP://CN=New User,CN=users,DC=fabrikam,DC=com&q ...