Hero.h
#ifndef _HERO_H
#define _HERO_H_
#include "cocos2d.h"
USING_NS_CC;
//只需设置初始位置。
class Hero : public Sprite
{
private:
enum Message { up = 1001, left, right, down, stay, sleep, over };//消息协议
Layer* _layer;
int _message;//消息存储器
int _actMessage = stay;//初始动作消息
Vec2 _pointRecord;//位置记录器
private:
std::string _plist;
std::string _png;
Sprite* upIng;
Sprite* downIng;
Sprite* leftIng;
Sprite* rightIng;
Sprite* stayIng;
Sprite* sleepIng;
Sprite* overIng;
private:
bool _bodyInit();//初始化身体
bool _spriteInit();//初始化精灵
void _dealWithMessage();//消息分发处理器
void _dealWithActionMessage();//动作消息处理器
public:
int height;//在外部使用
int overHeight = 0;
public:
Hero();
~Hero();
virtual bool init(Layer* layer, std::string plist, std::string png);
virtual void update(float dt);
public:
//检测角色位置,并发出移动命令,参数为地面高度
virtual void heroListener(float positionY);
//强制移动命令
virtual void actionCommander(int act);
//得到当前hero状态
int getMessage();
//** this layer, Hero's plist and png.
//* Uping.png, Downing.png, Lefting.png, Righting.png, Staying.png, Sleeping.png, Overing.png
static Hero* create(Layer* layer, std::string plist, std::string png);//利用静态全局方法可以引入外部指针
};
#endif
/**
*注意:类对象收集在自己外部的信息,传入内部做出反应。外部只需设置对象的监听或强制命令。
*
//
消息处理机制:
private:
0.消息存储器 _message :负责存储消息。
1.消息协议 enum Message { up = 1001, left, right, down, stay, sleep, over }。
2.消息处理器 _dealWithMessage :放置在自己的循环中,对收集到的消息进行识别处理。
public:
3.消息收听者 heroListener() :放置在主循环中持续收听并收集信息。
4.强制命令 actionCommander(int message) :直接指定角色消息。
//
static静态取出[外部类容器]机制:
private:
1.容器地址副本 Layer* _layer;
2.复制地址方法 void copyAdress(Layer* layer);//保存容器的地址。
public:
3.创造函数static 类名* create(容器* );//new一个该类对象并autorelease,调用copyAdress,最后返回。
//
this指针取入该类对象的指针进行调用该类的方法。
//
*/
Hero.cpp
#include "Hero.h"
Hero::Hero()
{
}
Hero::~Hero()
{
this->unscheduleUpdate();//析构时停止该类的update更新。
}
bool Hero::init(Layer* layer, std::string plist, std::string png)
{
_plist = plist;
_png = png;
_layer = layer;
if (!Sprite::init())
{
return false;
}
//初始化身体
if (!_bodyInit())
{
return false;
}
//初始化精灵
if (!_spriteInit())
{
return false;
}
scheduleUpdate();//注册更新函数
return true;
}
void Hero::update(float dt)//更新函数,使角色处于应激状态。
{
_dealWithMessage();
}
int Hero::getMessage()
{
return _message;
}
bool Hero::_bodyInit()
{//设置身体属性
Size s = Size(50, 45);
setContentSize(s);//设置显示大小
setPhysicsBody(PhysicsBody::createBox(s));
getPhysicsBody()->setRotationEnable(false);
getPhysicsBody()->setContactTestBitmask(1);
setPosition(50, getContentSize().height + 80);
_pointRecord =getPosition();//记录器初始化
_actMessage = stay;//初始状态为stay
return true;
}
bool Hero::_spriteInit()
{
// 首先读取plist
SpriteFrameCache* sfc = SpriteFrameCache::getInstance();
sfc->addSpriteFramesWithFile(_plist, _png);
upIng = Sprite::createWithSpriteFrameName("Uping.png");
downIng = Sprite::createWithSpriteFrameName("Downing.png");
leftIng = Sprite::createWithSpriteFrameName("Lefting.png");
rightIng = Sprite::createWithSpriteFrameName("Righting.png");
stayIng = Sprite::createWithSpriteFrameName("Staying.png");
sleepIng = Sprite::createWithSpriteFrameName("Sleeping.png");
overIng = Sprite::createWithSpriteFrameName("Overing.png");
_layer->addChild(upIng);
_layer->addChild(downIng);
_layer->addChild(leftIng);
_layer->addChild(rightIng);
_layer->addChild(stayIng);
_layer->addChild(sleepIng);
_layer->addChild(overIng);
return true;
}
void Hero::_dealWithMessage()//处理消息
{//分发消息
if (_message == up || _message == down || _message == left || _message == right || _message == stay || _message == sleep || _message == over)
{//如果是动作消息
_actMessage = _message;//存储动作消息,并调用动作消息处理器
_dealWithActionMessage();
}
}
void Hero::_dealWithActionMessage()
{//处理动作消息
//GirlAction0000 - 0006
switch (_actMessage)
{
case up: upIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I am up");//正常
break;
case down: downIng->setPosition(this->getPosition());
upIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I am down");
break;
case left: leftIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
upIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I go left");
break;
case right: rightIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
upIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I go right");
break;
case stay: stayIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
upIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I am staying");
break;
case sleep: sleepIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
upIng->setPosition(Point::ZERO);
overIng->setPosition(Point::ZERO);
log("I am sleeping");
break;
case over: overIng->setPosition(this->getPosition());
downIng->setPosition(Point::ZERO);
leftIng->setPosition(Point::ZERO);
rightIng->setPosition(Point::ZERO);
stayIng->setPosition(Point::ZERO);
sleepIng->setPosition(Point::ZERO);
upIng->setPosition(Point::ZERO);
log("I am over");
break;
default:
break;
}
}
void Hero::actionCommander(int message)
{
_message = message;//已收到强制命令。
}
Hero * Hero::create(Layer* layer, std::string plist, std::string png)
{
auto hero = new Hero();
hero->init(layer, plist, png);
hero->autorelease();
return hero;
}
void Hero::heroListener(float positionY)
{
if (this->getPosition() == _pointRecord)
{//静止状态
_message = stay;
if (overHeight && (height < 50))
{
_message = over;
}
}
else
{//移动状态
if (this->getPosition().y <= this->getContentSize().height + positionY)//考虑地板高度
{//如果在地上
if (this->getPosition().x < _pointRecord.x)
{///如果往左走
_message = left;
}
else
{///如果往右走
_message = right;
}
}
else
{//如果在空中
if (this->getPosition().y > _pointRecord.y)
{///如果上升
_message = up;
}
else
{///如果下降
_message = down;
}
}
}
_pointRecord = this->getPosition();//判断完毕,更新位置
}
实例化一个对象
//add hero
hero = Hero::create(_layer, "GirlAction.plist", "GirlAction.png");
hero->setPosition(50, hero->getContentSize().height + 80);
height = 0;//hero初始高度为0;
_layer->addChild(hero, 1);//添加hero到显示层
我刚学习时间不长,可能写的有些地方有问题。
如果有什么意见可以提出~