接下来添加攻击按钮用于执行攻击动作。
同时修复了上一版移动时的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. 在shell 中字符串,文件,数字的比较

    hadoop fs -test -e /path/exist ] ;then echo 'exist' else echo 'Error! path is not exist' fi 在shell中如 ...

  2. 关于Java的Properties类

    Properties类 先来学习下Properties类吧. Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串. ...

  3. htonl()函数学习

    今天在网上看到一篇关于htonl()函数的解释,感觉有道理,贴过来大家一起学习! htonl就是把本机字节顺序转化为网络字节顺序 h---host 本地主机 to 就是to 了 n ---net 网络 ...

  4. zookeeper连接 org.apache.curator.framework.imps.CuratorFrameworkImpl Background exception was not retry-able or retry gave up [main-EventThread]

    ERROR org.apache.curator.framework.imps.CuratorFrameworkImpl Background exception was not retry-able ...

  5. DataTable的AcceptChanges()和RejectChanges()方法

    一.DataTable.AcceptChanges()方法 提交自上次调用AcceptChanges()方法以来对该表进行的所有更改.调用AcceptChanges()时,任何扔处于编辑模式的Data ...

  6. Apache2.4.x版wampserver本地php服务器如何让外网访问及启用.htaccess

    http://www.jb51.net/article/61193.htm ———————————————————————————————————————————— 这篇文章主要介绍了Apache2. ...

  7. android之存储篇_SQLite数据库入门

    SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中 ...

  8. 【转】Jmeter分布式压力测试

    安装 下载地址:http://jmeter.apache.org/download_jmeter.cgi 安装前提(因为jmeter依赖于Java所以必须先配置好java) 下载后解压: tar -x ...

  9. [oracle] 重要服务启动与停止命令行

    ① 控制台服务[em control] 启动:emctl start dbconsole 停止:emctl stop dbconsole ② 监听器服务[listener control] 启动:ls ...

  10. TypeError: datetime.datetime(2016, 9, 25, 21, 12, 19, 135649) is not JSON serializable解决办法(json无法序列化对象的解决办法)

    1.一个简单的方法来修补json模块,这样序列将支持日期时间. import json import datetime json.JSONEncoder.default = lambda self, ...