〖cocos2d-x 3.3〗学习笔记之游戏实例 《跑酷》第四步— 加入岩石和游戏结束界面

接下来是第四步:加入岩石障碍物和游戏结束界面。 这里要用到和第二步背景循环差不多的原理来设置岩石的一个不断循环过程,另外要加一个碰撞检测,来检测主角和岩石 碰撞之后游戏结束的一个机制。

一共新添加了三个类:BaseManager、Rock、Base

加入类:BaseManager 有如下功能: 1.以Node为基的类,将岩石精灵绑到这个节点,从而控制这个岩石的动作以及其他操作(后面的加入金币也同理) 2.负责生成岩石和update(刷新)

加入类:Base 有如下功能: 1.也是以Node为基的类 2.负责将精灵添加到节点,获得精灵的大小(contentsize)

加入类:Rock 有如下功能: 1.初始化岩石,建立刚体并将其与岩石绑定 2.创建岩石的缓冲池,并从缓冲池拿出一个图片创建岩石精灵 3.设定掩码,用于碰撞检测

接下来就比较容易了,首先在PlayScene::init()方法加入下面两行代码,并切include一下"GameOver.h"、"BaseManager.h"这两个头文件:

m_manager = BaseManager::create(); this->addChild(m_manager);

还是在PlayScene.cpp,将下面代码加到最下面(代码注释很详细):

void PlayScene::onEnter(){
	Layer::onEnter();
	auto contactListenner = EventListenerPhysicsContact::create();

	//CC_CALLBACK表示回调函数的参数个数
	contactListenner->onContactBegin = CC_CALLBACK_1(PlayScene::onContactBegin, this);
	//dispatcher = Director::getInstance()->getEventDispatcher();

	//添加事件监听器到事件分发器. _eventDispatcher 是 Node 的属性,我们使用它来管理当前节点的所有事件分发 
	_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListenner, this);
}
void PlayScene::onExit(){
	Layer::onExit();
	//取消事件派发机制
	//dispatcher->removeAllEventListeners();
	_eventDispatcher->removeEventListenersForTarget(this);
}
bool PlayScene::onContactBegin(PhysicsContact& contact){
	auto body_1 = (Sprite*)contact.getShapeA()->getBody()->getNode();
	auto body_2 = (Sprite*)contact.getShapeB()->getBody()->getNode();

	CCLOG("ssssss");

	//这里表示是要人物和岩石相撞,BaseManager.h中宏定义了岩石的tag,runner的tag上一篇文章也设定了,是1
	if ((body_1->getTag() == 3 && body_2->getTag() == 1) ||
		(body_1->getTag() == 1 && body_2->getTag() == 3)){
		GameOver();
	}

	return false;
}

void PlayScene::GameOver(){
	Director::getInstance()->replaceScene(GameOver::scene());
}

记得在PlayScene.h中加入声明,在public中加入:

void onEnter(); void onExit(); bool onContactBegin(cocos2d::PhysicsContact& contact); void GameOver();
在private加入:
BaseManager* m_manager;

然后看Coin.h
#ifndef __Coin__H__
#define __Coin__H__

#include "Base.h"
#include "cocos2d.h"

USING_NS_CC;

class Coin : public Base
{
public:
	virtual bool init();
	CREATE_FUNC(Coin);

	//金币动作
	cocos2d::Animate* createAnimate(cocos2d::SpriteFrameCache* frameCache);
	//物理刚体
	void initBody();

private:
};/**/

#endif
Coin.cpp
#include "Coin.h"
#include "cocos2d.h"

USING_NS_CC;

bool Coin::init(){
	if (!Node::init()){
		return false;
	}

	//缓存池
	auto frameCache = SpriteFrameCache::getInstance();
	frameCache->addSpriteFramesWithFile("parkour.plist", "parkour.png");

	auto sprite = Sprite::createWithSpriteFrameName("coin7.png");

	//绑定
	setSprite(sprite);
	//执行动作
	getSprite()->runAction(createAnimate(frameCache));
	//绑定刚体
	initBody();

	return true;
}

Animate* Coin::createAnimate(SpriteFrameCache* frameCache){


	SpriteFrame* frame = NULL;
	//数组不行 要用vector
	//auto frameArray = Array::create();
	//frameArray->retain();
	Vector<SpriteFrame*>frameArray;

	// 用一个列表保存所有SpriteFrame对象 
	for (int i = 0; i <= 7; i++) {
		/* 从SpriteFrame缓存池中获取CCSpriteFrame对象 */
		frame = frameCache->spriteFrameByName(String::createWithFormat("coin%d.png", i)->getCString());
		frameArray.pushBack(frame);

	}
	/* 使用SpriteFrame列表创建动画对象 */
	auto animation = Animation::createWithSpriteFrames(frameArray);

	animation->setLoops(-1);

	animation->setDelayPerUnit(0.1f);

	/* 将动画包装成一个动作 */
	auto action = Animate::create(animation);

	return action;
}

void Coin::initBody(){
	auto phyBody = PhysicsBody::createBox(getSprite()->getContentSize());
	phyBody->setGravityEnable(false);
	phyBody->setCategoryBitmask(1);
	phyBody->setCollisionBitmask(1);
	phyBody->setContactTestBitmask(1);

	this->setPhysicsBody(phyBody);
}
在看BaseManager.h
#ifndef __BaseManager__H__
#define __BaseManager__H__

#include "cocos2d.h"
#include "Rock.h"

#define rockNum 2
#define rockTag 3

class BaseManager :public cocos2d::Node
{
public:
	virtual bool init();
	CREATE_FUNC(BaseManager);
	virtual void update(float dt);

private:
	//void createCoin();
	//cocos2d::Array* m_coinArr;

	void createRock();
	cocos2d::Array* m_rockArr;
};

#endif
BaseManager.cpp,看过第二步背景循环的估计这里应该没啥大问题
#include "BaseManager.h"

#define ground_height 59

USING_NS_CC;

bool BaseManager::init()
{
	if (!Node::init()){
		return false;
	}

	createRock();
	this->scheduleUpdate();
	return true;
}



void BaseManager::createRock()
{
	m_rockArr = Array::create();
	m_rockArr->retain();
	Rock* rock = NULL;
	float dis = 960;
	for (int i = 0; i <= rockNum;i++){
		rock = Rock::create();
		rock->setTag(rockTag);
		rock->setPosition(dis,ground_height+rock->getContentSize().height/2);
		dis += 640;
		this->addChild(rock);
		m_rockArr->addObject(rock);
	}
}

void BaseManager::update(float dt)
{


	Ref* rockObj = NULL;
	Rock* rock = NULL;
	CCARRAY_FOREACH(m_rockArr, rockObj){
		rock = (Rock*)rockObj;

		if (rock->getPositionX() < -rock->getConSize().width / 2){
			rock->setVisible(false);
		}
		if (rock->isVisible() == false){
			float posX = 1280;
			float posY = ground_height + rock->getConSize().height / 2;
			if (CCRANDOM_MINUS1_1() > 0){
				posY += 50;
			}
			rock->setPosition(posX, posY);
			rock->setVisible(true);
		}

		rock->setPositionX(rock->getPositionX() - 2);
	}
}
Base.h
#ifndef __Base__H__
#define __Base__H__

#include "cocos2d.h"

class Base : public cocos2d::Node{
public:
	Base();

	void setSprite(cocos2d::Sprite* sprite);
	cocos2d::Sprite* getSprite();

	cocos2d::Size getConSize();

private:
	cocos2d::Sprite* m_sprite;
};/**/

#endif
Base.cpp
#include "Base.h"

USING_NS_CC;

Base::Base(){
	m_sprite = NULL;
}

void Base::setSprite(Sprite* sprite){
	m_sprite = sprite;
	//要添加到子节点中 ,才能被显示出来
	this->addChild(m_sprite);
}

Sprite* Base::getSprite(){
	return m_sprite;
}

Size Base::getConSize(){
	return m_sprite->getContentSize();
}

全部弄好了之后如下两图,撞到岩石游戏结束,就会显示第二幅图:

QQ图片20150806103242 QQ图片20150806103312

游戏需要用到的资源(不放到resourse里运行会报错):Resources

上一步:〖cocos2d-x 3.3〗学习笔记之游戏实例 《跑酷》第三步— 加入主角

下一步:〖cocos2d-x 3.3〗学习笔记之游戏实例 《跑酷》第五步(大功告成)— 加入金币

标签:   |  
时间: 2015年08月06日上午11:04  |  
作者:
LEAVE A REPLY
loading
正在赶回来……