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