这里主要为敌人添加了一个移动动作和攻击动作。
移动动作是很简略的我动他也动的方式。
攻击动作是很简单的我打他也打的方式。
效果:
代码:
#ifndef __Progress__
#define __Progress__
#include "cocos2d.h"
USING_NS_CC; class Progress : public Sprite
{
public:
bool init(const char* background, const char* fillname);
/*
the inputs are SpriteFrame Names.
they should be loaded into SpriteFrameCache before calling this.
*/
static Progress* create(const char* background, const char* fill); void setFill(ProgressTimer* fill){_fill=fill;} void setProgress(float percentage){_fill->setPercentage(percentage);}
float getProgress() { return _fill->getPercentage(); } private:
ProgressTimer* _fill;
};
#endif
Progress.h
#include "Progress.h" bool Progress::init(const char* background, const char* fillname)
{
this->initWithSpriteFrameName(background);
ProgressTimer* fill = ProgressTimer::create(Sprite::createWithSpriteFrameName(fillname));
this->setFill(fill);
this->addChild(fill); fill->setType(ProgressTimer::Type::BAR);
fill->setMidpoint(Point(,0.5));
fill->setBarChangeRate(Point(1.0, ));
fill->setPosition(this->getContentSize()/);
fill->setPercentage();
return true;
} Progress* Progress::create(const char* background, const char* fillname)
{
Progress* progress = new Progress();
if(progress && progress->init(background,fillname))
{
progress->autorelease();
return progress;
}
else
{
delete progress;
progress = NULL;
return NULL;
}
}
Progress.cpp
#ifndef __Player__
#define __Player__
#include "cocos2d.h"
#include "Progress.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);
Sequence* getSeq() { return _seq; }
void getHit();
void autoDoAction(Player* hero);
void autoAttack(Player* hero);
Progress* getProgress() { return _progress; }
private:
PlayerType _type;
std::string _name;
int _animationNum = ;
float _speed;
std::vector<int> _animationFrameNums;
std::vector<std::string> _animationNames;
Sequence* _seq;
Progress* _progress;
bool _isShowBar;
}; #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";
_isShowBar = false;
int animationFrameNums[] = {, , , , };
_animationFrameNums.assign(animationFrameNums, animationFrameNums+);
_speed = ;
break;
}
case PlayerType::ENEMY:
{
_name = "enemy";
sfName = "enemy-stay0000.png";
_isShowBar = true;
int animationFrameNums[] = {, , , , };
_animationFrameNums.assign(animationFrameNums, animationFrameNums+);
_speed = ;
break;
}
}
this->initWithSpriteFrameName(sfName);
this->addAnimation(); auto size = this->getContentSize();
_progress = Progress::create("small-enemy-progress-bg.png","small-enemy-progress-fill.png");
_progress->setPosition( size.width/, size.height + _progress->getContentSize().height/);
this->addChild(_progress);
if(!_isShowBar)
{
_progress->setVisible(false);
} return true;
}
Player* Player::create(PlayerType type)
{
Player* player = new Player();
if (player && player->initWithPlayerType(type))
{
player->autorelease();
player->setAnchorPoint(Vec2(0.5, ));
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);
} void Player::getHit()
{
float blood = _progress->getProgress();
if (_name == "hero")
blood -= ;
else
blood -= ;
_progress->setProgress(blood);
log(String::createWithFormat("hit now blood is %f", blood)->getCString());
if (blood <= )
{
log(String::createWithFormat("%s is dead.", _name.c_str())->getCString());
auto func = [&]()
{
this->stopAllActions();
this->playAnimation("dead");
};
auto callback = CallFunc::create(func);
_seq = Sequence::create(callback, nullptr);
this->runAction(_seq);
this->_progress->setVisible(false);
this->setVisible(false);
return;
}
} void Player::autoDoAction(Player* hero) // just for _enemy
{
Vec2 dest = hero->getPosition();
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;
if (diff.x > ) diff.x -= ;
else diff.x += ;
if (diff.y > ) diff.y -= ;
else diff.y += ;
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);
} void Player::autoAttack(Player* hero) // just for _enemy
{
float blood = _progress->getProgress();
if (blood <= )
return;
Vec2 del = this->getPosition() - hero->getPosition();
if (del.length() <= )
{
this->playAnimation("attack");
hero->getHit();
}
}
Player.cpp
#ifndef __MainScene__
#define __MainScene__ #include "cocos2d.h"
#include "Player.h"
#include "Progress.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;
Progress* _progress;
}; #endif
MainScene.h
#include "MainScene.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");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("images/ui.plist","images/ui.pvr.ccz"); 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, ); _progress = Progress::create("player-progress-bg.png","player-progress-fill.png");
_progress->setPosition(_progress->getContentSize().width/, this->getContentSize().height - _progress->getContentSize().height/);
this->addChild(_progress); 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");
_enemy->autoDoAction(_hero);
return true;
} void MainScene::attackCallback(Ref* pSender)
{
_hero->stopAllActions();
_hero->playAnimation("attack");
Vec2 del = _hero->getPosition() - _enemy->getPosition();
float distance = del.length();
log(String::createWithFormat("distance == %f", distance)->getCString());
if (distance <= 100.0) {
_enemy->getHit();
}
_enemy->autoAttack(_hero);
_progress->setProgress(_hero->getProgress()->getProgress());
}
MainScene.cpp
------------华丽的分割线------------
最近工作上出了一点事情。可能暂时就写到这里了。希望以后有机会能够再补上接下来的内容。
参考教程:http://www.cocos.com/doc/tutorial/lists?id=85
项目github地址:https://github.com/moonlightpoet/HuanHero