从图书馆借了本木头的书籍,以下实例来自书籍,写在这里仅作笔记。。
游戏内容大概如下:
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);
}
运行效果如下
源码