您的位置:首页 > 移动开发 > Cocos引擎

笨木头 Little Runner

2016-04-18 17:11 645 查看
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);
}


2.创建主角类Player和金币类Monster.
#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);
}
<pre name="code" class="cpp">#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<Monster*> 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;
}


4.创建场景类
#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)  //<span style="font-family: Arial, Helvetica, sans-serif;">开启调用update函数的功能,需要加this->scheduleUpdate()</span>
{
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();
}


6.不要在写代码的时候,把所有的功能都往一个类里面写,多分开几个类来写,多写一些注释,以便后面要修改或者查阅看不懂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d-x