1. 写笔记主要是为了同强大的忘性作斗争,学习《Cocos2d-x 3.x游戏开发之旅》所记。
2. 以下参照书本,跑出来的效果图,所以主要还是把代码贴上来,方便日后查询。3.下面开始贴代码
创建基类,为人物和金币所继承.Entity 继承与Node.
#ifndef _ENTITY_H_
#define _ENTITY_H_
#include"cocos2d.h"
USING_NS_CC;
class Entity : public Node
{
public:
Entity();
~Entity();
Sprite* getSprite();
void bindSprite(Sprite* sprite);
private:
Sprite* m_sprite;
};
#endif
#include"Entity.h"
#include"Player.h"
Entity::Entity()
{
m_sprite = NULL;
}
Entity::~Entity()
{
}
Sprite* Entity::getSprite()
{
return this->m_sprite;
}
void Entity::bindSprite(Sprite* sprite)
{
this->m_sprite = sprite;
this->addChild(m_sprite);
/*由于需要做碰撞检测,而Node的默认宽高属性(0,0),所以需要获取精灵的宽高,设置给Entity.这样Entity就有了Sprite对象的宽高。*/
Size size = m_sprite->getContentSize();
m_sprite->setPosition(Point(size.width*0.5f, size.height*0.5f));
this->setContentSize(size);
}
#ifndef _PLAYER_H_
#define _PLAYER_H_
#include"cocos2d.h"
#include"Entity.h"
using namespace cocos2d;
#define JUMP_ACTION_TAG 1
class Player : public Entity
{
public:
Player();
~Player();
CREATE_FUNC(Player);
virtual bool init();
void jump();
void hit();
int getiHP();
void resetData();
private:
bool b_isJumping;
int m_iHP;
};
#endif
#include"Player.h"
//#include"FlowWord.h"
Player::Player()
{
b_isJumping = false;
m_iHP = 1000;
}
Player::~Player()
{}
bool Player::init()
{
return true;
}
void Player::hit()//碰撞时,人物的动作
{
if(getSprite() == NULL)
{
return;
}
m_iHP -= 15;
if(m_iHP < 0)
{
m_iHP = 0;
}
//FlowWord* flowWord = FlowWord::create();
//this->addChild(flowWord);
//flowWord->showWord("-15",GetSpoolFileHandle);
auto backMove = MoveBy::create(0.1f, Point(-20, 0));
auto forwardMove = MoveBy::create(0.1f, Point(20, 0));
auto backRotate = RotateBy::create(0.1f, -5, 0);
auto forwardRotate = RotateBy::create(0.1f, 5, 0);
auto backAction = Spawn::create(backMove, backRotate, NULL);
auto forwardAction = Spawn::create(forwardMove, forwardRotate, NULL);
auto actions = Sequence::create(backAction, forwardAction, NULL);
stopAllActions();
resetData();
runAction(actions);
}
void Player::resetData()
{
if(b_isJumping)
{
b_isJumping = false;
}
setPosition(Point(200, 140));
setScale(1.0f);
setRotation(0);
}
int Player::getiHP()
{
return m_iHP;
}
void Player::jump()
{
if(getSprite() == NULL)
return;
if(b_isJumping)
return;
b_isJumping = true;
auto jump = JumpBy::create(2.0f, Point(0, 0), 250, 1);//原地跳跃,高度250像素,跳跃一次
auto callFunc = CallFunc::create([&]()
{
b_isJumping = false;
});
auto jumpAction = Sequence::create(jump, callFunc,NULL);
this->runAction(jumpAction);
}
#ifndef _MONSTER_H_
#define _MONSTER_H_
#include"Entity.h"
#include"Player.h"
class Monster:public Entity
{
public:
Monster();
~Monster();
CREATE_FUNC(Monster);
virtual bool init();
public:
void show();
void hide();
void reset();
bool isAlive();
bool isCollideWithPlayer(Player* player);
private:
bool b_isAlive;
};
#endif
#include"Monster.h"
Monster::Monster()
{
b_isAlive = false;
}
Monster::~Monster()
{}
bool Monster::init()
{
return true;
}
void Monster::show()
{
if(getSprite() != NULL)
{
setVisible(true);
b_isAlive = true;
}
}
void Monster::hide()
{
if(getSprite() != NULL)
{
setVisible(false);
reset();
b_isAlive = false;
}
}
void Monster::reset()
{
if(getSprite() != NULL)
{
setPosition(Point(800+CCRANDOM_0_1() * 2000, 200-CCRANDOM_0_1()*100));
}
}
bool Monster::isAlive()
{
return b_isAlive;
}
bool Monster::isCollideWithPlayer(Player* player)
{
if(player == NULL || getSprite() == NULL)
return false;
Rect entityRect = player->getBoundingBox();//获取碰撞检测对象的boundingBox
Point monsterPos = getPosition();
return entityRect.containsPoint(monsterPos);
}
3.金币管理类,负责金币的创建,管理。
#ifndef _MANAGERMONSTER_H_
#define _MANAGERMONSTER_H_
#include "cocos2d.h"
#include "Monster.h"
USING_NS_CC;
#define MAX_MONSTER_NUM 10
class MonsterManager:public Node
{
public:
CREATE_FUNC(MonsterManager);
virtual bool init();
virtual void update(float dt);
private :
void createMonster();
public:
void bindPlayer(Player* player);
private:
Vector m_monsterArr;//Vector容器的应用
Player* m_player;
};
#endif
#include"MonsterManager.h"
#include"Player.h"
#include"Monster.h"
bool MonsterManager::init()
{
createMonster();
this->scheduleUpdate();
return true;
}
void MonsterManager::createMonster()
{
Monster* monster = NULL;
Sprite* sprite = NULL;
for(int i = 0; i < MAX_MONSTER_NUM; i++)
{
monster = Monster::create();
monster->bindSprite(Sprite::create("monster.png"));
monster->reset();
this->addChild(monster);
m_monsterArr.pushBack(monster);
}
}
void MonsterManager::update(float dt)
{
for(auto monster:m_monsterArr)
{
if(monster == NULL)
continue;
if(monster->isAlive())
{
monster->setPositionX(monster->getPositionX() - 4);
if(monster->getPositionX() < 0)
{
monster->hide();
}
}
else
{
monster->show();
}
if(monster->getPositionX() < 0)
{
monster->hide();
}
else if(monster->isCollideWithPlayer(m_player))
{
m_player->hit();
monster->hide();
}
}
}
void MonsterManager::bindPlayer(Player* player)
{
m_player = player;
}
#ifndef _TOLLGATESCENE_H_
#define _TOLLGATESCENE_H_
#include "cocos2d.h"
using namespace cocos2d;
#include"editor-support/cocostudio/CCSGUIReader.h"
#include"ui/CocosGUI.h"
using namespace cocos2d::ui;
using namespace cocostudio;
class Player;
class TollgateScene : public Layer
{
public:
static Scene* createScene();
virtual bool init();
CREATE_FUNC(TollgateScene);
virtual void update(float delta);//update函数的调用
private:
void initBG();
void loadUI();
void jumpEvent(Ref*, TouchEventType type);
private:
Sprite* m_bg1;
Sprite* m_bg2;
Player* m_player;
int m_iScore;
Text* m_scoreLab;
LoadingBar* m_hpBar;
};
#endif
#include"TollgateScene.h"
#include"Player.h"
#include"Entity.h"
#include"cocos2d.h"
#include"MonsterManager.h"
Scene* TollgateScene::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = TollgateScene::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
bool TollgateScene::init()
{
if(!Layer::init())
{
return false;
}
//尽量不要使用多线程,Cocos2d-x的Node对象提供了一个update函数,在游戏的每一帧都会调用update函数,我们只要调用它便可以
this->scheduleUpdate();//这句表示我们开启调用update函数的功能
Size visibleSize = Director::getInstance()->getVisibleSize();
Sprite* titleSprite = Sprite::create("title.png");
titleSprite->setPosition(Point(visibleSize.width/2, visibleSize.height-50));
this->addChild(titleSprite, 2);
m_player = Player::create();
m_player->bindSprite(Sprite::create("sprite.png"));
m_player->setPosition(Point(200, visibleSize.height / 4));
this->addChild(m_player, 3);
initBG();
MonsterManager* monsterMgr = MonsterManager::create();
this->addChild(monsterMgr, 4);
monsterMgr->bindPlayer(m_player);
m_iScore = 0;
return true;
}
void TollgateScene::initBG()
{
Size visibleSize = Director::getInstance()->getVisibleSize();
m_bg1 = Sprite::create("tollgateBG.jpg");
m_bg1->setPosition(Point(visibleSize.width/2, visibleSize.height/2));
this->addChild(m_bg1,0);
m_bg2 = Sprite::create("tollgateBG.jpg");
m_bg2->setPosition(Point(visibleSize.width+visibleSize.width/2,visibleSize.height/2));
m_bg2->setFlippedX(true);
this->addChild(m_bg2,0);
loadUI();
}
void TollgateScene::update(float delta) //开启调用update函数的功能,需要加this->scheduleUpdate()
{
int posX1 = m_bg1->getPositionX();
int posX2 = m_bg2->getPositionX();
int speed = 1;
posX1 -= speed;
posX2 -= speed;
m_bg1->setPositionX(posX1);
m_bg2->setPositionX(posX2);
Size mapsize = m_bg1->getContentSize();
if(posX1 <= -mapsize.width/2)
{
posX1 = mapsize.width + mapsize.width/2;
}
if(posX2 <= -mapsize.width/2)
{
posX2 = mapsize.width + mapsize.width/2;
}
m_bg1->setPositionX(posX1);
m_bg2->setPositionX(posX2);
m_iScore += 1;
m_scoreLab->setText(Value(m_iScore).asString());
//m_hpBar->setPercent(100);
m_hpBar->setPercent(m_player->getiHP()/1000.0f*100);
}
void TollgateScene::loadUI()//加载cocostudio的控件
{
auto UI = cocostudio::GUIReader::getInstance()->widgetFromJsonFile("LittleRunnerUI_1.ExportJson");
this->addChild(UI);
auto jumpBtn = (Button*)Helper::seekWidgetByName(UI, "JumpBtn");
jumpBtn->setTitleText("Jump");
jumpBtn->addTouchEventListener(this, toucheventselector(TollgateScene::jumpEvent));//跳跃动作的监听
m_scoreLab = (Text*)Helper::seekWidgetByName(UI, "scoreLab");
m_hpBar = (LoadingBar*)Helper::seekWidgetByName(UI, "ProgressBar_11");
}
void TollgateScene::jumpEvent(Ref*, TouchEventType type)
{
switch(type)
{
case TouchEventType::TOUCH_EVENT_ENDED:
m_player->jump();
break;
}
}
5 启动
#ifndef _APP_DELEGATE_H_
#define _APP_DELEGATE_H_
#include "cocos2d.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by Director.
*/
class AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
/**
@brief Implement Director and Scene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching();
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground();
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};
#endif // _APP_DELEGATE_H_
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "TollgateScene.h"
USING_NS_CC;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("My Game");
glview->setFrameSize(800, 500);//只针对windos平台,移植到手机后这些设置是无效的。由手机屏幕来决定大小
director->setOpenGLView(glview);
}
// turn on display FPS
director->setDisplayStats(false);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
auto scene = TollgateScene::createScene();
// run
director->runWithScene(scene);
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
Director::getInstance()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
Director::getInstance()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}