Cocos2dx 入门小游戏实例

从图书馆借了本木头的书籍,以下实例来自书籍,写在这里仅作笔记。。


游戏内容大概如下:

1.一个Sprite在地图上一直在跑,Sprite可以跳跃(其实是地图不断向左滚动)

2.途中有金币,Sprite吃金币,左上方的Score会++,并且会有+15的字样出现



1.创建实体类Entity,这是一个基类,主要用来绑定一个精灵,返回一个精灵

#ifndef Entity_H
#define Entity_H

#include "cocos2d.h"
using namespace cocos2d;

class Entity:public CCNode
{
public:
	Entity();

	~Entity();

	CCSprite* getSprite();

	void bindSprite(CCSprite* sprite);

private:
	CCSprite* m_sprite;
};
#endif

#include "Entity.h"

Entity::Entity()
{
	m_sprite=NULL;
}
Entity::~Entity()
{

};

CCSprite* Entity::getSprite()
{
	return this->m_sprite;
}
void Entity::bindSprite(CCSprite* sprite){
	this->m_sprite=sprite;
	this->addChild(m_sprite);
}



2.创建一个玩家主角类,可以jump,吃金币等

#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();
public:
	void jump();
	void jumpEnd();
	void hit();//主角和怪物撞击(玩家受伤害)
	int getMoney();
	CCRect getBoundingBox();/*获取碰撞范围*/
	void resetData();
	void actionEnd();
private:
	bool m_isJumping;
	int m_money;/*金钱*/

};
#endif
#include "Player.h"
#include "FlowWord.h"

Player::Player()
{
	m_isJumping=false;
	m_money=0;/*初始金钱为0*/
}
Player::~Player()
{

}
bool Player::init()
{
	return true;
}

void Player::jump()
{
	if(!getSprite())
	{
		return;
	}
	if(m_isJumping)/*如果主角还在跳跃中,则不重复跳跃*/
	{
		return;
	}

	m_isJumping=true;

	/*创建动作,2s,原地跳跃(即落地的地点相对于起跳地点x偏移0,y偏移0),高度250,弹跳次数1*/
	CCJumpBy* jump=CCJumpBy::create(1.5f,ccp(0,0),200,1);
	/*callFunc也是一个动作,作用是调用一个函数*/
	CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(Player::jumpEnd));
	/*组合动作*/
	CCActionInterval* jumpActions=CCSequence::create(jump,callFunc,NULL);
	
	runAction(jumpActions);
}

void Player::jumpEnd()
{
	m_isJumping=false;
}
void Player::hit()
{
	if(getSprite()==NULL)
	{
		return;
	}
	/*加钱特效提示*/
	FlowWord* flowword=FlowWord::create();
	this->addChild(flowword);
	flowword->showWord("+15",getSprite()->getPosition());
	
	m_money+=15;

	/*创建4种动作对象*/
	CCMoveBy* backMove=CCMoveBy::create(0.1f,ccp(-20,0));
	CCMoveBy* forwardMove=CCMoveBy::create(0.1f,ccp(20,0));
	CCRotateBy* backRotate=CCRotateBy::create(0.1f,-5,0);
	CCRotateBy* forwardRotate=CCRotateBy::create(0.1f,5,0);

	/*分别组合成两种动作(同时执行)*/
	CCSpawn* backActions=CCSpawn::create(backMove,backRotate,NULL);
	CCSpawn* forwardActions=CCSpawn::create(forwardMove,forwardRotate,NULL);

	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Player::actionEnd));

	CCActionInterval* actions=CCSequence::create(backActions,forwardActions,callFunc,NULL);
	
	//this->stopAllActions();
	//resetData();

	this->runAction(actions);


}
void Player::resetData()
{
	if(m_isJumping)
	{
		m_isJumping=false;
	}
	this->setPosition(ccp(200,500/4));
	this->setScale(1.0f);
	setRotation(0);
}
int Player::getMoney()
{
	return m_money;
}
CCRect Player::getBoundingBox()
{
	if(getSprite()==NULL){
		return CCRectMake(0,0,0,0);
	}
	/*由于Sprite是放在Player上的,所以要检测Player的碰撞范围*/
	CCSize spriteSize=getSprite()->getContentSize();
	CCPoint entityPos=this->getPosition();//获取player中心点

	//获取Player左下角的坐标值
	int x=entityPos.x-spriteSize.width/2;
	int y=entityPos.y-spriteSize.height/2;

	return CCRectMake(x,y,spriteSize.width,spriteSize.height);
}

void Player::actionEnd()
{
	this->setScale(1.0f);
	setRotation(0);
}




3.创建怪物类(金币),继承于实体类
--

#ifndef _Monster_H_
#define _Monster_H_

#include "Entity.h"
#include "cocos2d.h"
#include "Player.h"
#include "ccMacros.h"

USING_NS_CC;

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 m_isAlive;
};
#endif
#include "Monster.h"

Monster::Monster()
{
}
Monster::~Monster()
{
}
bool Monster::init()
{
	return true;
}
void Monster::show()
{
	if(getSprite()!=NULL)
	{
		this->setVisible(true);
		m_isAlive=true;/*标记为活动状态*/
	}
}
void Monster::hide()
{
	if(getSprite()!=NULL)
	{
		this->setVisible(false);
		reset();
		m_isAlive=false;/*标记为活动状态*/
	}
}
void Monster::reset()
{
	if(getSprite()!=NULL)
	{
		/*初始化怪物坐标,宽度(800-2800),高度(100-200)*/
		this->setPosition(ccp(800+CCRANDOM_0_1()*2000,200-CCRANDOM_0_1()*100));
	}
}
bool Monster::isAlive()
{
	return m_isAlive;
}
bool Monster::isCollideWithPlayer(Player* player)
{
	CCRect playerRect=player->getBoundingBox();
	CCPoint monsterPos=getPosition();

	/*判断是否有交集*/
	return playerRect.containsPoint(monsterPos);
}



4.创建怪物管理器类(MonsterManger),用来管理怪物的显示和隐藏


#ifndef __MonsterManger_H__
#define __MonsterManger_H__

#include "cocos2d.h"
#include "Player.h"
USING_NS_CC;

#define MAX_MONSTER_NUM 10

class MonsterManger:public CCNode
{
public:
	MonsterManger();
	~MonsterManger();
	CREATE_FUNC(MonsterManger);
	virtual bool init();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      	virtual void update(float dt);/*重写update函数*/
	void bindPlayer(Player* player);
private:
	void createMonsters();/*创建Monster对象*/
private:
	CCArray* m_monsterArr;/*存放怪物数组*/
	Player* m_player;
};

#endif

#include "MonsterManger.h"
#include "Monster.h"

MonsterManger::MonsterManger(){}

MonsterManger::~MonsterManger(){}

bool MonsterManger::init()
{
	bool bRet=false;
	do 
	{
		createMonsters();/*创建怪物*/
		this->scheduleUpdate();/*启用update*/
		bRet=true;
	} while (0);
	return bRet;
	
}


void MonsterManger::createMonsters()
{
	m_monsterArr=CCArray::create();
	m_monsterArr->retain();/*防止数组被释放*/

	Monster* monster=NULL;
	CCSprite* sprite=NULL;

	for(int i=0;i<MAX_MONSTER_NUM; i++)
	{
		monster=Monster::create();
		monster->bindSprite(CCSprite::create("monster.png"));
		monster->reset();

		this->addChild(monster);  /*将怪物添加到管理器(CCNode)中*/
		m_monsterArr->addObject(monster);/*添加到数组中,便于管理*/
	}
}

void MonsterManger::update(float dt)
{
	CCObject* obj=NULL;
	Monster* monster=NULL;
	
	CCARRAY_FOREACH(m_monsterArr,obj)/*循环遍历怪物数组,重复出现在屏幕上*/
	{
		monster=(Monster*) obj;
		if(monster->isAlive())/*活动状态*/
		{
			monster->setPositionX(monster->getPositionX()-3);//左移
			if(monster->getPositionX()<0)
			{
				monster->hide();

			}else if(monster->isCollideWithPlayer(m_player)){
				m_player->hit();
				monster->hide();
			}
		
		}else/*非活动状态*/
		{
			monster->show();//
		}
	}
}
void MonsterManger::bindPlayer(Player* player)
{
	this->m_player=player;
	this->m_player->retain();//引用计数 +1
}



5.创建文字飘动效果,(在主角身上显示"+15"特效)

#ifndef __FlowWord_H__
#define __FlowWord_H__

#include "cocos2d.h"
USING_NS_CC;

class FlowWord:public CCNode
{
public:
	FlowWord();
	~FlowWord();
	CREATE_FUNC(FlowWord);
	virtual bool init();
public:
	void showWord(const char* text, CCPoint pos);
	void flowEnd();
private:
	CCLabelTTF* m_textLab;
};

#endif


#include "FlowWord.h"

FlowWord::FlowWord(){}

FlowWord::~FlowWord(){}

bool FlowWord::init()
{
	m_textLab=CCLabelTTF::create("","Arial",30);
	m_textLab->setColor(ccc3(255,0,0));
	m_textLab->setVisible(false);

	this->addChild(m_textLab);

	return true;
}

void FlowWord::showWord(const char* str,CCPoint pos)
{
	m_textLab->setString(str);
	m_textLab->setPosition(pos);
	m_textLab->setAnchorPoint(ccp(1,0));
	m_textLab->setVisible(true);

	//先放大后缩小
	CCActionInterval* scaleLarge=CCScaleTo::create(0.3f,2.5f,2.5f);
	CCActionInterval* scaleSmall=CCScaleTo::create(0.4f,0.5f,0.5f);
	//回调动作,移除效果
	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(FlowWord::flowEnd));

	CCActionInterval* actions=CCSequence::create(scaleLarge,scaleSmall,callFunc,NULL);

	m_textLab->runAction(actions);
}

void FlowWord::flowEnd()
{
	m_textLab->setVisible(false);
	/*true: 从父节点移除,并移除节点的动作和回调函数*/
	m_textLab->removeFromParentAndCleanup(true);
}

6.创建游戏场景类,所有游戏的效果都在这上面展示

#ifndef __TollgateScene_H__
#define __TollgateScene_H__

#include "cocos2d.h"
#include "cocos-ext.h"
#include "Player.h"
using namespace cocos2d;
using namespace cocos2d::extension;


class TollgateScene : public CCLayer {
public:
	static CCScene* scene();
	virtual bool init();
	CREATE_FUNC(TollgateScene);

	virtual void update(float delta);

private:
	void initBG();  /* 初始化关卡背景 */
	void createJumpBtn();/*创建跳跃按钮*/
	void jumpEvent(CCObject* pSender,CCControlEvent event);/*响应按钮点击事件*/

	void createScoreLab();/*创建分数标签*/
	void createTimeSlider();/*创建时间条*/
private:
	CCSprite* m_bgSprite1;
	CCSprite* m_bgSprite2;

	Player* m_player;

	CCLabelTTF* m_scoreLab;//分数标签
	CCControlSlider* m_TimeSlider;//时间条

	int m_score;	/*得分*/
	int m_curTime; /*当前时间*/
};

#endif

#include "TollgateScene.h"
#include "MonsterManger.h"

CCScene* TollgateScene::scene() {
	CCScene* scene = NULL;
	do 
	{
		scene = CCScene::create();
		CC_BREAK_IF(!scene);

		TollgateScene* layer = TollgateScene::create();
		CC_BREAK_IF(!layer);

		scene->addChild(layer, 1);
	} while (0);

	return scene;
}

bool TollgateScene::init() {
	bool bRet = false;

	do 
	{
		CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

		/*游戏标题图片*/
// 		CCSprite* titleSprite = CCSprite::create("title.png");
// 		titleSprite->setPosition(ccp(visibleSize.width / 2, visibleSize.height - 50));
// 		this->addChild(titleSprite, 2);

		/*创建猪脚*/
		CCSprite* sprite = CCSprite::create("sprite.png");
		//sprite->setFlipX(true);
		m_player = Player::create();
		m_player->bindSprite(sprite);
		m_player->setPosition(ccp(200, visibleSize.height / 4));
		
		this->addChild(m_player,1);
		
		/*初始化背景图片*/
		initBG();

		/*创建按钮*/
		createJumpBtn();

		/*设置启用CCNode的update()函数,游戏会在每一帧调用update()函数*/
		this->scheduleUpdate();

		/*创建怪物管理器(管理器里面放了很多怪物)*/
		MonsterManger* monsterManger=MonsterManger::create();
		monsterManger->bindPlayer(m_player);
		this->addChild(monsterManger,4);

		/*创建分数标签*/
		createScoreLab();
		/*创建时间条*/
		createTimeSlider();

		bRet = true;
	} while (0);

	return bRet;
}

void TollgateScene::initBG() {
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	m_bgSprite1 = CCSprite::create("tollgateBG.jpg");
	m_bgSprite1->setPosition(ccp(visibleSize.width / 2, visibleSize.height / 2));
	this->addChild(m_bgSprite1, 0);

	m_bgSprite2 = CCSprite::create("tollgateBG.jpg");
	m_bgSprite2->setPosition(ccp(visibleSize.width + visibleSize.width / 2, visibleSize.height / 2));
	m_bgSprite2->setFlipX(true);
	this->addChild(m_bgSprite2, 0);
}

void TollgateScene::update(float delta)
{
	CCSize mapSize=m_bgSprite1->getContentSize();//地图大小

	int posX1=m_bgSprite1->getPositionX();  //地图1的x坐标
	int posX2=m_bgSprite2->getPositionX();	//地图2的x坐标

	int iSpeed = 2;	//地图滚动的速度

	posX1-=iSpeed;	//两张地图一起向左滚动
	posX2-=iSpeed;

	//创建无限循环
	if(posX1<=-mapSize.width/2)
	{
		posX1=mapSize.width+mapSize.width/2;
		posX2=mapSize.width/2;
	}
	if(posX2<=-mapSize.width/2)
	{
		posX1=mapSize.width/2;
		posX2=mapSize.width+mapSize.width/2;
	}

	m_bgSprite1->setPositionX(posX1);
	m_bgSprite2->setPositionX(posX2);

	/*分数增加*/
	m_score=m_player->getMoney();
	m_scoreLab->setString(CCString::createWithFormat("Score:%d",m_score)->getCString());

	m_TimeSlider->setValue(--m_curTime);
	
}
void TollgateScene::createJumpBtn()
{
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();

	/*按钮标题*/
	CCLabelTTF* jumpLabel=CCLabelTTF::create("Jump","Arial",35);

	/*按钮状态图片*/
	CCScale9Sprite* jumpNorBG=CCScale9Sprite::create("button.png");
	CCScale9Sprite* jumpLightBG=CCScale9Sprite::create("buttonHighlighted.png");
	
	/*创建按钮*/
	CCControlButton* jumpBtn=CCControlButton::create(jumpLabel,jumpNorBG);
	jumpBtn->setPosition(ccp(visibleSize.width-80,50));
	jumpBtn->setBackgroundSpriteForState(jumpLightBG,CCControlStateHighlighted);
	
	/*添加事件*/
	jumpBtn->addTargetWithActionForControlEvents(this,
		cccontrol_selector(TollgateScene::jumpEvent),
		CCControlEventTouchDown);

	this->addChild(jumpBtn);
}

void TollgateScene::jumpEvent(CCObject* pSender,CCControlEvent event)
{
	m_player->jump();
}

void TollgateScene::createScoreLab()
{
	m_score=m_player->getMoney();
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
	m_scoreLab=CCLabelTTF::create("Score:"+m_score,"Arial",35);
	m_scoreLab->setAnchorPoint(ccp(0,1));
	m_scoreLab->setPosition(ccp(0,visibleSize.height));
	this->addChild(m_scoreLab);

}

void TollgateScene::createTimeSlider()
{
	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
	m_curTime=10000;
	m_TimeSlider=CCControlSlider::create(
		CCSprite::create("background.png"),
		CCSprite::create("progress.png"),
		CCSprite::create("sliderThumb.png")
		);
	m_TimeSlider->setPosition(ccp(
		m_TimeSlider->getContentSize().width/2,
		visibleSize.height-m_TimeSlider->getContentSize().height-m_scoreLab->getContentSize().height
		));
	m_TimeSlider->setTouchEnabled(false);
	m_TimeSlider->setMaximumValue(10000);
	m_TimeSlider->setMinimumValue(0);
	m_TimeSlider->setValue(m_curTime);
	this->addChild(m_TimeSlider,3);
}



运行效果如下




源码

posted @ 2014-03-17 22:44  会做菜的老狼  阅读(945)  评论(0编辑  收藏  举报