今天要讲的使我们猪脚类
SpriteBird.h
SpriteBird.cpp
猪脚类要注意的是三种状态的切换,和单点触控侦听的设置,还有就是小鸟在飞行的过程中,头部会上下的摆动,物理模型这里就不说了,小鸟头部的摆动是靠小鸟Y轴的速度来判定的,当小鸟向上飞的时候,速度是正的,所以头部摆动的旋转角度也是向上,当小鸟下落的时候,速度是负的,所以头部摆动的旋转角度是向下的。
小鸟的三种状态:
下面是代码
//SpriteBird.h
#pragma once
#include "cocos2d.h"
//小鸟的三种状态
typedef enum ActionState
{
ACTION_STATE_IDLE, //空闲状态
ACTION_STATE_FLY, //飞行状态
ACTION_STATE_DIE //死亡状态
};
class SpriteBird:public cocos2d::Layer
{
public:
SpriteBird();
~SpriteBird();
static SpriteBird * createBird();
//状态转换函数
void changeState(ActionState);
//转换成空闲状态
void stateIdle();
//转换成飞行状态
void stateFly();
//转换成死亡状态
void stateDie();
bool init();
void update(float);
CREATE_FUNC(SpriteBird);
private:
//小鸟精灵
cocos2d::Sprite * sprite_bird;
//当前状态
ActionState bird_state;
//侦听对象
cocos2d::EventListenerTouchOneByOne * listener;
};
//SpriteBird.cpp
#include "SpriteBird.h"
#include "define.h"
USING_NS_CC;
SpriteBird::SpriteBird()
{
}
SpriteBird::~SpriteBird()
{
}
bool SpriteBird::init()
{
if (!Layer::init())
{
return false;
}
auto origin=Director::getInstance()->getVisibleOrigin();
auto visibleSize=Director::getInstance()->getVisibleSize();
Animate * animate;
//下面是随即产生三种小鸟(红色,黄色,蓝色),并实例对应的飞行动画
switch (int temp=int(rand()%3+1))
{
case 1:
{
sprite_bird=Sprite::createWithSpriteFrameName("bird0_0.png");
animate=Animate::create(AnimationCache::getInstance()->getAnimation(BIRDANIMATION_0));
sprite_bird->runAction(RepeatForever::create(animate));
break;
};
case 2:
{
sprite_bird=Sprite::createWithSpriteFrameName("bird1_0.png");
animate=Animate::create(AnimationCache::getInstance()->getAnimation(BIRDANIMATION_1));
sprite_bird->runAction(RepeatForever::create(animate));
break;
};
case 3:
{
sprite_bird=Sprite::createWithSpriteFrameName("bird2_0.png");
animate=Animate::create(AnimationCache::getInstance()->getAnimation(BIRDANIMATION_2));
sprite_bird->runAction(RepeatForever::create(animate));
break;
};
default:
{
log("bird:%d",temp);
break;
}
}
//这里是小鸟的物理模型,这里不多讲了,具体看上一章
PhysicsBody * body=PhysicsBody::create();
//小鸟的刚体是个圆
body->addShape(PhysicsShapeCircle::create(BIRD_RADIUS));
body->setDynamic(true);
body->setLinearDamping(0.7f);
body->setGravityEnable(false);
body->setCategoryBitmask(1);
body->setCollisionBitmask(-1);
body->setContactTestBitmask(-1);
sprite_bird->setPhysicsBody(body);
sprite_bird->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.6));
this->addChild(sprite_bird);
//下面是小鸟的点击侦听,listener是单点触控
//每次点击小鸟都会向上(Y轴)飞一段距离
//这里我们就给它赋值一个初速度(Y轴)
listener=EventListenerTouchOneByOne::create();
//设置触控是否向下传递
listener->setSwallowTouches(false);
//点击开始(单点触控一般分为三种状态,触控开始(onTouchBegan),移动(onTouchMove),触控结束(onTouchEnd))
//这里只用到了触控开始和结束
listener->onTouchBegan=[=](Touch * t,Event *e)
{
//触控开始时什么都不做
//注意这里要有返回值(bool)
log("touch begin");
return true;
};
listener->onTouchEnded=[=](Touch *t,Event *e)
{
//触控结束时,播放音效
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_wing.mp3");
//给小鸟一个初速度
sprite_bird->getPhysicsBody()->setVelocity(VELOCITY);
//注意这边没有返回值
};
//这里开了个定时器,防止小鸟飞出边界,和小鸟头部旋转角度设置
this->scheduleUpdate();
return true;
}
//创造小鸟对象
SpriteBird * SpriteBird::createBird()
{
SpriteBird * temp=new SpriteBird();
temp->init();
return temp;
}
//小鸟三种状态的切换
void SpriteBird::changeState( ActionState as)
{
switch (as)
{
case ACTION_STATE_IDLE:
stateIdle();
break;
case ACTION_STATE_FLY:
stateFly();
break;
case ACTION_STATE_DIE:
stateDie();
break;
default:
break;
}
}
//切换到空闲状态
//1:把小鸟添加到点击侦听中去
//2:小鸟移除重力感应(因为在这个状态下,小鸟是悬停在空中的)
void SpriteBird::stateIdle()
{
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite_bird);
sprite_bird->getPhysicsBody()->setGravityEnable(false);
}
//切换到飞行状态
//设置重力感应
void SpriteBird::stateFly()
{
sprite_bird->getPhysicsBody()->setGravityEnable(true);
}
//切换到死亡状态
void SpriteBird::stateDie()
{
//播放音效
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_die.mp3");
//关闭定时器
this->unscheduleUpdate();
//移除点击侦听
_eventDispatcher->removeEventListener(listener);
//开启重力感应(因为死亡后会自由落体.....)
sprite_bird->getPhysicsBody()->setGravityEnable(true);
//停止小鸟的所有动画
sprite_bird->stopAllActions();
//设置角度,头向下...
sprite_bird->setRotation(BIRD_DIE_ROTATION);
}
void SpriteBird::update( float )
{
auto origin=Director::getInstance()->getVisibleOrigin();
auto visibleSize=Director::getInstance()->getVisibleSize();
//防止飞出边界
if (sprite_bird->getPositionY()>(origin.y+visibleSize.height))
{
sprite_bird->setPositionY(origin.y+visibleSize.height);
}
//小鸟的飞行头部的角度,根据飞行的Y轴速度决定
sprite_bird->setRotation(sprite_bird->getPhysicsBody()->getVelocity().y*-0.1);
}
结束